]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: make go get new.code/... work
authorRuss Cox <rsc@golang.org>
Mon, 12 Mar 2012 20:35:15 +0000 (16:35 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 12 Mar 2012 20:35:15 +0000 (16:35 -0400)
Fixes #2909.

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

src/cmd/go/get.go
src/cmd/go/http.go
src/cmd/go/vcs.go

index aa0ab7bd753e38c4756d05ebd0d7539209c95916..b6a26f0e20a56138df51603954e3fdd801a7d65d 100644 (file)
@@ -8,6 +8,7 @@ package main
 
 import (
        "fmt"
+       "go/build"
        "os"
        "path/filepath"
        "runtime"
@@ -57,19 +58,13 @@ func init() {
 
 func runGet(cmd *Command, args []string) {
        // Phase 1.  Download/update.
-       args = importPaths(args)
        var stk importStack
-       for _, arg := range args {
+       for _, arg := range downloadPaths(args) {
                download(arg, &stk)
        }
        exitIfErrors()
 
-       if *getD {
-               // download only
-               return
-       }
-
-       // Phase 2. Install.
+       // Phase 2. Rescan packages and reevaluate args list.
 
        // Code we downloaded and all code that depends on it
        // needs to be evicted from the package cache so that
@@ -80,9 +75,48 @@ func runGet(cmd *Command, args []string) {
                delete(packageCache, name)
        }
 
+       args = importPaths(args)
+
+       // Phase 3.  Install.
+       if *getD {
+               // Download only.
+               // Check delayed until now so that importPaths
+               // has a chance to print errors.
+               return
+       }
+
        runInstall(cmd, args)
 }
 
+// downloadPath prepares the list of paths to pass to download.
+// It expands ... patterns that can be expanded.  If there is no match
+// for a particular pattern, downloadPaths leaves it in the result list,
+// in the hope that we can figure out the repository from the
+// initial ...-free prefix.
+func downloadPaths(args []string) []string {
+       args = importPathsNoDotExpansion(args)
+       var out []string
+       for _, a := range args {
+               if strings.Contains(a, "...") {
+                       var expand []string
+                       // Use matchPackagesInFS to avoid printing
+                       // warnings.  They will be printed by the 
+                       // eventual call to importPaths instead.
+                       if build.IsLocalImport(a) {
+                               expand = matchPackagesInFS(a)
+                       } else {
+                               expand = matchPackages(a)
+                       }
+                       if len(expand) > 0 {
+                               out = append(out, expand...)
+                               continue
+                       }
+               }
+               out = append(out, a)
+       }
+       return out
+}
+
 // downloadCache records the import paths we have already
 // considered during the download, to avoid duplicate work when
 // there is more than one dependency sequence leading to
@@ -112,38 +146,73 @@ func download(arg string, stk *importStack) {
        }
        downloadCache[arg] = true
 
+       pkgs := []*Package{p}
+       wildcardOkay := len(*stk) == 0
+
        // Download if the package is missing, or update if we're using -u.
        if p.Dir == "" || *getU {
                // The actual download.
                stk.push(p.ImportPath)
-               defer stk.pop()
-               if err := downloadPackage(p); err != nil {
+               err := downloadPackage(p)
+               if err != nil {
                        errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
+                       stk.pop()
                        return
                }
 
-               // Reread the package information from the updated files.
-               p = reloadPackage(arg, stk)
-               if p.Error != nil {
-                       errorf("%s", p.Error)
-                       return
+               args := []string{arg}
+               // If the argument has a wildcard in it, re-evaluate the wildcard.
+               // We delay this until after reloadPackage so that the old entry
+               // for p has been replaced in the package cache.
+               if wildcardOkay && strings.Contains(arg, "...") {
+                       if build.IsLocalImport(arg) {
+                               args = matchPackagesInFS(arg)
+                       } else {
+                               args = matchPackages(arg)
+                       }
                }
-       }
 
-       if *getFix {
-               run(stringList(tool("fix"), relPaths(p.gofiles)))
+               // Clear all relevant package cache entries before
+               // doing any new loads.
+               for _, arg := range args {
+                       p := packageCache[arg]
+                       if p != nil {
+                               delete(packageCache, p.Dir)
+                               delete(packageCache, p.ImportPath)
+                       }
+               }
 
-               // The imports might have changed, so reload again.
-               p = reloadPackage(arg, stk)
-               if p.Error != nil {
-                       errorf("%s", p.Error)
-                       return
+               pkgs = pkgs[:0]
+               for _, arg := range args {
+                       stk.push(arg)
+                       p := loadPackage(arg, stk)
+                       stk.pop()
+                       if p.Error != nil {
+                               errorf("%s", p.Error)
+                               continue
+                       }
+                       pkgs = append(pkgs, p)
                }
        }
 
-       // Process dependencies, now that we know what they are.
-       for _, dep := range p.deps {
-               download(dep.ImportPath, stk)
+       // Process package, which might now be multiple packages
+       // due to wildcard expansion.
+       for _, p := range pkgs {
+               if *getFix {
+                       run(stringList(tool("fix"), relPaths(p.gofiles)))
+
+                       // The imports might have changed, so reload again.
+                       p = reloadPackage(arg, stk)
+                       if p.Error != nil {
+                               errorf("%s", p.Error)
+                               return
+                       }
+               }
+
+               // Process dependencies, now that we know what they are.
+               for _, dep := range p.deps {
+                       download(dep.ImportPath, stk)
+               }
        }
 }
 
index 834de6cf24ce723484b1afd7a274c4b291a418cd..c1b9bb42a8f8d4cd0b9395bc3494d96cfb998aed 100644 (file)
@@ -76,7 +76,6 @@ func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err erro
        }
        if err != nil {
                closeBody(res)
-               log.Printf("http fetch failed")
                return "", nil, err
        }
        // Note: accepting a non-200 OK here, so people can serve a
index 642a89f891e708afd9f09d4a87f0515622b78f19..3634b606c30dfb518d79659e82af99b9caf220f2 100644 (file)
@@ -323,6 +323,23 @@ func repoRootForImportPath(importPath string) (*repoRoot, error) {
        rr, err := repoRootForImportPathStatic(importPath, "")
        if err == errUnknownSite {
                rr, err = repoRootForImportDynamic(importPath)
+
+               // repoRootForImportDynamic returns error detail
+               // that is irrelevant if the user didn't intend to use a
+               // dynamic import in the first place.
+               // Squelch it.
+               if err != nil {
+                       if buildV {
+                               log.Printf("import %q: %v", importPath, err)
+                       }
+                       err = fmt.Errorf("unrecognized import path %q", importPath)
+               }
+       }
+
+       if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.root, "...") {
+               // Do not allow wildcards in the repo root.
+               rr = nil
+               err = fmt.Errorf("cannot expand ... in %q", importPath)
        }
        return rr, err
 }