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

proposal: cmd/go: support local experiments with interdependent modules; then retire GOPATH #44347

ohir opened this issue Feb 17, 2021 · 2 comments


Copy link

@ohir ohir commented Feb 17, 2021

Go "tinker mode" proposal.

Last updated: 2021/02/18


@cosban wrote: I need to be able to, without being forced to commit code that is not fully vetted, build and test our modifications. (@cosban)

@rsc wrote: GOPATH is holding back the ecosystem and the toolchain. It's time to retire it. [...] we're happy to listen. But GOPATH needs to go. (@rsc)

@bcmills wrote: Many module issues and questions seem to center on editing, testing, and deploying multiple (possibly mutually-interdependent, possibly cyclic) modules (@bcmills)

The main workaround at the moment is to add replace directives among the modules to be edited, but maintaining those directives is tedious and error-prone. @rogpeppe's gohack tool automates away some of the tedium, but doesn't seem to remove the risk of accidentally checking in a go.mod with what were intended to be local, temporary replacements.

Related: #26640, #37755, #26377, #25053.

If an environment variable named GOTINKER is defined and set to an absolute path to the existing location on the local filesystem, and the import path of an include can be found under $GOTINKER/ directory, then build commands treat the $GOTINKER/src/import/path as a final authoritative source of the import; foregoing both vendor/ and any go.mod directive perpeting to this import/path.

Ie. build commands like 'go build' and 'go test' will compile modules present in the $GOTINKER directory instead of accessing the network, local module cache, or vendor directory.

Under tinker mode GOBIN, GOCACHE, GOMODCACHE, and GOENV are bound to locations relative to the GOTINKER: $GOTINKER/bin, $GOTINKER/cache, $GOTINKER/pkg/mod, and $GOTINKER/goenv - respectively.

$GOTINKER tree should be populated by the user. For yet some time to come the last version of Go to support GOPATH can be used to ease this task, ie. GOROOT=/where/go1.16 GO111MODULE=off GOPATH="$GOTINKER" go1.16 get

GOTINKER path last element may start with an underscore character so experiments can be kept inside any project tree.

Security considerations

Both object code and the executable built under the tinker mode should not accidentally leak to the production environment. Ie. while objects are built and cached under $GOTINKER, then built executable MUST be amended (by the compiler) to refuse to run in an environment where GOTINKER is not set, or it is set but does not match the last element of the GOTINKER path that was compiled in.

Ie. "tinkered with" executable preserves the last part of the GOTINKER path then matches it to the last part of GOTINKER string where it runs. If these do not match, exectutable exits immediately with "Experimental but GOTINKER is not set or did not match" error message.


  • 2021/02/17 added "match compiled in GOTINKER with run one" in Security
  • 2021/02/18 be explicit about possibility to keep GOTINKER tree inside a module tree, eg. in a _tinker/ subdirectory.
@gopherbot gopherbot added this to the Proposal milestone Feb 17, 2021
@gopherbot gopherbot added the Proposal label Feb 17, 2021
@ianlancetaylor ianlancetaylor added this to Incoming in Proposals Feb 17, 2021
Copy link

@ianlancetaylor ianlancetaylor commented Feb 17, 2021

Copy link

@jayconrod jayconrod commented Feb 17, 2021

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
4 participants