libgo: update to go1.9
[official-gcc.git] / libgo / go / cmd / go / internal / get / get.go
blob550321198d122a7e8c09c5e9cbe7732b5452c7eb
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package get implements the ``go get'' command.
6 package get
8 import (
9 "fmt"
10 "go/build"
11 "os"
12 "path/filepath"
13 "runtime"
14 "strings"
16 "cmd/go/internal/base"
17 "cmd/go/internal/cfg"
18 "cmd/go/internal/load"
19 "cmd/go/internal/str"
20 "cmd/go/internal/web"
21 "cmd/go/internal/work"
24 var CmdGet = &base.Command{
25 UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
26 Short: "download and install packages and dependencies",
27 Long: `
28 Get downloads the packages named by the import paths, along with their
29 dependencies. It then installs the named packages, like 'go install'.
31 The -d flag instructs get to stop after downloading the packages; that is,
32 it instructs get not to install the packages.
34 The -f flag, valid only when -u is set, forces get -u not to verify that
35 each package has been checked out from the source control repository
36 implied by its import path. This can be useful if the source is a local fork
37 of the original.
39 The -fix flag instructs get to run the fix tool on the downloaded packages
40 before resolving dependencies or building the code.
42 The -insecure flag permits fetching from repositories and resolving
43 custom domains using insecure schemes such as HTTP. Use with caution.
45 The -t flag instructs get to also download the packages required to build
46 the tests for the specified packages.
48 The -u flag instructs get to use the network to update the named packages
49 and their dependencies. By default, get uses the network to check out
50 missing packages but does not use it to look for updates to existing packages.
52 The -v flag enables verbose progress and debug output.
54 Get also accepts build flags to control the installation. See 'go help build'.
56 When checking out a new package, get creates the target directory
57 GOPATH/src/<import-path>. If the GOPATH contains multiple entries,
58 get uses the first one. For more details see: 'go help gopath'.
60 When checking out or updating a package, get looks for a branch or tag
61 that matches the locally installed version of Go. The most important
62 rule is that if the local installation is running version "go1", get
63 searches for a branch or tag named "go1". If no such version exists
64 it retrieves the default branch of the package.
66 When go get checks out or updates a Git repository,
67 it also updates any git submodules referenced by the repository.
69 Get never checks out or updates code stored in vendor directories.
71 For more about specifying packages, see 'go help packages'.
73 For more about how 'go get' finds source code to
74 download, see 'go help importpath'.
76 See also: go build, go install, go clean.
80 var getD = CmdGet.Flag.Bool("d", false, "")
81 var getF = CmdGet.Flag.Bool("f", false, "")
82 var getT = CmdGet.Flag.Bool("t", false, "")
83 var getU = CmdGet.Flag.Bool("u", false, "")
84 var getFix = CmdGet.Flag.Bool("fix", false, "")
85 var getInsecure = CmdGet.Flag.Bool("insecure", false, "")
87 func init() {
88 work.AddBuildFlags(CmdGet)
89 CmdGet.Run = runGet // break init loop
92 func runGet(cmd *base.Command, args []string) {
93 work.InstrumentInit()
94 work.BuildModeInit()
96 if *getF && !*getU {
97 base.Fatalf("go get: cannot use -f flag without -u")
100 // Disable any prompting for passwords by Git.
101 // Only has an effect for 2.3.0 or later, but avoiding
102 // the prompt in earlier versions is just too hard.
103 // If user has explicitly set GIT_TERMINAL_PROMPT=1, keep
104 // prompting.
105 // See golang.org/issue/9341 and golang.org/issue/12706.
106 if os.Getenv("GIT_TERMINAL_PROMPT") == "" {
107 os.Setenv("GIT_TERMINAL_PROMPT", "0")
110 // Disable any ssh connection pooling by Git.
111 // If a Git subprocess forks a child into the background to cache a new connection,
112 // that child keeps stdout/stderr open. After the Git subprocess exits,
113 // os /exec expects to be able to read from the stdout/stderr pipe
114 // until EOF to get all the data that the Git subprocess wrote before exiting.
115 // The EOF doesn't come until the child exits too, because the child
116 // is holding the write end of the pipe.
117 // This is unfortunate, but it has come up at least twice
118 // (see golang.org/issue/13453 and golang.org/issue/16104)
119 // and confuses users when it does.
120 // If the user has explicitly set GIT_SSH or GIT_SSH_COMMAND,
121 // assume they know what they are doing and don't step on it.
122 // But default to turning off ControlMaster.
123 if os.Getenv("GIT_SSH") == "" && os.Getenv("GIT_SSH_COMMAND") == "" {
124 os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no")
127 // Phase 1. Download/update.
128 var stk load.ImportStack
129 mode := 0
130 if *getT {
131 mode |= load.GetTestDeps
133 args = downloadPaths(args)
134 for _, arg := range args {
135 download(arg, nil, &stk, mode)
137 base.ExitIfErrors()
139 // Phase 2. Rescan packages and re-evaluate args list.
141 // Code we downloaded and all code that depends on it
142 // needs to be evicted from the package cache so that
143 // the information will be recomputed. Instead of keeping
144 // track of the reverse dependency information, evict
145 // everything.
146 load.ClearPackageCache()
148 // In order to rebuild packages information completely,
149 // we need to clear commands cache. Command packages are
150 // referring to evicted packages from the package cache.
151 // This leads to duplicated loads of the standard packages.
152 load.ClearCmdCache()
154 args = load.ImportPaths(args)
155 load.PackagesForBuild(args)
157 // Phase 3. Install.
158 if *getD {
159 // Download only.
160 // Check delayed until now so that importPaths
161 // and packagesForBuild have a chance to print errors.
162 return
165 work.InstallPackages(args, true)
168 // downloadPaths prepares the list of paths to pass to download.
169 // It expands ... patterns that can be expanded. If there is no match
170 // for a particular pattern, downloadPaths leaves it in the result list,
171 // in the hope that we can figure out the repository from the
172 // initial ...-free prefix.
173 func downloadPaths(args []string) []string {
174 args = load.ImportPathsNoDotExpansion(args)
175 var out []string
176 for _, a := range args {
177 if strings.Contains(a, "...") {
178 var expand []string
179 // Use matchPackagesInFS to avoid printing
180 // warnings. They will be printed by the
181 // eventual call to importPaths instead.
182 if build.IsLocalImport(a) {
183 expand = load.MatchPackagesInFS(a)
184 } else {
185 expand = load.MatchPackages(a)
187 if len(expand) > 0 {
188 out = append(out, expand...)
189 continue
192 out = append(out, a)
194 return out
197 // downloadCache records the import paths we have already
198 // considered during the download, to avoid duplicate work when
199 // there is more than one dependency sequence leading to
200 // a particular package.
201 var downloadCache = map[string]bool{}
203 // downloadRootCache records the version control repository
204 // root directories we have already considered during the download.
205 // For example, all the packages in the github.com/google/codesearch repo
206 // share the same root (the directory for that path), and we only need
207 // to run the hg commands to consider each repository once.
208 var downloadRootCache = map[string]bool{}
210 // download runs the download half of the get command
211 // for the package named by the argument.
212 func download(arg string, parent *load.Package, stk *load.ImportStack, mode int) {
213 if mode&load.UseVendor != 0 {
214 // Caller is responsible for expanding vendor paths.
215 panic("internal error: download mode has useVendor set")
217 load1 := func(path string, mode int) *load.Package {
218 if parent == nil {
219 return load.LoadPackage(path, stk)
221 return load.LoadImport(path, parent.Dir, parent, stk, nil, mode)
224 p := load1(arg, mode)
225 if p.Error != nil && p.Error.Hard {
226 base.Errorf("%s", p.Error)
227 return
230 // loadPackage inferred the canonical ImportPath from arg.
231 // Use that in the following to prevent hysteresis effects
232 // in e.g. downloadCache and packageCache.
233 // This allows invocations such as:
234 // mkdir -p $GOPATH/src/github.com/user
235 // cd $GOPATH/src/github.com/user
236 // go get ./foo
237 // see: golang.org/issue/9767
238 arg = p.ImportPath
240 // There's nothing to do if this is a package in the standard library.
241 if p.Standard {
242 return
245 // Only process each package once.
246 // (Unless we're fetching test dependencies for this package,
247 // in which case we want to process it again.)
248 if downloadCache[arg] && mode&load.GetTestDeps == 0 {
249 return
251 downloadCache[arg] = true
253 pkgs := []*load.Package{p}
254 wildcardOkay := len(*stk) == 0
255 isWildcard := false
257 // Download if the package is missing, or update if we're using -u.
258 if p.Dir == "" || *getU {
259 // The actual download.
260 stk.Push(arg)
261 err := downloadPackage(p)
262 if err != nil {
263 base.Errorf("%s", &load.PackageError{ImportStack: stk.Copy(), Err: err.Error()})
264 stk.Pop()
265 return
267 stk.Pop()
269 args := []string{arg}
270 // If the argument has a wildcard in it, re-evaluate the wildcard.
271 // We delay this until after reloadPackage so that the old entry
272 // for p has been replaced in the package cache.
273 if wildcardOkay && strings.Contains(arg, "...") {
274 if build.IsLocalImport(arg) {
275 args = load.MatchPackagesInFS(arg)
276 } else {
277 args = load.MatchPackages(arg)
279 isWildcard = true
282 // Clear all relevant package cache entries before
283 // doing any new loads.
284 load.ClearPackageCachePartial(args)
286 pkgs = pkgs[:0]
287 for _, arg := range args {
288 // Note: load calls loadPackage or loadImport,
289 // which push arg onto stk already.
290 // Do not push here too, or else stk will say arg imports arg.
291 p := load1(arg, mode)
292 if p.Error != nil {
293 base.Errorf("%s", p.Error)
294 continue
296 pkgs = append(pkgs, p)
300 // Process package, which might now be multiple packages
301 // due to wildcard expansion.
302 for _, p := range pkgs {
303 if *getFix {
304 files := base.FilterDotUnderscoreFiles(base.RelPaths(p.Internal.AllGoFiles))
305 base.Run(cfg.BuildToolexec, str.StringList(base.Tool("fix"), files))
307 // The imports might have changed, so reload again.
308 p = load.ReloadPackage(arg, stk)
309 if p.Error != nil {
310 base.Errorf("%s", p.Error)
311 return
315 if isWildcard {
316 // Report both the real package and the
317 // wildcard in any error message.
318 stk.Push(p.ImportPath)
321 // Process dependencies, now that we know what they are.
322 imports := p.Imports
323 if mode&load.GetTestDeps != 0 {
324 // Process test dependencies when -t is specified.
325 // (But don't get test dependencies for test dependencies:
326 // we always pass mode 0 to the recursive calls below.)
327 imports = str.StringList(imports, p.TestImports, p.XTestImports)
329 for i, path := range imports {
330 if path == "C" {
331 continue
333 // Fail fast on import naming full vendor path.
334 // Otherwise expand path as needed for test imports.
335 // Note that p.Imports can have additional entries beyond p.Internal.Build.Imports.
336 orig := path
337 if i < len(p.Internal.Build.Imports) {
338 orig = p.Internal.Build.Imports[i]
340 if j, ok := load.FindVendor(orig); ok {
341 stk.Push(path)
342 err := &load.PackageError{
343 ImportStack: stk.Copy(),
344 Err: "must be imported as " + path[j+len("vendor/"):],
346 stk.Pop()
347 base.Errorf("%s", err)
348 continue
350 // If this is a test import, apply vendor lookup now.
351 // We cannot pass useVendor to download, because
352 // download does caching based on the value of path,
353 // so it must be the fully qualified path already.
354 if i >= len(p.Imports) {
355 path = load.VendoredImportPath(p, path)
357 download(path, p, stk, 0)
360 if isWildcard {
361 stk.Pop()
366 // downloadPackage runs the create or download command
367 // to make the first copy of or update a copy of the given package.
368 func downloadPackage(p *load.Package) error {
369 var (
370 vcs *vcsCmd
371 repo, rootPath string
372 err error
375 security := web.Secure
376 if *getInsecure {
377 security = web.Insecure
380 if p.Internal.Build.SrcRoot != "" {
381 // Directory exists. Look for checkout along path to src.
382 vcs, rootPath, err = vcsFromDir(p.Dir, p.Internal.Build.SrcRoot)
383 if err != nil {
384 return err
386 repo = "<local>" // should be unused; make distinctive
388 // Double-check where it came from.
389 if *getU && vcs.remoteRepo != nil {
390 dir := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath))
391 remote, err := vcs.remoteRepo(vcs, dir)
392 if err != nil {
393 return err
395 repo = remote
396 if !*getF {
397 if rr, err := repoRootForImportPath(p.ImportPath, security); err == nil {
398 repo := rr.repo
399 if rr.vcs.resolveRepo != nil {
400 resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo)
401 if err == nil {
402 repo = resolved
405 if remote != repo && rr.isCustom {
406 return fmt.Errorf("%s is a custom import path for %s, but %s is checked out from %s", rr.root, repo, dir, remote)
411 } else {
412 // Analyze the import path to determine the version control system,
413 // repository, and the import path for the root of the repository.
414 rr, err := repoRootForImportPath(p.ImportPath, security)
415 if err != nil {
416 return err
418 vcs, repo, rootPath = rr.vcs, rr.repo, rr.root
420 if !vcs.isSecure(repo) && !*getInsecure {
421 return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
424 if p.Internal.Build.SrcRoot == "" {
425 // Package not found. Put in first directory of $GOPATH.
426 list := filepath.SplitList(cfg.BuildContext.GOPATH)
427 if len(list) == 0 {
428 return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
430 // Guard against people setting GOPATH=$GOROOT.
431 if filepath.Clean(list[0]) == filepath.Clean(cfg.GOROOT) {
432 return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
434 if _, err := os.Stat(filepath.Join(list[0], "src/cmd/go/alldocs.go")); err == nil {
435 return fmt.Errorf("cannot download, %s is a GOROOT, not a GOPATH. For more details see: 'go help gopath'", list[0])
437 p.Internal.Build.Root = list[0]
438 p.Internal.Build.SrcRoot = filepath.Join(list[0], "src")
439 p.Internal.Build.PkgRoot = filepath.Join(list[0], "pkg")
441 root := filepath.Join(p.Internal.Build.SrcRoot, filepath.FromSlash(rootPath))
442 // If we've considered this repository already, don't do it again.
443 if downloadRootCache[root] {
444 return nil
446 downloadRootCache[root] = true
448 if cfg.BuildV {
449 fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath)
452 // Check that this is an appropriate place for the repo to be checked out.
453 // The target directory must either not exist or have a repo checked out already.
454 meta := filepath.Join(root, "."+vcs.cmd)
455 st, err := os.Stat(meta)
456 if err == nil && !st.IsDir() {
457 return fmt.Errorf("%s exists but is not a directory", meta)
459 if err != nil {
460 // Metadata directory does not exist. Prepare to checkout new copy.
461 // Some version control tools require the target directory not to exist.
462 // We require that too, just to avoid stepping on existing work.
463 if _, err := os.Stat(root); err == nil {
464 return fmt.Errorf("%s exists but %s does not - stale checkout?", root, meta)
467 _, err := os.Stat(p.Internal.Build.Root)
468 gopathExisted := err == nil
470 // Some version control tools require the parent of the target to exist.
471 parent, _ := filepath.Split(root)
472 if err = os.MkdirAll(parent, 0777); err != nil {
473 return err
475 if cfg.BuildV && !gopathExisted && p.Internal.Build.Root == cfg.BuildContext.GOPATH {
476 fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.Internal.Build.Root)
479 if err = vcs.create(root, repo); err != nil {
480 return err
482 } else {
483 // Metadata directory does exist; download incremental updates.
484 if err = vcs.download(root); err != nil {
485 return err
489 if cfg.BuildN {
490 // Do not show tag sync in -n; it's noise more than anything,
491 // and since we're not running commands, no tag will be found.
492 // But avoid printing nothing.
493 fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd)
494 return nil
497 // Select and sync to appropriate version of the repository.
498 tags, err := vcs.tags(root)
499 if err != nil {
500 return err
502 vers := runtime.Version()
503 if i := strings.Index(vers, " "); i >= 0 {
504 vers = vers[:i]
506 if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil {
507 return err
510 return nil
513 // selectTag returns the closest matching tag for a given version.
514 // Closest means the latest one that is not after the current release.
515 // Version "goX" (or "goX.Y" or "goX.Y.Z") matches tags of the same form.
516 // Version "release.rN" matches tags of the form "go.rN" (N being a floating-point number).
517 // Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD".
519 // NOTE(rsc): Eventually we will need to decide on some logic here.
520 // For now, there is only "go1". This matches the docs in go help get.
521 func selectTag(goVersion string, tags []string) (match string) {
522 for _, t := range tags {
523 if t == "go1" {
524 return "go1"
527 return ""