mirror of
https://github.com/golang/go
synced 2024-11-24 21:10:04 -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:
parent
b70925d699
commit
4e18bfb930
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
// 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 {
|
||||
errorf("%s", p.Error)
|
||||
continue
|
||||
}
|
||||
pkgs = append(pkgs, p)
|
||||
}
|
||||
}
|
||||
|
||||
if *getFix {
|
||||
run(stringList(tool("fix"), relPaths(p.gofiles)))
|
||||
// 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
|
||||
// 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)
|
||||
// Process dependencies, now that we know what they are.
|
||||
for _, dep := range p.deps {
|
||||
download(dep.ImportPath, stk)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user