1
0
mirror of https://github.com/golang/go synced 2024-11-22 02:54:39 -07:00

cmd/go: make go get new.code/... work

Fixes #2909.

R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/5796072
This commit is contained in:
Russ Cox 2012-03-12 16:35:15 -04:00
parent b70925d699
commit 4e18bfb930
3 changed files with 112 additions and 27 deletions

View File

@ -8,6 +8,7 @@ package main
import ( import (
"fmt" "fmt"
"go/build"
"os" "os"
"path/filepath" "path/filepath"
"runtime" "runtime"
@ -57,19 +58,13 @@ func init() {
func runGet(cmd *Command, args []string) { func runGet(cmd *Command, args []string) {
// Phase 1. Download/update. // Phase 1. Download/update.
args = importPaths(args)
var stk importStack var stk importStack
for _, arg := range args { for _, arg := range downloadPaths(args) {
download(arg, &stk) download(arg, &stk)
} }
exitIfErrors() exitIfErrors()
if *getD { // Phase 2. Rescan packages and reevaluate args list.
// download only
return
}
// Phase 2. Install.
// Code we downloaded and all code that depends on it // Code we downloaded and all code that depends on it
// needs to be evicted from the package cache so that // needs to be evicted from the package cache so that
@ -80,9 +75,48 @@ func runGet(cmd *Command, args []string) {
delete(packageCache, name) 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) 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 // downloadCache records the import paths we have already
// considered during the download, to avoid duplicate work when // considered during the download, to avoid duplicate work when
// there is more than one dependency sequence leading to // there is more than one dependency sequence leading to
@ -112,24 +146,58 @@ func download(arg string, stk *importStack) {
} }
downloadCache[arg] = true downloadCache[arg] = true
pkgs := []*Package{p}
wildcardOkay := len(*stk) == 0
// Download if the package is missing, or update if we're using -u. // Download if the package is missing, or update if we're using -u.
if p.Dir == "" || *getU { if p.Dir == "" || *getU {
// The actual download. // The actual download.
stk.push(p.ImportPath) stk.push(p.ImportPath)
defer stk.pop() err := downloadPackage(p)
if err := downloadPackage(p); err != nil { if err != nil {
errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()}) errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
stk.pop()
return return
} }
// Reread the package information from the updated files. args := []string{arg}
p = reloadPackage(arg, stk) // 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)
}
}
// 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)
}
}
pkgs = pkgs[:0]
for _, arg := range args {
stk.push(arg)
p := loadPackage(arg, stk)
stk.pop()
if p.Error != nil { if p.Error != nil {
errorf("%s", p.Error) errorf("%s", p.Error)
return continue
}
pkgs = append(pkgs, p)
} }
} }
// Process package, which might now be multiple packages
// due to wildcard expansion.
for _, p := range pkgs {
if *getFix { if *getFix {
run(stringList(tool("fix"), relPaths(p.gofiles))) run(stringList(tool("fix"), relPaths(p.gofiles)))
@ -145,6 +213,7 @@ func download(arg string, stk *importStack) {
for _, dep := range p.deps { for _, dep := range p.deps {
download(dep.ImportPath, stk) download(dep.ImportPath, stk)
} }
}
} }
// downloadPackage runs the create or download command // downloadPackage runs the create or download command

View File

@ -76,7 +76,6 @@ func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err erro
} }
if err != nil { if err != nil {
closeBody(res) closeBody(res)
log.Printf("http fetch failed")
return "", nil, err return "", nil, err
} }
// Note: accepting a non-200 OK here, so people can serve a // Note: accepting a non-200 OK here, so people can serve a

View File

@ -323,6 +323,23 @@ func repoRootForImportPath(importPath string) (*repoRoot, error) {
rr, err := repoRootForImportPathStatic(importPath, "") rr, err := repoRootForImportPathStatic(importPath, "")
if err == errUnknownSite { if err == errUnknownSite {
rr, err = repoRootForImportDynamic(importPath) 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 return rr, err
} }