Skip to content

Commit

Permalink
design: add 30411-env.md
Browse files Browse the repository at this point in the history
See https://golang.org/design/30411-env and golang/go#30411.

Change-Id: I8f75958b1c75dea7420d7c90ad8b9d592ce03460
Reviewed-on: https://go-review.googlesource.com/c/164817
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
  • Loading branch information
rsc committed Mar 1, 2019
1 parent 5b63da9 commit dfb60c7
Showing 1 changed file with 114 additions and 0 deletions.
114 changes: 114 additions & 0 deletions design/30411-env.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Proposal: `go` command configuration file

Russ Cox

Last Updated: March 1, 2019.

[golang.org/design/30411-env](https://golang.org/design/30411-env)

Discussion at [golang.org/issue/30411](https://golang.org/issue/30411)

## 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()`](https://golang.org/issue/29960)`+”/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 [golang.org/issue/29960](https://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.

## 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.

0 comments on commit dfb60c7

Please sign in to comment.