Commit b70925d6 authored by Russ Cox's avatar Russ Cox

cmd/go: make net/... match net too

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