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 a -C flag value to not use any current directory #56868

Open
mvdan opened this issue Nov 21, 2022 · 3 comments
Open
Labels
GoCommand cmd/go Proposal Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@mvdan
Copy link
Member

mvdan commented Nov 21, 2022

cmd/go uses the current directory for a number of things:

  • Walking parent directories to find the current module
  • Walking parent directories to find the current workspace
  • Resolving relative package paths, like . or ./foo

However, in some cases, we do not need any of those. For example:

  • When querying global config settings, like go env -json GOROOT GOCACHE GOPROXY
  • When querying the default build context, like go list -f={{context.ReleaseTags}} runtime
  • When querying information about the standard library, like go list -json runtime

On one hand, finding the current module and workspace for these three commands is wasteful. On the other, it can be actively harmful. For example, if the current directory or any of its parents has a go.mod with broken syntax, then any of the three commands above may fail. In our fork of cmd/go/script_test.go, we had to make calls like these inside a temporary directory to work around the problem: rogpeppe/go-internal#188

Using a temporary directory is also far from ideal. It still walks the parent directories, which is still wasteful. And it could still break in some (hopefully rare) edge cases, like if /tmp/go.mod existed and had broken syntax.

One possible solution would be to manually turn off the search for "current module" and "current workspace". For the latter, it seems that we can use GOWORK=off. For the former, I don't seem to be able to find an "off" setting. There's GO111MODULE=off, but I don't really want GOPATH mode either, and I believe this mode will disappear at some point anyway.

Moreover, turning off the search for these two files may be enough today, but in the future cmd/go may use the current directory to look for more files, just like go.work was introduced recently. So I really want a general option to mean "do not use the current directory to alter your behavior in any way".

Luckily, in #50332 we gained a global "chdir" option. I propose that it gain a special value, -C=off, to mean just that. The process would still have a current directory, and it would still make direct accesses to the filesystem (e.g. to look inside GOROOT or to read the GOENV file), but any major feature relying on the current directory would be disabled or fail. For example:

  • There would never be a current or main module
  • There would never be a current or main workspace
  • Relative package paths, like go list . or go list ./foo, would fail

I realise that this is likely a complex set of changes for the innards of cmd/go, as the current directory is likely used in many places. I also realise that it likely does not make sense to use some commands like go build -C=off. So perhaps we could start by only supporting this mode in go env and go list: two commands often used by Go tools to get the information they need.

cc @myitcv @rogpeppe

@mvdan mvdan added Proposal GoCommand cmd/go Tools This label describes issues relating to any tools in the x/tools repository. labels Nov 21, 2022
@gopherbot gopherbot added this to the Proposal milestone Nov 21, 2022
@mvdan
Copy link
Member Author

mvdan commented Nov 21, 2022

One existing alternative would be -C=/, with the understanding that the root directory should never be a Go module or workspace. However, that value isn't portable to Windows, and the root directory will often cause other problems: the user may not be able to read/write it, or it may still contain Go files.

There's also -C=/dev/null, but again that's not portable - off is a portable constant, and it's already used for other file-based flags like -pgo=off or GOWORK=off. One could still chdir into the directory "off" via -C ./off, I presume.

@seankhliao
Copy link
Member

seankhliao commented Nov 22, 2022

Apparently some people do build at root /: #49570
off works for GOWORK because it has a naming convention, it without be unfortunate to carve out a valid name that breaks sometimes

@mvdan
Copy link
Member Author

mvdan commented Nov 22, 2022

I guess I don't have anything against people building as the root/superuser in the root directory, but I definitely don't want to be doing that :)

I'm not particularly worried about taking -C off because the same would apply to -pgo off, and one can always sidestep the limitation via -C ./off or -C $PWD/off.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GoCommand cmd/go Proposal Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants