golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.99k stars 17.67k forks source link

all: standardize -help behavior in go project tools #63659

Open adonovan opened 1 year ago

adonovan commented 1 year ago

UNIX commands vary wildly in the ways in which they provide help messages. Recently in the x/tools repo there has been a trend towards printing the doc.go comment when the -help flag is specified. Following a discussion with @rsc, we propose that all Go-project maintained command-line tools should consider the package doc comment as the primary documentation and print only a brief summary of usage.

Specifically, when a command is invoked with -h, or -help, or with no flags or arguments when this is not a meaningful command, it should print the following items:

  1. a single-line description of the form "name: purpose".
  2. a single-line summary of command syntax.
  3. a list of supported flags (e.g. flag.Usage).
  4. a link to a pkg.go.dev URL for complete documentation.
  5. a go doc package command for complete documentation.

Here's an example of what that would look like for golang.org/x/tools/cmd/callgraph:

$ callgraph
callgraph: display the call graph of a Go program

Usage: callgraph [flags] package...
  -algo=string
        call graph construction algorithm (static|cha|rta|vta)
  -test
        Include the package's tests in the analysis.
 -format=string
    Format in which each call graph edge is displayed (digraph|graphviz|template)
Packages are specified in 'go list' format.

See also: https://pkg.go.dev/golang.org/x/tools/go/callgraph
or run:   go doc golang.org/x/tools/cmd/callgraph

Let the bike shedding begin!

fzipp commented 1 year ago
 or run:   go doc golang.org/x/tools/cmd/callgraph

Unfortunately, go doc doesn't work for modules that aren't listed in a go.mod file, such as installed commands:

% go doc golang.org/x/tools/cmd/callgraph
doc: no required module provides package golang.org/x/tools/cmd/callgraph: go.mod file not found in current directory or any parent directory; see 'go help modules'
robpike commented 1 year ago

Cautious support.

I dislike the idea of printing all known documentation every time the command line is incomplete or incorrect. This is a common behavior of a number of tools, although not all. I'm scarred by years of subcommands of various tools printing masses of output when all I need is to be told I typoed a line, or forgot to write "format" instead of "fmt". Programs are too eager to scroll my working text off the screen in the interest of providing full documentation. When mid-flow, too much text can be worse than not enough.

If I get the flags wrong, print the flags and nothing else. Otherwise just tell me how to get fuller documentation. Your proposal covers that in a sensible way.

So I am supportive, but there is more to lock down, stylewise. For instance, the usage message should not include an essay about all the ways you can use the tool. In fact, by default I think the usage message should always be a single sentence, as in the example above. Your example satisfies this property, but many other commands do not.

Answer the question that needs to be answered, and none other, and do it briefly.

seankhliao commented 1 year ago

Essentially the opposite of #27580

bcmills commented 1 year ago

@seankhliao, not quite exactly the opposite, though — arguably much of the verbose go help documentation printed on the command line should be moved to online documentation too.

earthboundkid commented 1 year ago
$ go doc golang.org/x/tools/cmd/callgraph@latest
doc: package golang.org/x/tools/cmd/callgraph@latest: can only use path@version syntax with 'go get' and 'go install' in module-aware mode

There should be a proposal to allow go doc module@version.

earthboundkid commented 1 year ago

Traditionally, a problem for Go package documentation was that you would want to put a high level overview into the README for people browsing on GitHub, but that would then need to be duplicated in the Go doc. The pkg site now shows the README, which is good for de-duplication, but maybe go doc could show it too? That plus go doc path@version would be very powerful and simple.

adonovan commented 1 year ago

There should be a proposal to allow go doc module@version.

You're right. Here it is: https://github.com/golang/go/issues/63696

hyangah commented 1 year ago

A potential thought experiment could be how to improve go help list documentation. I'd also appreciate a shorter doc than what go help list currently offers, but also prefer to see sufficient details about what -f flag takes without needing the network and visiting the online documentation. go doc go (or go doc cmd/go) is too long to be useful in terminal and moreover, hard to guess for new users.

This proposal and #27580 complement each other IMO.

27580 talks about the -h or --help. This proposal talks about compact help info.

For example, go help mod -h now tells me Run 'go help mod edit'. go help mod edit then prints two pages long message and tells me See https://golang.org/ref/mod#go-mod-edit.

Ideally, we want go mod edit -h to print the amount of info this proposal proposes. Personally, I don't mind seeing a long, more verbose details with go help mod that I can less or grep.

rsc commented 1 year ago

This proposal has been added to the active column of the proposals project and will now be reviewed at the weekly proposal review meetings. — rsc for the proposal review group

rsc commented 11 months ago

Here's a new potential canonical usage message:

% gofmt --help
Usage: gofmt [flags] [path ...]

  -cpuprofile file
        write cpu profile to file
  -d    display diffs instead of rewriting files
  -e    report all errors (not just the first 10 on different lines)
  -l    list files whose formatting differs from gofmt's
  -r rule
        apply rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
  -s    simplify code
  -w    write result to (source) file instead of stdout

Docs: go doc cmd/gofmt
https://pkg.go.dev/cmd/gofmt
adonovan commented 11 months ago

Sharing some thoughts Russ and I had while developing the example above:

Two helper functions to print each of the last two items, taking the package name (e.g. cmd/gofmt) from runtime/debug.ReadBuildInfo.Path, could potentially be added to the flag package, along with advice on how to produce a good usage message.

rsc commented 10 months ago

Have all remaining concerns about this proposal been addressed?

Proposed standard -help format in https://github.com/golang/go/issues/63659#issuecomment-1854612414.

rsc commented 10 months ago

Based on the discussion above, this proposal seems like a likely accept. — rsc for the proposal review group

Proposed standard -help format in https://github.com/golang/go/issues/63659#issuecomment-1854612414.

rsc commented 9 months ago

No change in consensus, so accepted. 🎉 This issue now tracks the work of implementing the proposal. — rsc for the proposal review group

Proposed standard -help format in https://github.com/golang/go/issues/63659#issuecomment-1854612414.

TheCoreMan commented 9 months ago

In addition, a URL provides the complete manual as a web page.

I know this is closed for comments, but I think that setting up an automated check that the manual links aren't broken automatically is prudent if we want the documentation to stay "strong" as domains and webservers move and deteriorate over time.

adonovan commented 9 months ago

setting up an automated check that the manual links aren't broken automatically is prudent if we want the documentation to stay "strong" as domains and webservers move and deteriorate over time.

Russ and I discussed adding new public functions to the flag package that would assist in the printing of canonical help messages, perhaps by introspecting the main package to generate the go doc command and/or the pkg.go.dev URL, including the correct module version. If a user wants to write a test that makes an external HTTP request, they're free to do that, but it doesn't seem like the responsibility of the flag package.