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: allow go run to pass custom environment variables #63250

Open
dolmen opened this issue Sep 26, 2023 · 10 comments
Open

proposal: cmd/go: allow go run to pass custom environment variables #63250

dolmen opened this issue Sep 26, 2023 · 10 comments
Milestone

Comments

@dolmen
Copy link
Contributor

dolmen commented Sep 26, 2023

This is a proposal to extend the syntax of the command line of go run to allow to pass environment variables to the program that is executed after its compilation.

The current syntax:

go run [build flags] [-exec xprog] package [arguments...]

The proposed syntax:

go run [build flags] [-exec xprog] [name=value ...] package [arguments...]

That extended syntax will be incompatible with = being used in the package (package name, .go file) specification. However the language reference already mentions that a compiler implementation may exclude = from import paths.

Why?

  1. It is useful to be able to pass to the compiled program some environment variables with values different from the values passed to go run which might be needed for building the program (example: x/text/cmd/gotext: generate for one GOOS/GOARCH from a different GOOS/GOARCH #37846)
  2. go run is often used in //go:generate commands. It is often needed to pass environment variables to the program, but there is no built-in portable way for calling a command with environment variables (env(1) is available on Unixes, but not on Windows. Workaround: github.com/dolmen-go/env)
@gopherbot gopherbot added this to the Proposal milestone Sep 26, 2023
@seankhliao seankhliao changed the title proposal: cmd/go/internal/run: extend go run CLI to allow to pass environment variables when executing the program proposal: cmd/go: allow go run to pass custom environment variables Sep 26, 2023
@robpike
Copy link
Contributor

robpike commented Sep 26, 2023

I would argue against complicating go run, which should only be used for quick little tests and not for production jobs. Also, there should be little need for generators to be portable, as the design is for them to run on the author's machine, not the user's. In any case I don't see why prefixing the command with VAR=VALUE wouldn't cover almost every possible use of this idea, and for portability to Windows one can always wrap the command with sh -c.

@ianlancetaylor ianlancetaylor added the GoCommand cmd/go label Sep 27, 2023
@ianlancetaylor
Copy link
Contributor

CC @bcmills @matloob

@dolmen
Copy link
Contributor Author

dolmen commented Sep 28, 2023

Also, there should be little need for generators to be portable, as the design is for them to run on the author's machine, not the user's.

In a development team some developers might work on Windows while others on Unixes. This is even more true on open source projects where you can't enforce a unified development environment.

In any case I don't see why prefixing the command with VAR=VALUE wouldn't cover almost every possible use of this idea, and for portability to Windows one can always wrap the command with sh -c.

  • VAR=value go run foo.go doesn't work on Windows.
  • Windows doesn't have sh in PATH.

@apparentlymart
Copy link

apparentlymart commented Sep 28, 2023

If the motivation for this is primarily about go:generate comments and the go generate command, would you consider a solution that is more tightly scoped to that mechanism?

For example, I imagine that the code that finds go:generate comments and extracts the commands to run could, in principle, recognise a syntax for specifying environment variables to set and set them itself before running the specified command. That would still add some complexity, but it would be felt only by the subsystem that would seem to benefit from it the most.


With that said, if the environment variable values are going to be hardcoded into a comment in your source code anyway, I would expect that you could equivalently run a small wrapper program included in your own repository which sets those variables and then runs the main tool you intended to run.

It would be less convenient of course, but it seems justified for more esoteric needs to have less convenient solutions. I suppose we will see in this discussion whether this is an esoteric need or a common situation!

(I personally have not encountered this problem despite making quite extensive use of go:generate, but of course I am only one data point.)

@bcmills
Copy link
Contributor

bcmills commented Sep 28, 2023

For go:generate commands, you can always write a small Go program that sets the required environment variables and then invokes some other command, and have your go:generate line go run that program.

(But at that point why not have the command accept flags instead?)

@dolmen
Copy link
Contributor Author

dolmen commented Sep 29, 2023

For go:generate commands, you can always write a small Go program that sets the required environment variables and then invokes some other command, and have your go:generate line go run that program.

I have written github.com/dolmen-go/env (a portable implementation of env(1) that you can run via go run) for that purpose, and I have already pointed to it in the proposal.

@dolmen
Copy link
Contributor Author

dolmen commented Sep 29, 2023

@bcmills wrote:

(But at that point why not have the command accept flags instead?)

Here is one to fix in src/time/zoneinfo.go:

//go:generate env ZONEINFO=$GOROOT/lib/time/zoneinfo.zip go run genzabbrs.go -output zoneinfo_abbrs_windows.go

Replacing the environment variable with a command line flag in genzabbrs.go is not that trivial.

@dolmen
Copy link
Contributor Author

dolmen commented Sep 29, 2023

It seems that #37846 is the perfect use case for this proposal.

@metux
Copy link

metux commented Sep 30, 2023

IMHO the problem goes much deeper and the proposal is just a workaround for a different problem:
go generate needs to be aware of crosscompile situations and cant trust the GOARCH/GOOS variables, but instead detect on its own (unless explicity told by other variables)
See my comments in the other ticket.

@bcmills
Copy link
Contributor

bcmills commented Oct 13, 2023

@dolmen

Replacing the environment variable with a command line flag in genzabbrs.go is not that trivial.

Isn't it? Seems like it would just need something like os.Setenv("ZONEINFO", *zoneinfo) in between the calls to flag.Parse and readWindowsZones. 🤔

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Incoming
Development

No branches or pull requests

7 participants