Commit 94968155 authored by Ian Lance Taylor's avatar Ian Lance Taylor

cmd/go: put all generate variables in the environment

Fixes #13124.

Change-Id: I8a824156c84016504d29dc2dd2d522149b189be8
Reviewed-on: https://go-review.googlesource.com/16537Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent b16c6991
...@@ -179,6 +179,7 @@ type Generator struct { ...@@ -179,6 +179,7 @@ type Generator struct {
pkg string pkg string
commands map[string][]string commands map[string][]string
lineNum int // current line number. lineNum int // current line number.
env []string
} }
// run runs the generators in the current file. // run runs the generators in the current file.
...@@ -242,6 +243,7 @@ func (g *Generator) run() (ok bool) { ...@@ -242,6 +243,7 @@ func (g *Generator) run() (ok bool) {
} }
} }
g.setEnv()
words := g.split(string(buf)) words := g.split(string(buf))
if len(words) == 0 { if len(words) == 0 {
g.errorf("no arguments to directive") g.errorf("no arguments to directive")
...@@ -269,6 +271,19 @@ func isGoGenerate(buf []byte) bool { ...@@ -269,6 +271,19 @@ func isGoGenerate(buf []byte) bool {
return bytes.HasPrefix(buf, []byte("//go:generate ")) || bytes.HasPrefix(buf, []byte("//go:generate\t")) return bytes.HasPrefix(buf, []byte("//go:generate ")) || bytes.HasPrefix(buf, []byte("//go:generate\t"))
} }
// setEnv sets the extra environment variables used when executing a
// single go:generate command.
func (g *Generator) setEnv() {
g.env = []string{
"GOARCH=" + runtime.GOARCH,
"GOOS=" + runtime.GOOS,
"GOFILE=" + g.file,
"GOLINE=" + strconv.Itoa(g.lineNum),
"GOPACKAGE=" + g.pkg,
"DOLLAR=" + "$",
}
}
// split breaks the line into words, evaluating quoted // split breaks the line into words, evaluating quoted
// strings and evaluating environment variables. // strings and evaluating environment variables.
// The initial //go:generate element is present in line. // The initial //go:generate element is present in line.
...@@ -345,22 +360,13 @@ func (g *Generator) errorf(format string, args ...interface{}) { ...@@ -345,22 +360,13 @@ func (g *Generator) errorf(format string, args ...interface{}) {
// expandVar expands the $XXX invocation in word. It is called // expandVar expands the $XXX invocation in word. It is called
// by os.Expand. // by os.Expand.
func (g *Generator) expandVar(word string) string { func (g *Generator) expandVar(word string) string {
switch word { w := word + "="
case "GOARCH": for _, e := range g.env {
return buildContext.GOARCH if strings.HasPrefix(e, w) {
case "GOOS": return e[len(w):]
return buildContext.GOOS }
case "GOFILE":
return g.file
case "GOLINE":
return fmt.Sprint(g.lineNum)
case "GOPACKAGE":
return g.pkg
case "DOLLAR":
return "$"
default:
return os.Getenv(word)
} }
return os.Getenv(word)
} }
// identLength returns the length of the identifier beginning the string. // identLength returns the length of the identifier beginning the string.
...@@ -396,13 +402,7 @@ func (g *Generator) exec(words []string) { ...@@ -396,13 +402,7 @@ func (g *Generator) exec(words []string) {
cmd.Stderr = os.Stderr cmd.Stderr = os.Stderr
// Run the command in the package directory. // Run the command in the package directory.
cmd.Dir = g.dir cmd.Dir = g.dir
env := []string{ cmd.Env = mergeEnvLists(g.env, origEnv)
"GOARCH=" + runtime.GOARCH,
"GOOS=" + runtime.GOOS,
"GOFILE=" + g.file,
"GOPACKAGE=" + g.pkg,
}
cmd.Env = mergeEnvLists(env, origEnv)
err := cmd.Run() err := cmd.Run()
if err != nil { if err != nil {
g.errorf("running %q: %s", words[0], err) g.errorf("running %q: %s", words[0], err)
......
...@@ -39,6 +39,7 @@ func TestGenerateCommandParse(t *testing.T) { ...@@ -39,6 +39,7 @@ func TestGenerateCommandParse(t *testing.T) {
pkg: "sys", pkg: "sys",
commands: make(map[string][]string), commands: make(map[string][]string),
} }
g.setEnv()
g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"}) g.setShorthand([]string{"-command", "yacc", "go", "tool", "yacc"})
for _, test := range splitTests { for _, test := range splitTests {
// First with newlines. // First with newlines.
......
...@@ -2035,6 +2035,20 @@ func TestGoGenerateRunFlag(t *testing.T) { ...@@ -2035,6 +2035,20 @@ func TestGoGenerateRunFlag(t *testing.T) {
tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no") tg.grepStdoutNot("no", "go generate -run yes ./testdata/generate/test4.go selected no")
} }
func TestGoGenerateEnv(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("skipping because windows does not have the env command")
}
tg := testgo(t)
defer tg.cleanup()
tg.parallel()
tg.tempFile("env.go", "package main\n\n//go:generate env")
tg.run("generate", tg.path("env.go"))
for _, v := range []string{"GOARCH", "GOOS", "GOFILE", "GOLINE", "GOPACKAGE", "DOLLAR"} {
tg.grepStdout("^"+v+"=", "go generate environment missing "+v)
}
}
func TestGoGetCustomDomainWildcard(t *testing.T) { func TestGoGetCustomDomainWildcard(t *testing.T) {
testenv.MustHaveExternalNetwork(t) testenv.MustHaveExternalNetwork(t)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment