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: command to print out the directory Go will install binaries into #45546

Open
kevinburke1 opened this issue Apr 13, 2021 · 14 comments
Open
Labels
FeatureRequest GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@kevinburke1
Copy link

kevinburke1 commented Apr 13, 2021

Go can install binaries into one of several locations, I think:

  • if GOBIN is set, go will install to that directory
  • if GOPATH is set, go will install to GOPATH[0]/bin
  • otherwise (usually), $HOME/go/bin

I'm working with several people who are not really Go programmers, but need to install Go services in order to do their jobs (frontend programming, design, etc). It's a frequent pattern to have instructions that say like "run go install ./... and then start the server" and then they get "meter-server: command not found" because they haven't added whatever directory to their $PATH. So then I need to figure out where Go is actually installing binaries to and then walk them through that process. This is more difficult now when I can't sit right next to them and walk through the commands.

Having a way to easily see which directory Go is installing, or going to, install packages would be very helpful.

Going beyond that, a tool in the x/tools that can append that directory to your $PATH, based on your shell, would be extremely helpful.

@seankhliao seankhliao added GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. labels Apr 13, 2021
@seankhliao
Copy link
Member

maybe we can make GOBIN point to the chosen directory if otherwise unset? Then the command would be go env GOBIN

cc @bcmills @jayconrod @matloob

@kevinburke1
Copy link
Author

"go help environment" reports:

Additional information available from 'go env' but not read from the environment:

    GOEXE
	    The executable file name suffix (".exe" on Windows, "" on other systems).
    GOGCCFLAGS
	    A space-separated list of arguments supplied to the CC command.
    GOHOSTARCH
	    The architecture (GOARCH) of the Go toolchain binaries.
    GOHOSTOS
	    The operating system (GOOS) of the Go toolchain binaries.
    GOMOD
	    The absolute path to the go.mod of the main module.
	    If module-aware mode is enabled, but there is no go.mod, GOMOD will be
	    os.DevNull ("/dev/null" on Unix-like systems, "NUL" on Windows).
	    If module-aware mode is disabled, GOMOD will be the empty string.
    GOTOOLDIR
	    The directory where the go tools (compile, cover, doc, etc...) are installed.
    GOVERSION
	    The version of the installed Go tree, as reported by runtime.Version.

Perhaps we could add another value? GOINSTALLDIR or similar. One issue is GOINSTALLDIR would be less permanent than the values listed above.

@kevinburke1
Copy link
Author

or "go tool installdir"

@bcmills
Copy link
Contributor

bcmills commented Apr 13, 2021

Duplicate of #23439?

@bcmills
Copy link
Contributor

bcmills commented Apr 13, 2021

Also note that you can use go list -f {{.Target}} $IMPORTPATH to obtain this information for a given package main.

@kevinburke1
Copy link
Author

If you want "go env GOBIN" to always print the answer to this question instead of being empty if $GOBIN is empty, then yes it's a duplicate, however there are a few different ways to potentially solve this problem.

@kevinburke1
Copy link
Author

kevinburke1 commented Apr 13, 2021

Also note that you can use go list -f {{.Target}} $IMPORTPATH to obtain this information for a given package main.

This is really helpful and does basically what I want, thanks, though I guess the interface could be more intuitive. In the #general channel of the Gophers slack no one has suggested this so far in about 30 minutes, which suggests awareness of this solution is not widespread.

@eliasnaur
Copy link
Contributor

I'm working with several people who are not really Go programmers, but need to install Go services in order to do their jobs (frontend programming, design, etc). It's a frequent pattern to have instructions that say like "run go install ./... and then start the server" and then they get "meter-server: command not found" because they haven't added whatever directory to their $PATH.

If you have go install ... in your instructions, why not have go run ... instead? With Go 1.17 you can even do go run domain.com/your/main/pkg@some-version outside of any module.

@kevinburke
Copy link
Contributor

go list -f {{.Target}} $IMPORTPATH

Note this doesn't work to check if binaries are installed if they're not present in go.mod, for example test or build helpers like staticcheck.

@seankhliao seankhliao added this to the Unplanned milestone Aug 20, 2022
@thockin
Copy link

thockin commented Jan 20, 2023

I'd really appreciate the ability to do something like:

tool=$(go install --print-result example.com/tool)
"$tool" -flags

@hyangah
Copy link
Contributor

hyangah commented May 8, 2023

We see three different use cases and are considering the following fixes.

  1. A user ran go install but the installed binary is not in user's PATH. User doesn't know where it is installed.
    Possible fix: let go install print the location in stderr if it's installed in the path that's not in PATH.

  2. A user wants to access the installation info programmatically post go install (e.g. cmd/go: command to print out the directory Go will install binaries into #45546 (comment))
    Possible fix: let go install -where print the location in stdout.

  3. A user wants to know where the tool(s) would be installed without installing the tools.
    Possible fix: fix cmd/go: default GOBIN to GOPATH[0]/bin when outside of GOPATH? #23439 (go env GOBIN for module-aware mode)

    Alternatives are go mod init dummy && go get <path> && go list -f {{.Target}}, go install -n <path> &2>1 | grep 'mv $WORK' which aren't ideal.

@thockin
Copy link

thockin commented May 8, 2023

I hit this again this week with a tool within Kubernetes which had not properly set GOPATH and things got splatted all over.

What I'd really love to see is a per-{repo, metadata, dir, something} metadata file which lets me set GOBIN, GOCACHE, GOMODCACHE, and other things (anything that defines where go will write files) to a known place. E.g.

$ cat go.defs
GOBIN = ./_output/bin
GOCACACE = ./_cache/build
GOMODCACHE = ./_cache/mod

@ianlancetaylor
Copy link
Contributor

@thockin That sounds like the work module go.env file. Maybe? Should we try to figure out how to implement more specific versions of #57179?

@thockin
Copy link

thockin commented May 9, 2023

Honestly, I forgot about that thread, where I made more or less the same request :) That one is closed, but yeah - a per-workspace or even per-directory go.env seems like it would do what I want.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
FeatureRequest GoCommand cmd/go NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

8 participants