]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: set GOROOT explicitly for 'go generate' subprocesses
authorBryan C. Mills <bcmills@google.com>
Fri, 8 Apr 2022 19:26:38 +0000 (15:26 -0400)
committerBryan Mills <bcmills@google.com>
Tue, 12 Apr 2022 03:13:39 +0000 (03:13 +0000)
Code generators may reasonably expect to find the GOROOT for which the
code is being generated.

If the generator invokes 'go run' (which ought to be reasonable to do)
and the user has set 'GOFLAGS=trimpath' (which also ought to be
reasonable), then either 'go generate' or 'go run' needs to set GOROOT
explicitly.

I would argue that it is more appropriate for 'go generate' to set
GOROOT than for 'go run' to do so, since a user may reasonably invoke
'go run' to reproduce a user-reported bug in a standalone Go program,
but should not invoke 'go generate' except to regenerate code for a Go
package.

Updates #51461.

Change-Id: Iceba233b4eebd57c40cf5dcd4af9031d210dc9d8
Reviewed-on: https://go-review.googlesource.com/c/go/+/399157
Run-TryBot: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>

src/cmd/go/alldocs.go
src/cmd/go/internal/generate/generate.go
src/cmd/go/testdata/script/build_trimpath_goroot.txt

index 6800e1c7d2e1899ad77e54e58c0810aff083163a..586bc1a7ca57a3a621ea222198fbea4464871af7 100644 (file)
 //             The line number of the directive in the source file.
 //     $GOPACKAGE
 //             The name of the package of the file containing the directive.
+//     $GOROOT
+//             The GOROOT directory for the 'go' command that invoked the
+//             generator, containing the Go toolchain and standard library.
 //     $DOLLAR
 //             A dollar sign.
 //
index 0021bcc75aa2b37c6e07892913b0169fc0daa211..a46f4f8908c44bd6976e831f172a5fad8bef9cf4 100644 (file)
@@ -84,6 +84,9 @@ Go generate sets several variables when it runs the generator:
                The line number of the directive in the source file.
        $GOPACKAGE
                The name of the package of the file containing the directive.
+       $GOROOT
+               The GOROOT directory for the 'go' command that invoked the
+               generator, containing the Go toolchain and standard library.
        $DOLLAR
                A dollar sign.
 
@@ -326,6 +329,7 @@ func isGoGenerate(buf []byte) bool {
 // single go:generate command.
 func (g *Generator) setEnv() {
        g.env = []string{
+               "GOROOT=" + cfg.GOROOT,
                "GOARCH=" + cfg.BuildContext.GOARCH,
                "GOOS=" + cfg.BuildContext.GOOS,
                "GOFILE=" + g.file,
index 91e5107e589db546d073a95a309ae463dab74f6c..a26cfd23be488cdf90afba4b270e9ad7469483c2 100644 (file)
@@ -62,6 +62,11 @@ stderr 'cannot find package "runtime" in any of:\n\t\(\$GOROOT not set\)\n\t'$WO
 stdout '^GOROOT $'
 stdout 'cannot find package "runtime" in any of:\n\t\(\$GOROOT not set\)\n\t'$WORK${/}gopath${/}src${/}runtime' \(from \$GOPATH\)$'
 
+env GOFLAGS=-trimpath
+go generate .
+stdout '^GOROOT '$TESTGO_GOROOT'$'
+stdout '^runtime '$TESTGO_GOROOT${/}src${/}runtime'$'
+
 -- go.mod --
 module example
 
@@ -69,6 +74,8 @@ go 1.19
 -- main.go --
 package main
 
+//go:generate go run .
+
 import (
        "fmt"
        "go/build"