github.com/fenixara/go@v0.0.0-20170127160404-96ea0918e670/src/cmd/go/get.go (about)

     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.
     4  
     5  package main
     6  
     7  import (
     8  	"fmt"
     9  	"go/build"
    10  	"os"
    11  	"path/filepath"
    12  	"regexp"
    13  	"runtime"
    14  	"strconv"
    15  	"strings"
    16  )
    17  
    18  var cmdGet = &Command{
    19  	UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
    20  	Short:     "download and install packages and dependencies",
    21  	Long: `
    22  Get downloads the packages named by the import paths, along with their
    23  dependencies. It then installs the named packages, like 'go install'.
    24  
    25  The -d flag instructs get to stop after downloading the packages; that is,
    26  it instructs get not to install the packages.
    27  
    28  The -f flag, valid only when -u is set, forces get -u not to verify that
    29  each package has been checked out from the source control repository
    30  implied by its import path. This can be useful if the source is a local fork
    31  of the original.
    32  
    33  The -fix flag instructs get to run the fix tool on the downloaded packages
    34  before resolving dependencies or building the code.
    35  
    36  The -insecure flag permits fetching from repositories and resolving
    37  custom domains using insecure schemes such as HTTP. Use with caution.
    38  
    39  The -t flag instructs get to also download the packages required to build
    40  the tests for the specified packages.
    41  
    42  The -u flag instructs get to use the network to update the named packages
    43  and their dependencies.  By default, get uses the network to check out
    44  missing packages but does not use it to look for updates to existing packages.
    45  
    46  The -v flag enables verbose progress and debug output.
    47  
    48  Get also accepts build flags to control the installation. See 'go help build'.
    49  
    50  When checking out a new package, get creates the target directory
    51  GOPATH/src/<import-path>. If the GOPATH contains multiple entries,
    52  get uses the first one. For more details see: 'go help gopath'.
    53  
    54  When checking out or updating a package, get looks for a branch or tag
    55  that matches the locally installed version of Go. The most important
    56  rule is that if the local installation is running version "go1", get
    57  searches for a branch or tag named "go1". If no such version exists it
    58  retrieves the most recent version of the package.
    59  
    60  When go get checks out or updates a Git repository,
    61  it also updates any git submodules referenced by the repository.
    62  
    63  Get never checks out or updates code stored in vendor directories.
    64  
    65  For more about specifying packages, see 'go help packages'.
    66  
    67  For more about how 'go get' finds source code to
    68  download, see 'go help importpath'.
    69  
    70  See also: go build, go install, go clean.
    71  	`,
    72  }
    73  
    74  var getD = cmdGet.Flag.Bool("d", false, "")
    75  var getF = cmdGet.Flag.Bool("f", false, "")
    76  var getT = cmdGet.Flag.Bool("t", false, "")
    77  var getU = cmdGet.Flag.Bool("u", false, "")
    78  var getFix = cmdGet.Flag.Bool("fix", false, "")
    79  var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
    80  
    81  func init() {
    82  	addBuildFlags(cmdGet)
    83  	cmdGet.Run = runGet // break init loop
    84  }
    85  
    86  func runGet(cmd *Command, args []string) {
    87  	if *getF && !*getU {
    88  		fatalf("go get: cannot use -f flag without -u")
    89  	}
    90  
    91  	// Disable any prompting for passwords by Git.
    92  	// Only has an effect for 2.3.0 or later, but avoiding
    93  	// the prompt in earlier versions is just too hard.
    94  	// If user has explicitly set GIT_TERMINAL_PROMPT=1, keep
    95  	// prompting.
    96  	// See golang.org/issue/9341 and golang.org/issue/12706.
    97  	if os.Getenv("GIT_TERMINAL_PROMPT") == "" {
    98  		os.Setenv("GIT_TERMINAL_PROMPT", "0")
    99  	}
   100  
   101  	// Disable any ssh connection pooling by Git.
   102  	// If a Git subprocess forks a child into the background to cache a new connection,
   103  	// that child keeps stdout/stderr open. After the Git subprocess exits,
   104  	// os /exec expects to be able to read from the stdout/stderr pipe
   105  	// until EOF to get all the data that the Git subprocess wrote before exiting.
   106  	// The EOF doesn't come until the child exits too, because the child
   107  	// is holding the write end of the pipe.
   108  	// This is unfortunate, but it has come up at least twice
   109  	// (see golang.org/issue/13453 and golang.org/issue/16104)
   110  	// and confuses users when it does.
   111  	// If the user has explicitly set GIT_SSH or GIT_SSH_COMMAND,
   112  	// assume they know what they are doing and don't step on it.
   113  	// But default to turning off ControlMaster.
   114  	if os.Getenv("GIT_SSH") == "" && os.Getenv("GIT_SSH_COMMAND") == "" {
   115  		os.Setenv("GIT_SSH_COMMAND", "ssh -o ControlMaster=no")
   116  	}
   117  
   118  	// Phase 1.  Download/update.
   119  	var stk importStack
   120  	mode := 0
   121  	if *getT {
   122  		mode |= getTestDeps
   123  	}
   124  	args = downloadPaths(args)
   125  	for _, arg := range args {
   126  		download(arg, nil, &stk, mode)
   127  	}
   128  	exitIfErrors()
   129  
   130  	// Phase 2. Rescan packages and re-evaluate args list.
   131  
   132  	// Code we downloaded and all code that depends on it
   133  	// needs to be evicted from the package cache so that
   134  	// the information will be recomputed. Instead of keeping
   135  	// track of the reverse dependency information, evict
   136  	// everything.
   137  	for name := range packageCache {
   138  		delete(packageCache, name)
   139  	}
   140  
   141  	// In order to rebuild packages information completely,
   142  	// we need to clear commands cache. Command packages are
   143  	// referring to evicted packages from the package cache.
   144  	// This leads to duplicated loads of the standard packages.
   145  	for name := range cmdCache {
   146  		delete(cmdCache, name)
   147  	}
   148  
   149  	args = importPaths(args)
   150  	packagesForBuild(args)
   151  
   152  	// Phase 3.  Install.
   153  	if *getD {
   154  		// Download only.
   155  		// Check delayed until now so that importPaths
   156  		// and packagesForBuild have a chance to print errors.
   157  		return
   158  	}
   159  
   160  	installPackages(args, true)
   161  }
   162  
   163  // downloadPaths prepares the list of paths to pass to download.
   164  // It expands ... patterns that can be expanded. If there is no match
   165  // for a particular pattern, downloadPaths leaves it in the result list,
   166  // in the hope that we can figure out the repository from the
   167  // initial ...-free prefix.
   168  func downloadPaths(args []string) []string {
   169  	args = importPathsNoDotExpansion(args)
   170  	var out []string
   171  	for _, a := range args {
   172  		if strings.Contains(a, "...") {
   173  			var expand []string
   174  			// Use matchPackagesInFS to avoid printing
   175  			// warnings. They will be printed by the
   176  			// eventual call to importPaths instead.
   177  			if build.IsLocalImport(a) {
   178  				expand = matchPackagesInFS(a)
   179  			} else {
   180  				expand = matchPackages(a)
   181  			}
   182  			if len(expand) > 0 {
   183  				out = append(out, expand...)
   184  				continue
   185  			}
   186  		}
   187  		out = append(out, a)
   188  	}
   189  	return out
   190  }
   191  
   192  // downloadCache records the import paths we have already
   193  // considered during the download, to avoid duplicate work when
   194  // there is more than one dependency sequence leading to
   195  // a particular package.
   196  var downloadCache = map[string]bool{}
   197  
   198  // downloadRootCache records the version control repository
   199  // root directories we have already considered during the download.
   200  // For example, all the packages in the github.com/google/codesearch repo
   201  // share the same root (the directory for that path), and we only need
   202  // to run the hg commands to consider each repository once.
   203  var downloadRootCache = map[string]bool{}
   204  
   205  // download runs the download half of the get command
   206  // for the package named by the argument.
   207  func download(arg string, parent *Package, stk *importStack, mode int) {
   208  	if mode&useVendor != 0 {
   209  		// Caller is responsible for expanding vendor paths.
   210  		panic("internal error: download mode has useVendor set")
   211  	}
   212  	load := func(path string, mode int) *Package {
   213  		if parent == nil {
   214  			return loadPackage(path, stk)
   215  		}
   216  		return loadImport(path, parent.Dir, parent, stk, nil, mode)
   217  	}
   218  
   219  	p := load(arg, mode)
   220  	if p.Error != nil && p.Error.hard {
   221  		errorf("%s", p.Error)
   222  		return
   223  	}
   224  
   225  	// loadPackage inferred the canonical ImportPath from arg.
   226  	// Use that in the following to prevent hysteresis effects
   227  	// in e.g. downloadCache and packageCache.
   228  	// This allows invocations such as:
   229  	//   mkdir -p $GOPATH/src/github.com/user
   230  	//   cd $GOPATH/src/github.com/user
   231  	//   go get ./foo
   232  	// see: golang.org/issue/9767
   233  	arg = p.ImportPath
   234  
   235  	// There's nothing to do if this is a package in the standard library.
   236  	if p.Standard {
   237  		return
   238  	}
   239  
   240  	// Only process each package once.
   241  	// (Unless we're fetching test dependencies for this package,
   242  	// in which case we want to process it again.)
   243  	if downloadCache[arg] && mode&getTestDeps == 0 {
   244  		return
   245  	}
   246  	downloadCache[arg] = true
   247  
   248  	pkgs := []*Package{p}
   249  	wildcardOkay := len(*stk) == 0
   250  	isWildcard := false
   251  
   252  	// Download if the package is missing, or update if we're using -u.
   253  	if p.Dir == "" || *getU {
   254  		// The actual download.
   255  		stk.push(arg)
   256  		err := downloadPackage(p)
   257  		if err != nil {
   258  			errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
   259  			stk.pop()
   260  			return
   261  		}
   262  		stk.pop()
   263  
   264  		args := []string{arg}
   265  		// If the argument has a wildcard in it, re-evaluate the wildcard.
   266  		// We delay this until after reloadPackage so that the old entry
   267  		// for p has been replaced in the package cache.
   268  		if wildcardOkay && strings.Contains(arg, "...") {
   269  			if build.IsLocalImport(arg) {
   270  				args = matchPackagesInFS(arg)
   271  			} else {
   272  				args = matchPackages(arg)
   273  			}
   274  			isWildcard = true
   275  		}
   276  
   277  		// Clear all relevant package cache entries before
   278  		// doing any new loads.
   279  		for _, arg := range args {
   280  			p := packageCache[arg]
   281  			if p != nil {
   282  				delete(packageCache, p.Dir)
   283  				delete(packageCache, p.ImportPath)
   284  			}
   285  		}
   286  
   287  		pkgs = pkgs[:0]
   288  		for _, arg := range args {
   289  			// Note: load calls loadPackage or loadImport,
   290  			// which push arg onto stk already.
   291  			// Do not push here too, or else stk will say arg imports arg.
   292  			p := load(arg, mode)
   293  			if p.Error != nil {
   294  				errorf("%s", p.Error)
   295  				continue
   296  			}
   297  			pkgs = append(pkgs, p)
   298  		}
   299  	}
   300  
   301  	// Process package, which might now be multiple packages
   302  	// due to wildcard expansion.
   303  	for _, p := range pkgs {
   304  		if *getFix {
   305  			run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles)))
   306  
   307  			// The imports might have changed, so reload again.
   308  			p = reloadPackage(arg, stk)
   309  			if p.Error != nil {
   310  				errorf("%s", p.Error)
   311  				return
   312  			}
   313  		}
   314  
   315  		if isWildcard {
   316  			// Report both the real package and the
   317  			// wildcard in any error message.
   318  			stk.push(p.ImportPath)
   319  		}
   320  
   321  		// Process dependencies, now that we know what they are.
   322  		imports := p.Imports
   323  		if mode&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 = stringList(imports, p.TestImports, p.XTestImports)
   328  		}
   329  		for i, path := range imports {
   330  			if path == "C" {
   331  				continue
   332  			}
   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.build.Imports.
   336  			orig := path
   337  			if i < len(p.build.Imports) {
   338  				orig = p.build.Imports[i]
   339  			}
   340  			if j, ok := findVendor(orig); ok {
   341  				stk.push(path)
   342  				err := &PackageError{
   343  					ImportStack: stk.copy(),
   344  					Err:         "must be imported as " + path[j+len("vendor/"):],
   345  				}
   346  				stk.pop()
   347  				errorf("%s", err)
   348  				continue
   349  			}
   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 = vendoredImportPath(p, path)
   356  			}
   357  			download(path, p, stk, 0)
   358  		}
   359  
   360  		if isWildcard {
   361  			stk.pop()
   362  		}
   363  	}
   364  }
   365  
   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 *Package) error {
   369  	var (
   370  		vcs            *vcsCmd
   371  		repo, rootPath string
   372  		err            error
   373  	)
   374  
   375  	security := secure
   376  	if *getInsecure {
   377  		security = insecure
   378  	}
   379  
   380  	if p.build.SrcRoot != "" {
   381  		// Directory exists. Look for checkout along path to src.
   382  		vcs, rootPath, err = vcsFromDir(p.Dir, p.build.SrcRoot)
   383  		if err != nil {
   384  			return err
   385  		}
   386  		repo = "<local>" // should be unused; make distinctive
   387  
   388  		// Double-check where it came from.
   389  		if *getU && vcs.remoteRepo != nil {
   390  			dir := filepath.Join(p.build.SrcRoot, filepath.FromSlash(rootPath))
   391  			remote, err := vcs.remoteRepo(vcs, dir)
   392  			if err != nil {
   393  				return err
   394  			}
   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
   403  						}
   404  					}
   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)
   407  					}
   408  				}
   409  			}
   410  		}
   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
   417  		}
   418  		vcs, repo, rootPath = rr.vcs, rr.repo, rr.root
   419  	}
   420  	if !vcs.isSecure(repo) && !*getInsecure {
   421  		return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
   422  	}
   423  
   424  	if p.build.SrcRoot == "" {
   425  		// Package not found. Put in first directory of $GOPATH.
   426  		list := filepath.SplitList(buildContext.GOPATH)
   427  		if len(list) == 0 {
   428  			return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'")
   429  		}
   430  		// Guard against people setting GOPATH=$GOROOT.
   431  		if list[0] == goroot {
   432  			return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'")
   433  		}
   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])
   436  		}
   437  		p.build.Root = list[0]
   438  		p.build.SrcRoot = filepath.Join(list[0], "src")
   439  		p.build.PkgRoot = filepath.Join(list[0], "pkg")
   440  	}
   441  	root := filepath.Join(p.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
   445  	}
   446  	downloadRootCache[root] = true
   447  
   448  	if buildV {
   449  		fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath)
   450  	}
   451  
   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)
   458  	}
   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)
   465  		}
   466  
   467  		_, err := os.Stat(p.build.Root)
   468  		gopathExisted := err == nil
   469  
   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
   474  		}
   475  		if buildV && !gopathExisted && p.build.Root == buildContext.GOPATH {
   476  			fmt.Fprintf(os.Stderr, "created GOPATH=%s; see 'go help gopath'\n", p.build.Root)
   477  		}
   478  
   479  		if err = vcs.create(root, repo); err != nil {
   480  			return err
   481  		}
   482  	} else {
   483  		// Metadata directory does exist; download incremental updates.
   484  		if err = vcs.download(root); err != nil {
   485  			return err
   486  		}
   487  	}
   488  
   489  	if 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
   495  	}
   496  
   497  	// Select and sync to appropriate version of the repository.
   498  	tags, err := vcs.tags(root)
   499  	if err != nil {
   500  		return err
   501  	}
   502  	vers := runtime.Version()
   503  	if i := strings.Index(vers, " "); i >= 0 {
   504  		vers = vers[:i]
   505  	}
   506  	if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil {
   507  		return err
   508  	}
   509  
   510  	return nil
   511  }
   512  
   513  // goTag matches go release tags such as go1 and go1.2.3.
   514  // The numbers involved must be small (at most 4 digits),
   515  // have no unnecessary leading zeros, and the version cannot
   516  // end in .0 - it is go1, not go1.0 or go1.0.0.
   517  var goTag = regexp.MustCompile(
   518  	`^go((0|[1-9][0-9]{0,3})\.)*([1-9][0-9]{0,3})$`,
   519  )
   520  
   521  // selectTag returns the closest matching tag for a given version.
   522  // Closest means the latest one that is not after the current release.
   523  // Version "goX" (or "goX.Y" or "goX.Y.Z") matches tags of the same form.
   524  // Version "release.rN" matches tags of the form "go.rN" (N being a floating-point number).
   525  // Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD".
   526  //
   527  // NOTE(rsc): Eventually we will need to decide on some logic here.
   528  // For now, there is only "go1".  This matches the docs in go help get.
   529  func selectTag(goVersion string, tags []string) (match string) {
   530  	for _, t := range tags {
   531  		if t == "go1" {
   532  			return "go1"
   533  		}
   534  	}
   535  	return ""
   536  
   537  	/*
   538  		if goTag.MatchString(goVersion) {
   539  			v := goVersion
   540  			for _, t := range tags {
   541  				if !goTag.MatchString(t) {
   542  					continue
   543  				}
   544  				if cmpGoVersion(match, t) < 0 && cmpGoVersion(t, v) <= 0 {
   545  					match = t
   546  				}
   547  			}
   548  		}
   549  
   550  		return match
   551  	*/
   552  }
   553  
   554  // cmpGoVersion returns -1, 0, +1 reporting whether
   555  // x < y, x == y, or x > y.
   556  func cmpGoVersion(x, y string) int {
   557  	// Malformed strings compare less than well-formed strings.
   558  	if !goTag.MatchString(x) {
   559  		return -1
   560  	}
   561  	if !goTag.MatchString(y) {
   562  		return +1
   563  	}
   564  
   565  	// Compare numbers in sequence.
   566  	xx := strings.Split(x[len("go"):], ".")
   567  	yy := strings.Split(y[len("go"):], ".")
   568  
   569  	for i := 0; i < len(xx) && i < len(yy); i++ {
   570  		// The Atoi are guaranteed to succeed
   571  		// because the versions match goTag.
   572  		xi, _ := strconv.Atoi(xx[i])
   573  		yi, _ := strconv.Atoi(yy[i])
   574  		if xi < yi {
   575  			return -1
   576  		} else if xi > yi {
   577  			return +1
   578  		}
   579  	}
   580  
   581  	if len(xx) < len(yy) {
   582  		return -1
   583  	}
   584  	if len(xx) > len(yy) {
   585  		return +1
   586  	}
   587  	return 0
   588  }