mirror of
https://github.com/golang/go
synced 2024-11-18 21:44:45 -07:00
go/buildutil: add ExpandPatterns utility
This will be used by the guru command's -scope argument. + test Change-Id: I5bf38b544809e4518e2c22a73ec3349a5d2c09fc Reviewed-on: https://go-review.googlesource.com/19746 Reviewed-by: Michael Matloob <matloob@golang.org>
This commit is contained in:
parent
54fa7477e2
commit
ba766134cc
@ -123,3 +123,73 @@ func allPackages(ctxt *build.Context, root string, ch chan<- item) {
|
||||
walkDir(root)
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// ExpandPatterns returns the set of packages matched by patterns,
|
||||
// which may have the following forms:
|
||||
//
|
||||
// golang.org/x/tools/cmd/guru # a single package
|
||||
// golang.org/x/tools/... # all packages beneath dir
|
||||
// ... # the entire workspace.
|
||||
//
|
||||
// Order is significant: a pattern preceded by '-' removes matching
|
||||
// packages from the set. For example, these patterns match all encoding
|
||||
// packages except encoding/xml:
|
||||
//
|
||||
// encoding/... -encoding/xml
|
||||
//
|
||||
func ExpandPatterns(ctxt *build.Context, patterns []string) map[string]bool {
|
||||
// TODO(adonovan): support other features of 'go list':
|
||||
// - "std"/"cmd"/"all" meta-packages
|
||||
// - "..." not at the end of a pattern
|
||||
// - relative patterns using "./" or "../" prefix
|
||||
|
||||
pkgs := make(map[string]bool)
|
||||
doPkg := func(pkg string, neg bool) {
|
||||
if neg {
|
||||
delete(pkgs, pkg)
|
||||
} else {
|
||||
pkgs[pkg] = true
|
||||
}
|
||||
}
|
||||
|
||||
// Scan entire workspace if wildcards are present.
|
||||
// TODO(adonovan): opt: scan only the necessary subtrees of the workspace.
|
||||
var all []string
|
||||
for _, arg := range patterns {
|
||||
if strings.HasSuffix(arg, "...") {
|
||||
all = AllPackages(ctxt)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for _, arg := range patterns {
|
||||
if arg == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
neg := arg[0] == '-'
|
||||
if neg {
|
||||
arg = arg[1:]
|
||||
}
|
||||
|
||||
if arg == "..." {
|
||||
// ... matches all packages
|
||||
for _, pkg := range all {
|
||||
doPkg(pkg, neg)
|
||||
}
|
||||
} else if dir := strings.TrimSuffix(arg, "/..."); dir != arg {
|
||||
// dir/... matches all packages beneath dir
|
||||
for _, pkg := range all {
|
||||
if strings.HasPrefix(pkg, dir) &&
|
||||
(len(pkg) == len(dir) || pkg[len(dir)] == '/') {
|
||||
doPkg(pkg, neg)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// single package
|
||||
doPkg(arg, neg)
|
||||
}
|
||||
}
|
||||
|
||||
return pkgs
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ package buildutil_test
|
||||
|
||||
import (
|
||||
"go/build"
|
||||
"sort"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/tools/go/buildutil"
|
||||
@ -34,3 +36,41 @@ func TestAllPackages(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExpandPatterns(t *testing.T) {
|
||||
tree := make(map[string]map[string]string)
|
||||
for _, pkg := range []string{
|
||||
"encoding",
|
||||
"encoding/xml",
|
||||
"encoding/hex",
|
||||
"encoding/json",
|
||||
"fmt",
|
||||
} {
|
||||
tree[pkg] = make(map[string]string)
|
||||
}
|
||||
ctxt := buildutil.FakeContext(tree)
|
||||
|
||||
for _, test := range []struct {
|
||||
patterns string
|
||||
want string
|
||||
}{
|
||||
{"", ""},
|
||||
{"fmt", "fmt"},
|
||||
{"nosuchpkg", "nosuchpkg"},
|
||||
{"nosuchdir/...", ""},
|
||||
{"...", "encoding encoding/hex encoding/json encoding/xml fmt"},
|
||||
{"encoding/... -encoding/xml", "encoding encoding/hex encoding/json"},
|
||||
{"... -encoding/...", "fmt"},
|
||||
} {
|
||||
var pkgs []string
|
||||
for pkg := range buildutil.ExpandPatterns(ctxt, strings.Fields(test.patterns)) {
|
||||
pkgs = append(pkgs, pkg)
|
||||
}
|
||||
sort.Strings(pkgs)
|
||||
got := strings.Join(pkgs, " ")
|
||||
if got != test.want {
|
||||
t.Errorf("ExpandPatterns(%s) = %s, want %s",
|
||||
test.patterns, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user