Last Updated: March 1, 2019.
Discussion at golang.org/issue/30411
Setting environment variables for
go command configuration is too difficult and system-specific. We propose to add
go env -w, to set defaults more easily.
go command is configured by environment variables: see the output of
go env for a partial list, and
go help environment for a longer one. Although nearly all variables are optional, it is not uncommon to need to set one or another. The details of setting an environment variable's initial value differs by operating system and even by distribution or terminal program—for example, do you have to log out entirely, or just restart the shell window?—which can make this environment-based configuration quite difficult. (When setting
$GOPATH was required to get started with Go, doing so was a major stumbling block for new users.)
It would help all users to have a consistent, simple way to set the default value for these configuration variables.
We propose to store in the file
+”/go/env” a list of key-value pairs giving the default settings for configuration variables used by the
go command. Environment variables, when set, override the settings in this file.
go env <NAME> ... command will continue to report the effective values of the named configuration variables, using the current environment, or else the
go.env file, or else a computed default.
A new option
go env -w <NAME>=<VALUE> ... will set one or more configuration variables in the
go.env file. The command will also print a warning if the current environment has
$<NAME> defined and it is not set to
<VALUE>. For example, a user who needs to set a default
$GOPATH could now use:
go env -w GOPATH=$HOME/mygopath
Another popular setting might be:
go env -w GOBIN=$HOME/bin
go env -u <NAME>... will unset (delete, remove) entries in the environment file.
Most users will interact with the
os.UserConfigDir()/go/env file through the
go env and
go env -w command line syntax, so the exact stored file format should not matter too much. But for concreteness, the format is a sequence of lines of the form
<NAME>=<VALUE>, in which everything after the
= is a literal, uninterpreted value—no quoting, no dollar expansion, no multiline values. Blank lines, lines beginning with
#, and lines not containing
=, are ignored. If the file contains multiple lines beginning with
<NAME>=, only the first has any effect. Lines with empty values set the default value to the empty string, possibly overriding a non-empty default.
go command will consult the
os.UserConfigDir()/go/env file. The environment variables that control
go libraries at runtime—for example,
GOTRACEBACK—will not be read from
go.env and will be rejected by
go env command lines.
go command is already configured by environment variables, simple
<KEY>=<VALUE> pairs. An alternative would be to introduce a richer configuration file format, such as JSON, TOML, XML, or YAML, but then we would also need to define how these richer values can be overridden in certain contexts. Continuing to use plain
<KEY>=<VALUE> pairs aligns better with the existing environment-based approach and avoids increasing the potential complexity of any particular configuration.
The use of
os.UserConfigDir() (see golang.org/issue/29960) seems to be the established correct default for most systems. Traditionally we've stored things in
$GOPATH, but we want to allow this file to contain the default value for
$GOPATH. It may be necessary—albeit ironic—to add a
GOENV environment variable overriding the default location. Obviously, it would not be possible to set the default for
GOENV itself in the file.
There are no compatibility issues. It may be surprising in some use cases that an empty environment still uses the
go.env settings, but those contexts could avoid creating a
go.env in the first place, or (if we add it) set
Russ Cox plans to do the implementation in the
go command in Go 1.13.