|
| 1 | +# Proposal: `go` command configuration file |
| 2 | + |
| 3 | +Russ Cox |
| 4 | + |
| 5 | +Last Updated: March 1, 2019. |
| 6 | + |
| 7 | +[golang.org/design/30411-env](https://golang.org/design/30411-env) |
| 8 | + |
| 9 | +Discussion at [golang.org/issue/30411](https://golang.org/issue/30411) |
| 10 | + |
| 11 | +## Abstract |
| 12 | + |
| 13 | +Setting environment variables for `go` command configuration |
| 14 | +is too difficult and system-specific. |
| 15 | +We propose to add `go env -w`, to set defaults more easily. |
| 16 | + |
| 17 | +## Background |
| 18 | + |
| 19 | +The `go` command is configured by environment variables: |
| 20 | +see the output of `go env` for a partial list, |
| 21 | +and `go help environment` for a longer one. |
| 22 | +Although nearly all variables are optional, |
| 23 | +it is not uncommon to need to set one or another. |
| 24 | +The details of setting an environment variable's initial value |
| 25 | +differs by operating system and even by distribution or |
| 26 | +terminal program—for example, do you have to log out entirely, |
| 27 | +or just restart the shell window?—which can make this environment-based configuration |
| 28 | +quite difficult. |
| 29 | +(When setting `$GOPATH` was required to get started with Go, |
| 30 | +doing so was a major stumbling block for new users.) |
| 31 | + |
| 32 | +It would help all users to have a consistent, simple way to set the |
| 33 | +default value for these configuration variables. |
| 34 | + |
| 35 | +## Proposal |
| 36 | + |
| 37 | +We propose to store in the file [`os.UserConfigDir()`](https://golang.org/issue/29960)`+”/go/env”` |
| 38 | +a list of key-value pairs giving the default settings for |
| 39 | +configuration variables used by the `go` command. |
| 40 | +Environment variables, when set, override the settings in this file. |
| 41 | + |
| 42 | +The `go env <NAME> ...` command will continue to report the |
| 43 | +effective values of the named configuration variables, |
| 44 | +using the current environment, or else the `go.env` file, |
| 45 | +or else a computed default. |
| 46 | + |
| 47 | +A new option `go env -w <NAME>=<VALUE> ...` will set one or more |
| 48 | +configuration variables in the `go.env` file. |
| 49 | +The command will also print a warning if the |
| 50 | +current environment has `$<NAME>` defined |
| 51 | +and it is not set to `<VALUE>`. |
| 52 | +For example, a user who needs to set a default `$GOPATH` |
| 53 | +could now use: |
| 54 | + |
| 55 | + go env -w GOPATH=$HOME/mygopath |
| 56 | + |
| 57 | +Another popular setting might be: |
| 58 | + |
| 59 | + go env -w GOBIN=$HOME/bin |
| 60 | + |
| 61 | +The command `go env -u <NAME>...` will unset (delete, remove) entries |
| 62 | +in the environment file. |
| 63 | + |
| 64 | +Most users will interact with the `os.UserConfigDir()/go/env` file through the |
| 65 | +`go env` and `go env -w` command line syntax, |
| 66 | +so the exact stored file format |
| 67 | +should not matter too much. |
| 68 | +But for concreteness, the format is a sequence |
| 69 | +of lines of the form `<NAME>=<VALUE>`, |
| 70 | +in which everything after the `=` is a literal, uninterpreted value—no quoting, |
| 71 | +no dollar expansion, no multiline values. |
| 72 | +Blank lines, lines beginning with `#`, and |
| 73 | +lines not containing `=`, are ignored. |
| 74 | +If the file contains multiple lines beginning with `<NAME>=`, only the first has any effect. |
| 75 | +Lines with empty values set the default value to the empty string, |
| 76 | +possibly overriding a non-empty default. |
| 77 | + |
| 78 | +Only the `go` command will consult the `os.UserConfigDir()/go/env` file. |
| 79 | +The environment variables that control `go` libraries at runtime—for example, |
| 80 | +`GODEBUG`, `GOMAXPROCS`, and `GOTRACEBACK`—will not be read from |
| 81 | +`go.env` and will be rejected by `go env` command lines. |
| 82 | + |
| 83 | +## Rationale |
| 84 | + |
| 85 | +The `go` command is already configured by environment variables, |
| 86 | +simple `<KEY>=<VALUE>` pairs. |
| 87 | +An alternative would be to introduce a richer configuration file format, |
| 88 | +such as JSON, TOML, XML, or YAML, |
| 89 | +but then we would also need to define how these richer values |
| 90 | +can be overridden in certain contexts. |
| 91 | +Continuing to use plain `<KEY>=<VALUE>` pairs |
| 92 | +aligns better with the existing environment-based approach |
| 93 | +and avoids increasing the potential complexity of any particular configuration. |
| 94 | + |
| 95 | +The use of `os.UserConfigDir()` (see [golang.org/issue/29960](https://golang.org/issue/29960)) |
| 96 | +seems to be the established correct default for most systems. |
| 97 | +Traditionally we've stored things in `$GOPATH`, but we want to allow this file to contain |
| 98 | +the default value for `$GOPATH`. |
| 99 | +It may be necessary—albeit ironic—to add a `GOENV` environment variable |
| 100 | +overriding the default location. |
| 101 | +Obviously, it would not be possible to set the default for `GOENV` itself in the file. |
| 102 | + |
| 103 | +## Compatibility |
| 104 | + |
| 105 | +There are no compatibility issues. |
| 106 | +It may be surprising in some use cases |
| 107 | +that an empty environment still uses the `go.env` settings, |
| 108 | +but those contexts could avoid creating a `go.env` in the first place, |
| 109 | +or (if we add it) set `GOENV=off`. |
| 110 | + |
| 111 | +## Implementation |
| 112 | + |
| 113 | +Russ Cox plans to do the implementation in the `go` command in Go 1.13. |
| 114 | + |
0 commit comments