]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: make net/... match net too
authorRuss Cox <rsc@golang.org>
Mon, 12 Mar 2012 20:34:24 +0000 (16:34 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 12 Mar 2012 20:34:24 +0000 (16:34 -0400)
Otherwise there's no good way to get both, and it comes up often.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5794064

src/cmd/go/doc.go
src/cmd/go/help.go
src/cmd/go/main.go
src/cmd/go/match_test.go [new file with mode: 0644]

index 45278a6d714b8ac238c272bd08bb64bf74acb48c..eb9c38b63968bfe98207838b3bae68c9c418d20a 100644 (file)
@@ -508,9 +508,8 @@ An import path is a pattern if it includes one or more "..." wildcards,
 each of which can match any string, including the empty string and
 strings containing slashes.  Such a pattern expands to all package
 directories found in the GOPATH trees with names matching the
-patterns.  For example, encoding/... expands to all packages
-in subdirectories of the encoding tree, while net... expands to
-net and all its subdirectories.
+patterns.  As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
 
 An import path can also name a package to be downloaded from
 a remote repository.  Run 'go help remote' for details.
index 1d1dae37d19c62f769a60a6dde5aff6474c45c3b..26640d833c5489a8545374f188236bcf410c006e 100644 (file)
@@ -36,9 +36,8 @@ An import path is a pattern if it includes one or more "..." wildcards,
 each of which can match any string, including the empty string and
 strings containing slashes.  Such a pattern expands to all package
 directories found in the GOPATH trees with names matching the
-patterns.  For example, encoding/... expands to all packages
-in subdirectories of the encoding tree, while net... expands to
-net and all its subdirectories.
+patterns.  As a special case, x/... matches x as well as x's subdirectories.
+For example, net/... expands to net and packages in its subdirectories.
 
 An import path can also name a package to be downloaded from
 a remote repository.  Run 'go help remote' for details.
index 2cc23d9bd3c16be58756b27a432d85c0ead30e17..2f8209c86f4185223fd60e164822efa23719cc69 100644 (file)
@@ -247,8 +247,9 @@ func help(args []string) {
        os.Exit(2) // failed at 'go help cmd'
 }
 
-// importPaths returns the import paths to use for the given command line.
-func importPaths(args []string) []string {
+// importPathsNoDotExpansion returns the import paths to use for the given
+// command line, but it does no ... expansion.
+func importPathsNoDotExpansion(args []string) []string {
        if len(args) == 0 {
                return []string{"."}
        }
@@ -270,13 +271,26 @@ func importPaths(args []string) []string {
                } else {
                        a = path.Clean(a)
                }
-
-               if build.IsLocalImport(a) && strings.Contains(a, "...") {
-                       out = append(out, allPackagesInFS(a)...)
+               if a == "all" || a == "std" {
+                       out = append(out, allPackages(a)...)
                        continue
                }
-               if a == "all" || a == "std" || strings.Contains(a, "...") {
-                       out = append(out, allPackages(a)...)
+               out = append(out, a)
+       }
+       return out
+}
+
+// importPaths returns the import paths to use for the given command line.
+func importPaths(args []string) []string {
+       args = importPathsNoDotExpansion(args)
+       var out []string
+       for _, a := range args {
+               if strings.Contains(a, "...") {
+                       if build.IsLocalImport(a) {
+                               out = append(out, allPackagesInFS(a)...)
+                       } else {
+                               out = append(out, allPackages(a)...)
+                       }
                        continue
                }
                out = append(out, a)
@@ -345,6 +359,10 @@ func runOut(dir string, cmdargs ...interface{}) []byte {
 func matchPattern(pattern string) func(name string) bool {
        re := regexp.QuoteMeta(pattern)
        re = strings.Replace(re, `\.\.\.`, `.*`, -1)
+       // Special case: foo/... matches foo too.
+       if strings.HasSuffix(re, `/.*`) {
+               re = re[:len(re)-len(`/.*`)] + `(/.*)?`
+       }
        reg := regexp.MustCompile(`^` + re + `$`)
        return func(name string) bool {
                return reg.MatchString(name)
@@ -356,6 +374,14 @@ func matchPattern(pattern string) func(name string) bool {
 // The pattern is either "all" (all packages), "std" (standard packages)
 // or a path including "...".
 func allPackages(pattern string) []string {
+       pkgs := matchPackages(pattern)
+       if len(pkgs) == 0 {
+               fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+       }
+       return pkgs
+}
+
+func matchPackages(pattern string) []string {
        match := func(string) bool { return true }
        if pattern != "all" && pattern != "std" {
                match = matchPattern(pattern)
@@ -432,10 +458,6 @@ func allPackages(pattern string) []string {
                        return nil
                })
        }
-
-       if len(pkgs) == 0 {
-               fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
-       }
        return pkgs
 }
 
@@ -443,6 +465,14 @@ func allPackages(pattern string) []string {
 // beginning ./ or ../, meaning it should scan the tree rooted
 // at the given directory.  There are ... in the pattern too.
 func allPackagesInFS(pattern string) []string {
+       pkgs := matchPackagesInFS(pattern)
+       if len(pkgs) == 0 {
+               fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
+       }
+       return pkgs
+}
+
+func matchPackagesInFS(pattern string) []string {
        // Find directory to begin the scan.
        // Could be smarter but this one optimization
        // is enough for now, since ... is usually at the
@@ -482,10 +512,6 @@ func allPackagesInFS(pattern string) []string {
                pkgs = append(pkgs, name)
                return nil
        })
-
-       if len(pkgs) == 0 {
-               fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
-       }
        return pkgs
 }
 
diff --git a/src/cmd/go/match_test.go b/src/cmd/go/match_test.go
new file mode 100644 (file)
index 0000000..f058f23
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2012 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.
+
+package main
+
+import "testing"
+
+var matchTests = []struct {
+       pattern string
+       path    string
+       match   bool
+}{
+       {"...", "foo", true},
+       {"net", "net", true},
+       {"net", "net/http", false},
+       {"net/http", "net", false},
+       {"net/http", "net/http", true},
+       {"net...", "netchan", true},
+       {"net...", "net", true},
+       {"net...", "net/http", true},
+       {"net...", "not/http", false},
+       {"net/...", "netchan", false},
+       {"net/...", "net", true},
+       {"net/...", "net/http", true},
+       {"net/...", "not/http", false},
+}
+
+func TestMatchPattern(t *testing.T) {
+       for _, tt := range matchTests {
+               match := matchPattern(tt.pattern)(tt.path)
+               if match != tt.match {
+                       t.Errorf("matchPattern(%q)(%q) = %v, want %v", tt.pattern, tt.path, match, tt.match)
+               }
+       }
+}