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,
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.
......
......@@ -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.
......
......@@ -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
}
......
// 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