Skip to content
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: Documentation should make it clearer that the go tool works best on packages #43970

vdobler opened this issue Jan 28, 2021 · 3 comments
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.


Copy link

vdobler commented Jan 28, 2021

What version of Go are you using (go version)?


Does this issue reproduce with the latest release?


What operating system and processor architecture are you using (go env)?


Problem description

There seem to be a growing set of users who think that the arguments to the various subcommands of the go tool should be source code file names (or at least can be source code files without any drawbacks). This leads to a lot of questions why something doesn't work out as expected. The following is an anecdotic list of questions I heave seen in the past years:

  • Why doesn't go run main.go work any longer if I move some of my code to a new file server.go?
  • Why doesn't go build main.go foo.go special.go not honour build tags?
  • Why doesn't go test some_test.go run the tests in file some_test.go but fails with compiler errors?
  • Why does the trivial program package main; func main(){} lead to memory allocations as can be seen by GODEBUG=gctrace=1 go run trivial.go ?
  • Why shouldn't I execute my Go script in my docker container via go run?
  • Why does importing import "./mypkg/mycode.go" throw an error but the file ./mypkg/mycode.go does exist and contains the code?

The tutorial has been updated already in commit 713e774d
to work on packages only but it seems this information doesn't really reach the intended audience.

When I heard of Go a decade ago the package system was one of the first things I read about and was impressed how transitive dependencies are are handled and how clean testing and platform specific code was. Building Go code was always go build without arguments for me. And this "just works". But it seems as if a lot of newcomers to the language are used to work with source code files and lots of (external) tutorials promoting go run main.go together with the possibility of using go build with source files too might have lead to the assumption that the "go tools works on files (as most other languages actually do)".

I think there is not enough "warning" on that explains how Go and the go tool is different in handling its compilation units and that the go tool works best if applied to packages.

For a Go veteran this is not news and nothing wich needs to be spelled out in detail but I think lot's of newcomers are confused about packages and the fact that the go tool works quite well on files for simple cases (as they are used from other languages) but has some sharp edges. And after 3 month of go run main.go this file-based thinking sets in and ultimately leads to frustration because Go's compilation unit is a package (which de facto is a folder).

(An other frequent question is about "software architecture" in the sense of "which folder layout for my source code should my project use" which I think also indicates that the concept of a Go package is often only poorly understood. Other question regarding "sub-packages" or "parent-packages" also hint in this direction. The hassle to understand a Go module as nothing more than a set of packages with the same lifecycle versioned together might also come from not grasping the concept of a package.)

Unfortunately I cannot point to one (or several) documents on the website and say "here it needs a paragraph explaining concept of a package and here we have to add the Use-the-go-tool-on-packages-only-! warning sign."

There are good reasons to do a go run gen.go or use go build with files but probably these should be the exception and the official documentation should make it very clear: Use the go tool on packages only!

Copy link

bcmills commented Jan 28, 2021

CC @stevetraut @jayconrod @matloob

Copy link

@vdobler, thanks for the note. I'm focusing on docs. Here are the key bits I read from your note:

  • There's a difference between the best practice for the go tool and what is common in other languages. Docs could make the Go way clearer, particularly with new users in mind.
  • There's no clear documentation on packages (and perhaps modules).
  • It's not always easy to find documentation for a given subject.

Each of these is, in some way, addressed in plans for new content. I think there's a lot of useful content about packages and modules (for example) embedded in blog posts and articles on the site, but it can be hard to find.

Copy link
Contributor Author

vdobler commented Jan 29, 2021

@stevetraut Thanks for the summary, it almost captures my issue:

The third bullet is overly generic and a common problem and not the main issue I wanted to address.

The first and second bullet are the main issues and probably should be combined. Go is package oriented: Visibility is package based. Import is package based, source code layout is package based. Testing is package based. Build is package based. Code reuse is package based. So the correct way to test, build and run Go code is always a plain go build or go test only and maybe a go run .. Working with source code files is wrong (but possible to accommodate for edge cases, expert usage and toy cases): You cannot import them, you cannot test them and building them might not do what you expect it to do based on experience with other languages. This package orientation is a distinguishing feature and---as such---underrepresented in the documentation.

This lead to frustrating experience for newcomers who think go run main.go might be the recommended (or even just a safe) way to "execute Go code". Newcomers should never use go run.

(Modules might be "underdocumented" but the idea of what modules are and how to use them is basically trivial once someone understands packages, import paths (as package-identity) and same lifecycle / evolving in lockstep.)

@toothrot toothrot added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Jan 29, 2021
@toothrot toothrot added this to the Backlog milestone Jan 29, 2021
@toothrot toothrot changed the title Documentation should make it clearer that the go tool works best on packages cmd/go: Documentation should make it clearer that the go tool works best on packages Jan 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Documentation NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
None yet

No branches or pull requests

5 participants