-
Notifications
You must be signed in to change notification settings - Fork 17.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/go: mod is too much of a grab bag #26581
Comments
I agree go mod is not right as it stands. It's too much of a grab bag. We don't have any sub-sub-commands today, and I don't particularly want to go there. As the new 'go help mod' text (CL pending) points out:
Too many people think everything about modules is 'go mod', to the point of not including 'go get' in tutorials about how to download dependencies. Subcommands won't help avoid that misperception. But mod should probably be split into a few different commands. The bulk of the flags do combine nicely. In particular -init, -module, -require, -exclude, -replace, -droprequire, -dropexclude, -dropreplace all work really well together in a single invocation and would work less well if you had to run the go command repeatedly to effect the same list of those changes. I've been thinking there should be a -n that just shows you the resulting go.mod instead of writing it out. Similarly -json prints the go.mod in json form and maybe -n -json should print it without writing go.mod back. All this was meant to keep the promise in #23966 to make go.mod machine parseable (with -json) and editable (with the others). The -fmt and -fix flags fit into that category too. The abuses begin with -sync, although even that is a natural thing to do after the edits and before committing the modified go.mod to disk as well. But it ends up being a useful operation by itself enough of the time that maybe it should be kept separate. It is unlike the others mentioned so far in that it looks at Go source files. Then -vendor, which must do most of the work of -sync to decide what to vendor, and then vendor it. Then -verify, which doesn't actually look at any packages but does consult go.sum and the download caches. Then -packages, which can probably just be dropped so I won't say more. Then -graph, which is quite possibly the most important thing here after -sync. It prints the module graph in a simple text form that allows further analysis, andthat data is hard to extract in any other way. I also have a CL in progress to add a -pgraph to print the module+package import graph so that you can answer "why does go mod -sync keep such and such module around?". That data is possible to extract in other ways, so maybe it's not as important. If we're going to split up the mod command, probably the editing operations should stick around as 'go mod'. Another possibility is to split out 'go init' and leave the others as 'go mod'. Then you would have But then maybe 'go graph' (package graph), 'go graph -m' (module graph), 'go sync', 'go vendor', 'go verify'? Happy to brainstorm tomorrow. |
What about |
I don't think there's any design principle at work here that argues against sub-subcommands, and a compelling argument in favor of them is that they make it much easier to provided targeted, per-operation help from the command line. Another is a similar story for flags. |
Change https://golang.org/cl/126655 mentions this issue: |
Cross posting here from the CL 126655. This seems like less seamless integration to me. Do we really need 'mod edit' part of go command? go mod edit => remove, go mod edit -fmt can be part of go fmt |
However, I agree that I disagree that I suspect that |
@bcmills, let me disagree on your
point. I'm pretty much confident that teams which already make heavy use of vendoring will unlikely be moving away to "the next thing" (borderline package proxies?) anytime soon: there will just not be enough justification to fix what is not broken. |
The UX model for
go mod
is to define what the operation is by setting a flag. This is an odd model that I suspect just fell out of the way thego
command already works. But I find it odd, and it mixes mandatory and optional flags together in odd ways.It will take some rearchitecting but the operations should be specified as subcommands, not flags, like this:
Besides being a better match for the usage, this would enable two important changes: First, a help enabler could be added; today we get
which is no help at all, really, when we could have
Similarly, by turning these actual commands into syntactic commands, we open up the possibility of having flags on them, with the usual advantages (and disadvantages) and clarity that results.
The text was updated successfully, but these errors were encountered: