go/buildutil: TagsFlag provides a flag.Value for setting build.Context.BuildTags from -tags flag.
Add -tags flag to oracle, ssadump, callgraph, gomvpkg, gorename, eg. Change-Id: I4a818501b2331c4ea589caca37a3ad9d381dc8af Reviewed-on: https://go-review.googlesource.com/9172 Reviewed-by: David Crawshaw <crawshaw@golang.org>
This commit is contained in:
parent
b1aed1a596
commit
ee9a07d373
|
@ -30,6 +30,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"text/template"
|
"text/template"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/go/callgraph"
|
"golang.org/x/tools/go/callgraph"
|
||||||
"golang.org/x/tools/go/callgraph/cha"
|
"golang.org/x/tools/go/callgraph/cha"
|
||||||
"golang.org/x/tools/go/callgraph/rta"
|
"golang.org/x/tools/go/callgraph/rta"
|
||||||
|
@ -50,6 +51,10 @@ var formatFlag = flag.String("format",
|
||||||
"{{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}}",
|
"{{.Caller}}\t--{{.Dynamic}}-{{.Line}}:{{.Column}}-->\t{{.Callee}}",
|
||||||
"A template expression specifying how to format an edge")
|
"A template expression specifying how to format an edge")
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
}
|
||||||
|
|
||||||
const Usage = `callgraph: display the the call graph of a Go program.
|
const Usage = `callgraph: display the the call graph of a Go program.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
|
@ -6,6 +6,7 @@ package main // import "golang.org/x/tools/cmd/eg"
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/build"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/printer"
|
"go/printer"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
@ -13,6 +14,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/refactor/eg"
|
"golang.org/x/tools/refactor/eg"
|
||||||
)
|
)
|
||||||
|
@ -26,6 +28,10 @@ var (
|
||||||
verboseFlag = flag.Bool("v", false, "show verbose matcher diagnostics")
|
verboseFlag = flag.Bool("v", false, "show verbose matcher diagnostics")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
}
|
||||||
|
|
||||||
const usage = `eg: an example-based refactoring tool.
|
const usage = `eg: an example-based refactoring tool.
|
||||||
|
|
||||||
Usage: eg -t template.go [-w] [-transitive] <args>...
|
Usage: eg -t template.go [-w] [-transitive] <args>...
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"go/build"
|
"go/build"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/refactor/rename"
|
"golang.org/x/tools/refactor/rename"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -22,6 +23,10 @@ var (
|
||||||
helpFlag = flag.Bool("help", false, "show usage message")
|
helpFlag = flag.Bool("help", false, "show usage message")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
}
|
||||||
|
|
||||||
const Usage = `gomvpkg: moves a package, updating import declarations
|
const Usage = `gomvpkg: moves a package, updating import declarations
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/refactor/rename"
|
"golang.org/x/tools/refactor/rename"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
flag.BoolVar(&rename.Force, "force", false, "proceed, even if conflicts were reported")
|
flag.BoolVar(&rename.Force, "force", false, "proceed, even if conflicts were reported")
|
||||||
flag.BoolVar(&rename.DryRun, "dryrun", false, "show the change, but do not apply it")
|
flag.BoolVar(&rename.DryRun, "dryrun", false, "show the change, but do not apply it")
|
||||||
flag.BoolVar(&rename.Verbose, "v", false, "print verbose information")
|
flag.BoolVar(&rename.Verbose, "v", false, "print verbose information")
|
||||||
|
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/oracle"
|
"golang.org/x/tools/oracle"
|
||||||
)
|
)
|
||||||
|
@ -38,6 +39,10 @@ var formatFlag = flag.String("format", "plain", "Output format. One of {plain,j
|
||||||
|
|
||||||
var reflectFlag = flag.Bool("reflect", false, "Analyze reflection soundly (slow).")
|
var reflectFlag = flag.Bool("reflect", false, "Analyze reflection soundly (slow).")
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
}
|
||||||
|
|
||||||
const useHelp = "Run 'oracle -help' for more information.\n"
|
const useHelp = "Run 'oracle -help' for more information.\n"
|
||||||
|
|
||||||
const helpMessage = `Go source code oracle.
|
const helpMessage = `Go source code oracle.
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
"golang.org/x/tools/go/loader"
|
"golang.org/x/tools/go/loader"
|
||||||
"golang.org/x/tools/go/ssa"
|
"golang.org/x/tools/go/ssa"
|
||||||
"golang.org/x/tools/go/ssa/interp"
|
"golang.org/x/tools/go/ssa/interp"
|
||||||
|
@ -39,7 +40,7 @@ Usage: ssadump [<flag> ...] <args> ...
|
||||||
Use -help flag to display options.
|
Use -help flag to display options.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
% ssadump -build=FP -importbin hello.go # quickly dump SSA form of a single package
|
% ssadump -build=F hello.go # dump SSA form of a single package
|
||||||
% ssadump -run -interp=T hello.go # interpret a program, with tracing
|
% ssadump -run -interp=T hello.go # interpret a program, with tracing
|
||||||
% ssadump -run -test unicode -- -test.v # interpret the unicode package's tests, verbosely
|
% ssadump -run -test unicode -- -test.v # interpret the unicode package's tests, verbosely
|
||||||
` + loader.FromArgsUsage +
|
` + loader.FromArgsUsage +
|
||||||
|
@ -53,6 +54,8 @@ if set, it runs the tests of each package.
|
||||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
|
||||||
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
|
// If $GOMAXPROCS isn't set, use the full capacity of the machine.
|
||||||
// For small machines, use at least 4 threads.
|
// For small machines, use at least 4 threads.
|
||||||
if os.Getenv("GOMAXPROCS") == "" {
|
if os.Getenv("GOMAXPROCS") == "" {
|
||||||
|
@ -76,8 +79,8 @@ func doMain() error {
|
||||||
args := flag.Args()
|
args := flag.Args()
|
||||||
|
|
||||||
conf := loader.Config{Build: &build.Default}
|
conf := loader.Config{Build: &build.Default}
|
||||||
// TODO(adonovan): make go/types choose its default Sizes from
|
|
||||||
// build.Default or a specified *build.Context.
|
// Choose types.Sizes from conf.Build.
|
||||||
var wordSize int64 = 8
|
var wordSize int64 = 8
|
||||||
switch conf.Build.GOARCH {
|
switch conf.Build.GOARCH {
|
||||||
case "386", "arm":
|
case "386", "arm":
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
package buildutil
|
||||||
|
|
||||||
|
// This logic was copied from stringsFlag from $GOROOT/src/cmd/go/build.go.
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const TagsFlagDoc = `'tag list'\ta list of build tags to consider satisfied during the build.
|
||||||
|
For more information about build tags, see the description of
|
||||||
|
build constraints in the documentation for the go/build package`
|
||||||
|
|
||||||
|
// TagsFlag is an implementation of the flag.Value interface that parses
|
||||||
|
// a flag value in the same manner as go build's -tags flag and
|
||||||
|
// populates a []string slice.
|
||||||
|
//
|
||||||
|
// See $GOROOT/src/go/build/doc.go for description of build tags.
|
||||||
|
// See $GOROOT/src/cmd/go/doc.go for description of 'go build -tags' flag.
|
||||||
|
//
|
||||||
|
// Example:
|
||||||
|
// flag.Var((*buildutil.TagsFlag)(&build.Default.BuildTags), "tags", buildutil.TagsDoc)
|
||||||
|
type TagsFlag []string
|
||||||
|
|
||||||
|
func (v *TagsFlag) Set(s string) error {
|
||||||
|
var err error
|
||||||
|
*v, err = splitQuotedFields(s)
|
||||||
|
if *v == nil {
|
||||||
|
*v = []string{}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitQuotedFields(s string) ([]string, error) {
|
||||||
|
// Split fields allowing '' or "" around elements.
|
||||||
|
// Quotes further inside the string do not count.
|
||||||
|
var f []string
|
||||||
|
for len(s) > 0 {
|
||||||
|
for len(s) > 0 && isSpaceByte(s[0]) {
|
||||||
|
s = s[1:]
|
||||||
|
}
|
||||||
|
if len(s) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Accepted quoted string. No unescaping inside.
|
||||||
|
if s[0] == '"' || s[0] == '\'' {
|
||||||
|
quote := s[0]
|
||||||
|
s = s[1:]
|
||||||
|
i := 0
|
||||||
|
for i < len(s) && s[i] != quote {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
if i >= len(s) {
|
||||||
|
return nil, fmt.Errorf("unterminated %c string", quote)
|
||||||
|
}
|
||||||
|
f = append(f, s[:i])
|
||||||
|
s = s[i+1:]
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
i := 0
|
||||||
|
for i < len(s) && !isSpaceByte(s[i]) {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
f = append(f, s[:i])
|
||||||
|
s = s[i:]
|
||||||
|
}
|
||||||
|
return f, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *TagsFlag) String() string {
|
||||||
|
return "<tagsFlag>"
|
||||||
|
}
|
||||||
|
|
||||||
|
func isSpaceByte(c byte) bool {
|
||||||
|
return c == ' ' || c == '\t' || c == '\n' || c == '\r'
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package buildutil_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"go/build"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"golang.org/x/tools/go/buildutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTags(t *testing.T) {
|
||||||
|
f := flag.NewFlagSet("TestTags", flag.PanicOnError)
|
||||||
|
var ctxt build.Context
|
||||||
|
f.Var((*buildutil.TagsFlag)(&ctxt.BuildTags), "tags", buildutil.TagsFlagDoc)
|
||||||
|
f.Parse([]string{"-tags", ` 'one'"two" 'three "four"'`, "rest"})
|
||||||
|
|
||||||
|
// BuildTags
|
||||||
|
want := []string{"one", "two", "three \"four\""}
|
||||||
|
if !reflect.DeepEqual(ctxt.BuildTags, want) {
|
||||||
|
t.Errorf("BuildTags = %q, want %q", ctxt.BuildTags, want)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args()
|
||||||
|
if want := []string{"rest"}; !reflect.DeepEqual(f.Args(), want) {
|
||||||
|
t.Errorf("f.Args() = %q, want %q", f.Args(), want)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue