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: 's avatarRuss Cox <rsc@golang.org>
parent 27067df9
......@@ -322,9 +322,10 @@ The generator is run in the package's source directory.
Go generate accepts one specific flag:
-run=""
TODO: This flag is unimplemented.
if non-empty, specifies a regular expression to
select directives whose command matches the expression.
if non-empty, specifies a regular expression to select
directives whose full original source text (excluding
any trailing spaces and final newline) matches the
expression.
It also accepts the standard build flags -v, -n, and -x.
The -v flag prints the names of packages and files as they are
......
......@@ -13,6 +13,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"runtime"
"strconv"
"strings"
......@@ -108,9 +109,10 @@ The generator is run in the package's source directory.
Go generate accepts one specific flag:
-run=""
TODO: This flag is unimplemented.
if non-empty, specifies a regular expression to
select directives whose command matches the expression.
if non-empty, specifies a regular expression to select
directives whose full original source text (excluding
any trailing spaces and final newline) matches the
expression.
It also accepts the standard build flags -v, -n, and -x.
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'.
`,
}
var generateRunFlag string // generate -run flag
var (
generateRunFlag string // generate -run flag
generateRunRE *regexp.Regexp // compiled expression for -run
)
func init() {
addBuildFlags(cmdGenerate)
......@@ -130,6 +135,13 @@ func init() {
}
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.
for _, pkg := range packages(args) {
for _, file := range pkg.gofiles {
......@@ -223,6 +235,11 @@ func (g *Generator) run() (ok bool) {
if !isGoGenerate(buf) {
continue
}
if generateRunFlag != "" {
if !generateRunRE.Match(bytes.TrimSpace(buf)) {
continue
}
}
words := g.split(string(buf))
if len(words) == 0 {
......
......@@ -1069,28 +1069,40 @@ fi
TEST 'go generate handles simple command'
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
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
fi
TEST 'go generate handles command alias'
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
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
fi
TEST 'go generate variable substitution'
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
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
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