mirror of
https://github.com/golang/go
synced 2024-11-22 03:34:40 -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 (
|
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)))
|
||||||
|
|
||||||
@ -146,6 +214,7 @@ func download(arg string, stk *importStack) {
|
|||||||
download(dep.ImportPath, stk)
|
download(dep.ImportPath, stk)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// downloadPackage runs the create or download command
|
// downloadPackage runs the create or download command
|
||||||
// to make the first copy of or update a copy of the given package.
|
// to make the first copy of or update a copy of the given package.
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user