cmd/go: add -f (format) flag to go mod edit
josharian opened this issue · 9 comments
go mod edit -json dumps the entire mod file. However, having to parse json immediately takes this out of the realm of simple bash scripts.
As part of working on #34867, I've already hit two cases in which I need targeted information out of go mod edit -json: The required version of a module, and all replacements involving that module.
Writing a quick program to parse json is easy, but the obvious language to use is Go. But in my circumstances, I can't go run a Go program, because the mod file is in a broken state.
I propose that, like go list, go mod edit have a format flag to enable easy information requests from a shell script.
I'm curious: why do you need go mod edit -json for this task (rather than go list)?
Two reasons:
-
go.mod is in a bad state (replace directive points to non-existent dir), so go list fails.
-
The info I need is about replace directives (in particular what versions have replace directives), which go list does not expose.
go list does expose replace directives: see the Replace field of type Module at https://golang.org/cmd/go/#hdr-List_packages_or_modules.
For the replace directive pointing to a non-existent directory: perhaps we should make go list -m -e more tolerant of bad edges in the module graph?
go list does expose replace directives: see the Replace field of type Module at https://golang.org/cmd/go/#hdr-List_packages_or_modules.
Maybe I'm holding it wrong, but I don't seem to be able to get a version out of that. Relevant parts of go.mod:
go 1.13
require (
github.com/josharian/git2go v0.0.0-20191016055211-da2fefa41c8c
)
replace github.com/josharian/git2go v0.0.0-20191016055211-da2fefa41c8c => ./build/git2go/v0.0.0-20191016055211-da2fefa41c8c
Result of running go list:
$ go list -m -f '{{.Replace}}' github.com/josharian/git2go
./build/git2go/v0.0.0-20191016055211-da2fefa41c8c
$ go list -m -f '{{.Replace.Version}}' github.com/josharian/git2go
$
Also, I want to get all replace directives for that module, not just the active one. (This is lower priority, though.)
For the replace directive pointing to a non-existent directory: perhaps we should make go list -m -e more tolerant of bad edges in the module graph?
Seems like a good idea.
Maybe I'm holding it wrong, but I don't seem to be able to get a version out of that.
Your replace directive specified a filesystem path, not a version. (The Version field is blank because there is no version on the right side of that directive.)
To see what I mean, try:
go list -m -f '{{.Path}} {{.Version}}{{with .Replace}} => {{.Path}} {{.Version}}{{end}}' all
Your replace directive specified a filesystem path, not a version. (The Version field is blank because there is no version on the right side of that directive.)
Ah. I was focused on trying to learn what was on the left hand side of the directive, because that's what go mod edit -dropreplace needs. But I can skip doing cleanup and just use the main version. Assuming -e is made more tolerant.
I found a different way to approach this.
The goal was to remove all replace directives for a given module. The old approach was to try obtain all replace directives and remove them one by one.
Thanks to the new and improved docs by @jayconrod in CL 210340, I now see there is a much simple way: Add an versionless replace directive, which removes all existing replace directives, and then remove it:
$ go mod edit -replace path/to/module=./placeholder
$ go mod edit -dropreplace path/to/module
I still think it would be a good to make go list -m -e more tolerant of bad edges in the module graph, though.
Bryan, I'll let you decide what to do with this issue now. Thanks for your patience and assistance.
I still think it would be a good to make
go list -m -emore tolerant of bad edges in the module graph, though.
Agreed: we've been trying to make go list -e more tolerant of all kinds of errors, but that seems like a separate issue.
Since you have a suitable workaround and nobody else has chimed in on this request, let's close it. (We can always revisit if we find more use-cases, or if we discover that your use-case is needed frequently enough to address directly.)