github.com/panjjo/go@v0.0.0-20161104043856-d62b31386338/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 load := func(path string, mode int) *Package { 209 if parent == nil { 210 return loadPackage(path, stk) 211 } 212 return loadImport(path, parent.Dir, parent, stk, nil, mode) 213 } 214 215 p := load(arg, mode) 216 if p.Error != nil && p.Error.hard { 217 errorf("%s", p.Error) 218 return 219 } 220 221 // loadPackage inferred the canonical ImportPath from arg. 222 // Use that in the following to prevent hysteresis effects 223 // in e.g. downloadCache and packageCache. 224 // This allows invocations such as: 225 // mkdir -p $GOPATH/src/github.com/user 226 // cd $GOPATH/src/github.com/user 227 // go get ./foo 228 // see: golang.org/issue/9767 229 arg = p.ImportPath 230 231 // There's nothing to do if this is a package in the standard library. 232 if p.Standard { 233 return 234 } 235 236 // Only process each package once. 237 // (Unless we're fetching test dependencies for this package, 238 // in which case we want to process it again.) 239 if downloadCache[arg] && mode&getTestDeps == 0 { 240 return 241 } 242 downloadCache[arg] = true 243 244 pkgs := []*Package{p} 245 wildcardOkay := len(*stk) == 0 246 isWildcard := false 247 248 // Download if the package is missing, or update if we're using -u. 249 if p.Dir == "" || *getU { 250 // The actual download. 251 stk.push(arg) 252 err := downloadPackage(p) 253 if err != nil { 254 errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()}) 255 stk.pop() 256 return 257 } 258 stk.pop() 259 260 args := []string{arg} 261 // If the argument has a wildcard in it, re-evaluate the wildcard. 262 // We delay this until after reloadPackage so that the old entry 263 // for p has been replaced in the package cache. 264 if wildcardOkay && strings.Contains(arg, "...") { 265 if build.IsLocalImport(arg) { 266 args = matchPackagesInFS(arg) 267 } else { 268 args = matchPackages(arg) 269 } 270 isWildcard = true 271 } 272 273 // Clear all relevant package cache entries before 274 // doing any new loads. 275 for _, arg := range args { 276 p := packageCache[arg] 277 if p != nil { 278 delete(packageCache, p.Dir) 279 delete(packageCache, p.ImportPath) 280 } 281 } 282 283 pkgs = pkgs[:0] 284 for _, arg := range args { 285 // Note: load calls loadPackage or loadImport, 286 // which push arg onto stk already. 287 // Do not push here too, or else stk will say arg imports arg. 288 p := load(arg, mode) 289 if p.Error != nil { 290 errorf("%s", p.Error) 291 continue 292 } 293 pkgs = append(pkgs, p) 294 } 295 } 296 297 // Process package, which might now be multiple packages 298 // due to wildcard expansion. 299 for _, p := range pkgs { 300 if *getFix { 301 run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles))) 302 303 // The imports might have changed, so reload again. 304 p = reloadPackage(arg, stk) 305 if p.Error != nil { 306 errorf("%s", p.Error) 307 return 308 } 309 } 310 311 if isWildcard { 312 // Report both the real package and the 313 // wildcard in any error message. 314 stk.push(p.ImportPath) 315 } 316 317 // Process dependencies, now that we know what they are. 318 for _, path := range p.Imports { 319 if path == "C" { 320 continue 321 } 322 // Don't get test dependencies recursively. 323 // Imports is already vendor-expanded. 324 download(path, p, stk, 0) 325 } 326 if mode&getTestDeps != 0 { 327 // Process test dependencies when -t is specified. 328 // (Don't get test dependencies for test dependencies.) 329 // We pass useVendor here because p.load does not 330 // vendor-expand TestImports and XTestImports. 331 // The call to loadImport inside download needs to do that. 332 for _, path := range p.TestImports { 333 if path == "C" { 334 continue 335 } 336 download(path, p, stk, useVendor) 337 } 338 for _, path := range p.XTestImports { 339 if path == "C" { 340 continue 341 } 342 download(path, p, stk, useVendor) 343 } 344 } 345 346 if isWildcard { 347 stk.pop() 348 } 349 } 350 } 351 352 // downloadPackage runs the create or download command 353 // to make the first copy of or update a copy of the given package. 354 func downloadPackage(p *Package) error { 355 var ( 356 vcs *vcsCmd 357 repo, rootPath string 358 err error 359 ) 360 361 security := secure 362 if *getInsecure { 363 security = insecure 364 } 365 366 if p.build.SrcRoot != "" { 367 // Directory exists. Look for checkout along path to src. 368 vcs, rootPath, err = vcsFromDir(p.Dir, p.build.SrcRoot) 369 if err != nil { 370 return err 371 } 372 repo = "<local>" // should be unused; make distinctive 373 374 // Double-check where it came from. 375 if *getU && vcs.remoteRepo != nil { 376 dir := filepath.Join(p.build.SrcRoot, filepath.FromSlash(rootPath)) 377 remote, err := vcs.remoteRepo(vcs, dir) 378 if err != nil { 379 return err 380 } 381 repo = remote 382 if !*getF { 383 if rr, err := repoRootForImportPath(p.ImportPath, security); err == nil { 384 repo := rr.repo 385 if rr.vcs.resolveRepo != nil { 386 resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo) 387 if err == nil { 388 repo = resolved 389 } 390 } 391 if remote != repo && rr.isCustom { 392 return fmt.Errorf("%s is a custom import path for %s, but %s is checked out from %s", rr.root, repo, dir, remote) 393 } 394 } 395 } 396 } 397 } else { 398 // Analyze the import path to determine the version control system, 399 // repository, and the import path for the root of the repository. 400 rr, err := repoRootForImportPath(p.ImportPath, security) 401 if err != nil { 402 return err 403 } 404 vcs, repo, rootPath = rr.vcs, rr.repo, rr.root 405 } 406 if !vcs.isSecure(repo) && !*getInsecure { 407 return fmt.Errorf("cannot download, %v uses insecure protocol", repo) 408 } 409 410 if p.build.SrcRoot == "" { 411 // Package not found. Put in first directory of $GOPATH. 412 list := filepath.SplitList(buildContext.GOPATH) 413 if len(list) == 0 { 414 return fmt.Errorf("cannot download, $GOPATH not set. For more details see: 'go help gopath'") 415 } 416 // Guard against people setting GOPATH=$GOROOT. 417 if list[0] == goroot { 418 return fmt.Errorf("cannot download, $GOPATH must not be set to $GOROOT. For more details see: 'go help gopath'") 419 } 420 p.build.SrcRoot = filepath.Join(list[0], "src") 421 p.build.PkgRoot = filepath.Join(list[0], "pkg") 422 } 423 root := filepath.Join(p.build.SrcRoot, filepath.FromSlash(rootPath)) 424 // If we've considered this repository already, don't do it again. 425 if downloadRootCache[root] { 426 return nil 427 } 428 downloadRootCache[root] = true 429 430 if buildV { 431 fmt.Fprintf(os.Stderr, "%s (download)\n", rootPath) 432 } 433 434 // Check that this is an appropriate place for the repo to be checked out. 435 // The target directory must either not exist or have a repo checked out already. 436 meta := filepath.Join(root, "."+vcs.cmd) 437 st, err := os.Stat(meta) 438 if err == nil && !st.IsDir() { 439 return fmt.Errorf("%s exists but is not a directory", meta) 440 } 441 if err != nil { 442 // Metadata directory does not exist. Prepare to checkout new copy. 443 // Some version control tools require the target directory not to exist. 444 // We require that too, just to avoid stepping on existing work. 445 if _, err := os.Stat(root); err == nil { 446 return fmt.Errorf("%s exists but %s does not - stale checkout?", root, meta) 447 } 448 // Some version control tools require the parent of the target to exist. 449 parent, _ := filepath.Split(root) 450 if err = os.MkdirAll(parent, 0777); err != nil { 451 return err 452 } 453 if err = vcs.create(root, repo); err != nil { 454 return err 455 } 456 } else { 457 // Metadata directory does exist; download incremental updates. 458 if err = vcs.download(root); err != nil { 459 return err 460 } 461 } 462 463 if buildN { 464 // Do not show tag sync in -n; it's noise more than anything, 465 // and since we're not running commands, no tag will be found. 466 // But avoid printing nothing. 467 fmt.Fprintf(os.Stderr, "# cd %s; %s sync/update\n", root, vcs.cmd) 468 return nil 469 } 470 471 // Select and sync to appropriate version of the repository. 472 tags, err := vcs.tags(root) 473 if err != nil { 474 return err 475 } 476 vers := runtime.Version() 477 if i := strings.Index(vers, " "); i >= 0 { 478 vers = vers[:i] 479 } 480 if err := vcs.tagSync(root, selectTag(vers, tags)); err != nil { 481 return err 482 } 483 484 return nil 485 } 486 487 // goTag matches go release tags such as go1 and go1.2.3. 488 // The numbers involved must be small (at most 4 digits), 489 // have no unnecessary leading zeros, and the version cannot 490 // end in .0 - it is go1, not go1.0 or go1.0.0. 491 var goTag = regexp.MustCompile( 492 `^go((0|[1-9][0-9]{0,3})\.)*([1-9][0-9]{0,3})$`, 493 ) 494 495 // selectTag returns the closest matching tag for a given version. 496 // Closest means the latest one that is not after the current release. 497 // Version "goX" (or "goX.Y" or "goX.Y.Z") matches tags of the same form. 498 // Version "release.rN" matches tags of the form "go.rN" (N being a floating-point number). 499 // Version "weekly.YYYY-MM-DD" matches tags like "go.weekly.YYYY-MM-DD". 500 // 501 // NOTE(rsc): Eventually we will need to decide on some logic here. 502 // For now, there is only "go1". This matches the docs in go help get. 503 func selectTag(goVersion string, tags []string) (match string) { 504 for _, t := range tags { 505 if t == "go1" { 506 return "go1" 507 } 508 } 509 return "" 510 511 /* 512 if goTag.MatchString(goVersion) { 513 v := goVersion 514 for _, t := range tags { 515 if !goTag.MatchString(t) { 516 continue 517 } 518 if cmpGoVersion(match, t) < 0 && cmpGoVersion(t, v) <= 0 { 519 match = t 520 } 521 } 522 } 523 524 return match 525 */ 526 } 527 528 // cmpGoVersion returns -1, 0, +1 reporting whether 529 // x < y, x == y, or x > y. 530 func cmpGoVersion(x, y string) int { 531 // Malformed strings compare less than well-formed strings. 532 if !goTag.MatchString(x) { 533 return -1 534 } 535 if !goTag.MatchString(y) { 536 return +1 537 } 538 539 // Compare numbers in sequence. 540 xx := strings.Split(x[len("go"):], ".") 541 yy := strings.Split(y[len("go"):], ".") 542 543 for i := 0; i < len(xx) && i < len(yy); i++ { 544 // The Atoi are guaranteed to succeed 545 // because the versions match goTag. 546 xi, _ := strconv.Atoi(xx[i]) 547 yi, _ := strconv.Atoi(yy[i]) 548 if xi < yi { 549 return -1 550 } else if xi > yi { 551 return +1 552 } 553 } 554 555 if len(xx) < len(yy) { 556 return -1 557 } 558 if len(xx) > len(yy) { 559 return +1 560 } 561 return 0 562 }