design: add

See and golang/go#30411.

Change-Id: I8f75958b1c75dea7420d7c90ad8b9d592ce03460
Run-TryBot: Russ Cox <>
Reviewed-by: Russ Cox <>
diff --git a/design/ b/design/
new file mode 100644
index 0000000..4d97568
--- /dev/null
+++ b/design/
@@ -0,0 +1,114 @@
+# Proposal: `go` command configuration file
+Russ Cox
+Last Updated: March 1, 2019.
+Discussion at [](
+## Abstract
+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.
+## Background
+The `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.
+## Proposal
+We propose to store in the file [`os.UserConfigDir()`](`+”/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.
+The `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
+The command `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.
+Only the `go` command will consult the `os.UserConfigDir()/go/env` file.
+The environment variables that control `go` libraries at runtime—for example,
+`GODEBUG`, `GOMAXPROCS`, and `GOTRACEBACK`—will not be read from
+`go.env` and will be rejected by `go env` command lines.
+## Rationale
+The `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 [](
+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.
+## Compatibility
+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 `GOENV=off`.
+## Implementation
+Russ Cox plans to do the implementation in the `go` command in Go 1.13.