Commit 2807572a authored by Rob Pike's avatar Rob Pike

cmd/go: implement the long-promised -run flag for go generate

Trivial to do, but overlooked for 1.4, which is good because I prefer
the new design, which is just to match against the source code of
the line rather than the command word alone.

Change-Id: Idcf7c4479e97bb7cd732f0d058012321b6057628
Reviewed-on: https://go-review.googlesource.com/9005Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 27067df9
...@@ -322,9 +322,10 @@ The generator is run in the package's source directory. ...@@ -322,9 +322,10 @@ The generator is run in the package's source directory.
Go generate accepts one specific flag: Go generate accepts one specific flag:
-run="" -run=""
TODO: This flag is unimplemented. if non-empty, specifies a regular expression to select
if non-empty, specifies a regular expression to directives whose full original source text (excluding
select directives whose command matches the expression. any trailing spaces and final newline) matches the
expression.
It also accepts the standard build flags -v, -n, and -x. It also accepts the standard build flags -v, -n, and -x.
The -v flag prints the names of packages and files as they are The -v flag prints the names of packages and files as they are
......
...@@ -13,6 +13,7 @@ import ( ...@@ -13,6 +13,7 @@ import (
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
"regexp"
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
...@@ -108,9 +109,10 @@ The generator is run in the package's source directory. ...@@ -108,9 +109,10 @@ The generator is run in the package's source directory.
Go generate accepts one specific flag: Go generate accepts one specific flag:
-run="" -run=""
TODO: This flag is unimplemented. if non-empty, specifies a regular expression to select
if non-empty, specifies a regular expression to directives whose full original source text (excluding
select directives whose command matches the expression. any trailing spaces and final newline) matches the
expression.
It also accepts the standard build flags -v, -n, and -x. It also accepts the standard build flags -v, -n, and -x.
The -v flag prints the names of packages and files as they are The -v flag prints the names of packages and files as they are
...@@ -122,7 +124,10 @@ For more about specifying packages, see 'go help packages'. ...@@ -122,7 +124,10 @@ For more about specifying packages, see 'go help packages'.
`, `,
} }
var generateRunFlag string // generate -run flag var (
generateRunFlag string // generate -run flag
generateRunRE *regexp.Regexp // compiled expression for -run
)
func init() { func init() {
addBuildFlags(cmdGenerate) addBuildFlags(cmdGenerate)
...@@ -130,6 +135,13 @@ func init() { ...@@ -130,6 +135,13 @@ func init() {
} }
func runGenerate(cmd *Command, args []string) { func runGenerate(cmd *Command, args []string) {
if generateRunFlag != "" {
var err error
generateRunRE, err = regexp.Compile(generateRunFlag)
if err != nil {
log.Fatalf("generate: %s", err)
}
}
// Even if the arguments are .go files, this loop suffices. // Even if the arguments are .go files, this loop suffices.
for _, pkg := range packages(args) { for _, pkg := range packages(args) {
for _, file := range pkg.gofiles { for _, file := range pkg.gofiles {
...@@ -223,6 +235,11 @@ func (g *Generator) run() (ok bool) { ...@@ -223,6 +235,11 @@ func (g *Generator) run() (ok bool) {
if !isGoGenerate(buf) { if !isGoGenerate(buf) {
continue continue
} }
if generateRunFlag != "" {
if !generateRunRE.Match(bytes.TrimSpace(buf)) {
continue
}
}
words := g.split(string(buf)) words := g.split(string(buf))
if len(words) == 0 { if len(words) == 0 {
......
...@@ -1069,28 +1069,40 @@ fi ...@@ -1069,28 +1069,40 @@ fi
TEST 'go generate handles simple command' TEST 'go generate handles simple command'
if ! ./testgo generate ./testdata/generate/test1.go > testdata/std.out; then if ! ./testgo generate ./testdata/generate/test1.go > testdata/std.out; then
echo "go test ./testdata/generate/test1.go failed to run" echo "go generate ./testdata/generate/test1.go failed to run"
ok=false ok=false
elif ! grep 'Success' testdata/std.out > /dev/null; then elif ! grep 'Success' testdata/std.out > /dev/null; then
echo "go test ./testdata/generate/test1.go generated wrong output" echo "go generate ./testdata/generate/test1.go generated wrong output"
ok=false ok=false
fi fi
TEST 'go generate handles command alias' TEST 'go generate handles command alias'
if ! ./testgo generate ./testdata/generate/test2.go > testdata/std.out; then if ! ./testgo generate ./testdata/generate/test2.go > testdata/std.out; then
echo "go test ./testdata/generate/test2.go failed to run" echo "go generate ./testdata/generate/test2.go failed to run"
ok=false ok=false
elif ! grep 'Now is the time for all good men' testdata/std.out > /dev/null; then elif ! grep 'Now is the time for all good men' testdata/std.out > /dev/null; then
echo "go test ./testdata/generate/test2.go generated wrong output" echo "go generate ./testdata/generate/test2.go generated wrong output"
ok=false ok=false
fi fi
TEST 'go generate variable substitution' TEST 'go generate variable substitution'
if ! ./testgo generate ./testdata/generate/test3.go > testdata/std.out; then if ! ./testgo generate ./testdata/generate/test3.go > testdata/std.out; then
echo "go test ./testdata/generate/test3.go failed to run" echo "go generate ./testdata/generate/test3.go failed to run"
ok=false ok=false
elif ! grep "$GOARCH test3.go p xyzp/test3.go/123" testdata/std.out > /dev/null; then elif ! grep "$GOARCH test3.go p xyzp/test3.go/123" testdata/std.out > /dev/null; then
echo "go test ./testdata/generate/test3.go generated wrong output" echo "go generate ./testdata/generate/test3.go generated wrong output"
ok=false
fi
TEST 'go generate run flag'
if ! ./testgo generate -run y.s ./testdata/generate/test4.go > testdata/std.out; then
echo "go test -run y.s ./testdata/generate/test4.go failed to run"
ok=false
elif ! grep "yes" testdata/std.out > /dev/null; then
echo "go generate -run y.s ./testdata/generate/test4.go did not select yes"
ok=false
elif grep "no" testdata/std.out > /dev/null; then
echo "go generate -run y.s ./testdata/generate/test4.go selected no"
ok=false ok=false
fi fi
......
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Test -run flag
//go:generate echo oh yes my man
//go:generate echo no, no, a thousand times no
package p
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