github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/go/pkg.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 "bytes" 9 "errors" 10 "fmt" 11 "go/build" 12 "go/scanner" 13 "go/token" 14 "os" 15 pathpkg "path" 16 "path/filepath" 17 "sort" 18 "strings" 19 "time" 20 "unicode" 21 ) 22 23 // A Package describes a single package found in a directory. 24 type Package struct { 25 // Note: These fields are part of the go command's public API. 26 // See list.go. It is okay to add fields, but not to change or 27 // remove existing ones. Keep in sync with list.go 28 Dir string `json:",omitempty"` // directory containing package sources 29 ImportPath string `json:",omitempty"` // import path of package in dir 30 Name string `json:",omitempty"` // package name 31 Doc string `json:",omitempty"` // package documentation string 32 Target string `json:",omitempty"` // install path 33 Goroot bool `json:",omitempty"` // is this package found in the Go root? 34 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 35 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 36 Root string `json:",omitempty"` // Go root or Go path dir containing this package 37 38 // Source files 39 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 40 CgoFiles []string `json:",omitempty"` // .go sources files that import "C" 41 IgnoredGoFiles []string `json:",omitempty"` // .go sources ignored due to build constraints 42 CFiles []string `json:",omitempty"` // .c source files 43 HFiles []string `json:",omitempty"` // .h source files 44 SFiles []string `json:",omitempty"` // .s source files 45 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 46 SwigFiles []string `json:",omitempty"` // .swig files 47 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 48 49 // Cgo directives 50 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler 51 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker 52 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names 53 54 // Dependency information 55 Imports []string `json:",omitempty"` // import paths used by this package 56 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 57 58 // Error information 59 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 60 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 61 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 62 63 // Test information 64 TestGoFiles []string `json:",omitempty"` // _test.go files in package 65 TestImports []string `json:",omitempty"` // imports from TestGoFiles 66 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 67 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 68 69 // Unexported fields are not part of the public API. 70 build *build.Package 71 pkgdir string // overrides build.PkgDir 72 imports []*Package 73 deps []*Package 74 gofiles []string // GoFiles+CgoFiles+TestGoFiles+XTestGoFiles files, absolute paths 75 sfiles []string 76 allgofiles []string // gofiles + IgnoredGoFiles, absolute paths 77 target string // installed file for this package (may be executable) 78 fake bool // synthesized package 79 forceBuild bool // this package must be rebuilt 80 forceLibrary bool // this package is a library (even if named "main") 81 local bool // imported via local path (./ or ../) 82 localPrefix string // interpret ./ and ../ imports relative to this prefix 83 exeName string // desired name for temporary executable 84 } 85 86 func (p *Package) copyBuild(pp *build.Package) { 87 p.build = pp 88 89 p.Dir = pp.Dir 90 p.ImportPath = pp.ImportPath 91 p.Name = pp.Name 92 p.Doc = pp.Doc 93 p.Root = pp.Root 94 // TODO? Target 95 p.Goroot = pp.Goroot 96 p.Standard = p.Goroot && p.ImportPath != "" && !strings.Contains(p.ImportPath, ".") 97 p.GoFiles = pp.GoFiles 98 p.CgoFiles = pp.CgoFiles 99 p.IgnoredGoFiles = pp.IgnoredGoFiles 100 p.CFiles = pp.CFiles 101 p.HFiles = pp.HFiles 102 p.SFiles = pp.SFiles 103 p.SysoFiles = pp.SysoFiles 104 p.SwigFiles = pp.SwigFiles 105 p.SwigCXXFiles = pp.SwigCXXFiles 106 p.CgoCFLAGS = pp.CgoCFLAGS 107 p.CgoLDFLAGS = pp.CgoLDFLAGS 108 p.CgoPkgConfig = pp.CgoPkgConfig 109 p.Imports = pp.Imports 110 p.TestGoFiles = pp.TestGoFiles 111 p.TestImports = pp.TestImports 112 p.XTestGoFiles = pp.XTestGoFiles 113 p.XTestImports = pp.XTestImports 114 } 115 116 // A PackageError describes an error loading information about a package. 117 type PackageError struct { 118 ImportStack []string // shortest path from package named on command line to this one 119 Pos string // position of error 120 Err string // the error itself 121 } 122 123 func (p *PackageError) Error() string { 124 if p.Pos != "" { 125 // Omit import stack. The full path to the file where the error 126 // is the most important thing. 127 return p.Pos + ": " + p.Err 128 } 129 if len(p.ImportStack) == 0 { 130 return p.Err 131 } 132 return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err 133 } 134 135 // An importStack is a stack of import paths. 136 type importStack []string 137 138 func (s *importStack) push(p string) { 139 *s = append(*s, p) 140 } 141 142 func (s *importStack) pop() { 143 *s = (*s)[0 : len(*s)-1] 144 } 145 146 func (s *importStack) copy() []string { 147 return append([]string{}, *s...) 148 } 149 150 // shorterThan returns true if sp is shorter than t. 151 // We use this to record the shortest import sequence 152 // that leads to a particular package. 153 func (sp *importStack) shorterThan(t []string) bool { 154 s := *sp 155 if len(s) != len(t) { 156 return len(s) < len(t) 157 } 158 // If they are the same length, settle ties using string ordering. 159 for i := range s { 160 if s[i] != t[i] { 161 return s[i] < t[i] 162 } 163 } 164 return false // they are equal 165 } 166 167 // packageCache is a lookup cache for loadPackage, 168 // so that if we look up a package multiple times 169 // we return the same pointer each time. 170 var packageCache = map[string]*Package{} 171 172 // reloadPackage is like loadPackage but makes sure 173 // not to use the package cache. 174 func reloadPackage(arg string, stk *importStack) *Package { 175 p := packageCache[arg] 176 if p != nil { 177 delete(packageCache, p.Dir) 178 delete(packageCache, p.ImportPath) 179 } 180 return loadPackage(arg, stk) 181 } 182 183 // dirToImportPath returns the pseudo-import path we use for a package 184 // outside the Go path. It begins with _/ and then contains the full path 185 // to the directory. If the package lives in c:\home\gopher\my\pkg then 186 // the pseudo-import path is _/c_/home/gopher/my/pkg. 187 // Using a pseudo-import path like this makes the ./ imports no longer 188 // a special case, so that all the code to deal with ordinary imports works 189 // automatically. 190 func dirToImportPath(dir string) string { 191 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 192 } 193 194 func makeImportValid(r rune) rune { 195 // Should match Go spec, compilers, and ../../pkg/go/parser/parser.go:/isValidImport. 196 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 197 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 198 return '_' 199 } 200 return r 201 } 202 203 // loadImport scans the directory named by path, which must be an import path, 204 // but possibly a local import path (an absolute file system path or one beginning 205 // with ./ or ../). A local relative path is interpreted relative to srcDir. 206 // It returns a *Package describing the package found in that directory. 207 func loadImport(path string, srcDir string, stk *importStack, importPos []token.Position) *Package { 208 stk.push(path) 209 defer stk.pop() 210 211 // Determine canonical identifier for this package. 212 // For a local import the identifier is the pseudo-import path 213 // we create from the full directory to the package. 214 // Otherwise it is the usual import path. 215 importPath := path 216 isLocal := build.IsLocalImport(path) 217 if isLocal { 218 importPath = dirToImportPath(filepath.Join(srcDir, path)) 219 } 220 if p := packageCache[importPath]; p != nil { 221 return reusePackage(p, stk) 222 } 223 224 p := new(Package) 225 p.local = isLocal 226 p.ImportPath = importPath 227 packageCache[importPath] = p 228 229 // Load package. 230 // Import always returns bp != nil, even if an error occurs, 231 // in order to return partial information. 232 // 233 // TODO: After Go 1, decide when to pass build.AllowBinary here. 234 // See issue 3268 for mistakes to avoid. 235 bp, err := buildContext.Import(path, srcDir, 0) 236 bp.ImportPath = importPath 237 if gobin != "" { 238 bp.BinDir = gobin 239 } 240 p.load(stk, bp, err) 241 if p.Error != nil && len(importPos) > 0 { 242 pos := importPos[0] 243 pos.Filename = shortPath(pos.Filename) 244 p.Error.Pos = pos.String() 245 } 246 247 return p 248 } 249 250 // reusePackage reuses package p to satisfy the import at the top 251 // of the import stack stk. If this use causes an import loop, 252 // reusePackage updates p's error information to record the loop. 253 func reusePackage(p *Package, stk *importStack) *Package { 254 // We use p.imports==nil to detect a package that 255 // is in the midst of its own loadPackage call 256 // (all the recursion below happens before p.imports gets set). 257 if p.imports == nil { 258 if p.Error == nil { 259 p.Error = &PackageError{ 260 ImportStack: stk.copy(), 261 Err: "import cycle not allowed", 262 } 263 } 264 p.Incomplete = true 265 } 266 if p.Error != nil && stk.shorterThan(p.Error.ImportStack) { 267 p.Error.ImportStack = stk.copy() 268 } 269 return p 270 } 271 272 // isGoTool is the list of directories for Go programs that are installed in 273 // $GOROOT/pkg/tool. 274 var isGoTool = map[string]bool{ 275 "cmd/api": true, 276 "cmd/cgo": true, 277 "cmd/fix": true, 278 "cmd/vet": true, 279 "cmd/yacc": true, 280 } 281 282 // expandScanner expands a scanner.List error into all the errors in the list. 283 // The default Error method only shows the first error. 284 func expandScanner(err error) error { 285 // Look for parser errors. 286 if err, ok := err.(scanner.ErrorList); ok { 287 // Prepare error with \n before each message. 288 // When printed in something like context: %v 289 // this will put the leading file positions each on 290 // its own line. It will also show all the errors 291 // instead of just the first, as err.Error does. 292 var buf bytes.Buffer 293 for _, e := range err { 294 e.Pos.Filename = shortPath(e.Pos.Filename) 295 buf.WriteString("\n") 296 buf.WriteString(e.Error()) 297 } 298 return errors.New(buf.String()) 299 } 300 return err 301 } 302 303 // load populates p using information from bp, err, which should 304 // be the result of calling build.Context.Import. 305 func (p *Package) load(stk *importStack, bp *build.Package, err error) *Package { 306 p.copyBuild(bp) 307 308 // The localPrefix is the path we interpret ./ imports relative to. 309 // Synthesized main packages sometimes override this. 310 p.localPrefix = dirToImportPath(p.Dir) 311 312 if err != nil { 313 p.Incomplete = true 314 err = expandScanner(err) 315 p.Error = &PackageError{ 316 ImportStack: stk.copy(), 317 Err: err.Error(), 318 } 319 return p 320 } 321 322 if p.Name == "main" { 323 _, elem := filepath.Split(p.Dir) 324 full := buildContext.GOOS + "_" + buildContext.GOARCH + "/" + elem 325 if buildContext.GOOS != toolGOOS || buildContext.GOARCH != toolGOARCH { 326 // Install cross-compiled binaries to subdirectories of bin. 327 elem = full 328 } 329 if p.build.BinDir != "" { 330 p.target = filepath.Join(p.build.BinDir, elem) 331 } 332 if p.Goroot && (isGoTool[p.ImportPath] || strings.HasPrefix(p.ImportPath, "exp/")) { 333 p.target = filepath.Join(gorootPkg, "tool", full) 334 } 335 if p.target != "" && buildContext.GOOS == "windows" { 336 p.target += ".exe" 337 } 338 } else if p.local { 339 // Local import turned into absolute path. 340 // No permanent install target. 341 p.target = "" 342 } else { 343 p.target = p.build.PkgObj 344 } 345 346 importPaths := p.Imports 347 // Packages that use cgo import runtime/cgo implicitly, 348 // except runtime/cgo itself. 349 if len(p.CgoFiles) > 0 && (!p.Standard || p.ImportPath != "runtime/cgo") { 350 importPaths = append(importPaths, "runtime/cgo") 351 } 352 // Everything depends on runtime, except runtime and unsafe. 353 if !p.Standard || (p.ImportPath != "runtime" && p.ImportPath != "unsafe") { 354 importPaths = append(importPaths, "runtime") 355 // When race detection enabled everything depends on runtime/race. 356 // Exclude runtime/cgo and cmd/cgo to avoid circular dependencies. 357 if buildRace && (!p.Standard || (p.ImportPath != "runtime/race" && p.ImportPath != "runtime/cgo" && p.ImportPath != "cmd/cgo")) { 358 importPaths = append(importPaths, "runtime/race") 359 } 360 } 361 362 // Build list of full paths to all Go files in the package, 363 // for use by commands like go fmt. 364 p.gofiles = stringList(p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles) 365 for i := range p.gofiles { 366 p.gofiles[i] = filepath.Join(p.Dir, p.gofiles[i]) 367 } 368 sort.Strings(p.gofiles) 369 370 p.sfiles = stringList(p.SFiles) 371 for i := range p.sfiles { 372 p.sfiles[i] = filepath.Join(p.Dir, p.sfiles[i]) 373 } 374 sort.Strings(p.sfiles) 375 376 p.allgofiles = stringList(p.IgnoredGoFiles) 377 for i := range p.allgofiles { 378 p.allgofiles[i] = filepath.Join(p.Dir, p.allgofiles[i]) 379 } 380 p.allgofiles = append(p.allgofiles, p.gofiles...) 381 sort.Strings(p.allgofiles) 382 383 // Check for case-insensitive collision of input files. 384 // To avoid problems on case-insensitive files, we reject any package 385 // where two different input files have equal names under a case-insensitive 386 // comparison. 387 f1, f2 := foldDup(stringList( 388 p.GoFiles, 389 p.CgoFiles, 390 p.IgnoredGoFiles, 391 p.CFiles, 392 p.HFiles, 393 p.SFiles, 394 p.SysoFiles, 395 p.SwigFiles, 396 p.SwigCXXFiles, 397 p.TestGoFiles, 398 p.XTestGoFiles, 399 )) 400 if f1 != "" { 401 p.Error = &PackageError{ 402 ImportStack: stk.copy(), 403 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 404 } 405 return p 406 } 407 408 // Build list of imported packages and full dependency list. 409 imports := make([]*Package, 0, len(p.Imports)) 410 deps := make(map[string]bool) 411 for i, path := range importPaths { 412 if path == "C" { 413 continue 414 } 415 p1 := loadImport(path, p.Dir, stk, p.build.ImportPos[path]) 416 if p1.local { 417 if !p.local && p.Error == nil { 418 p.Error = &PackageError{ 419 ImportStack: stk.copy(), 420 Err: fmt.Sprintf("local import %q in non-local package", path), 421 } 422 pos := p.build.ImportPos[path] 423 if len(pos) > 0 { 424 p.Error.Pos = pos[0].String() 425 } 426 } 427 path = p1.ImportPath 428 importPaths[i] = path 429 } 430 deps[path] = true 431 imports = append(imports, p1) 432 for _, dep := range p1.Deps { 433 deps[dep] = true 434 } 435 if p1.Incomplete { 436 p.Incomplete = true 437 } 438 } 439 p.imports = imports 440 441 p.Deps = make([]string, 0, len(deps)) 442 for dep := range deps { 443 p.Deps = append(p.Deps, dep) 444 } 445 sort.Strings(p.Deps) 446 for _, dep := range p.Deps { 447 p1 := packageCache[dep] 448 if p1 == nil { 449 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 450 } 451 p.deps = append(p.deps, p1) 452 if p1.Error != nil { 453 p.DepsErrors = append(p.DepsErrors, p1.Error) 454 } 455 } 456 457 // unsafe is a fake package. 458 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 459 p.target = "" 460 } 461 p.Target = p.target 462 463 // In the absence of errors lower in the dependency tree, 464 // check for case-insensitive collisions of import paths. 465 if len(p.DepsErrors) == 0 { 466 dep1, dep2 := foldDup(p.Deps) 467 if dep1 != "" { 468 p.Error = &PackageError{ 469 ImportStack: stk.copy(), 470 Err: fmt.Sprintf("case-insensitive import collision: %q and %q", dep1, dep2), 471 } 472 return p 473 } 474 } 475 476 return p 477 } 478 479 // usesSwig returns whether the package needs to run SWIG. 480 func (p *Package) usesSwig() bool { 481 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 482 } 483 484 // swigSoname returns the name of the shared library we create for a 485 // SWIG input file. 486 func (p *Package) swigSoname(file string) string { 487 return strings.Replace(p.ImportPath, "/", "-", -1) + "-" + strings.Replace(file, ".", "-", -1) + ".so" 488 } 489 490 // swigDir returns the name of the shared SWIG directory for a 491 // package. 492 func (p *Package) swigDir(ctxt *build.Context) string { 493 dir := p.build.PkgRoot 494 if ctxt.Compiler == "gccgo" { 495 dir = filepath.Join(dir, "gccgo_"+ctxt.GOOS+"_"+ctxt.GOARCH) 496 } else { 497 dir = filepath.Join(dir, ctxt.GOOS+"_"+ctxt.GOARCH) 498 } 499 return filepath.Join(dir, "swig") 500 } 501 502 // packageList returns the list of packages in the dag rooted at roots 503 // as visited in a depth-first post-order traversal. 504 func packageList(roots []*Package) []*Package { 505 seen := map[*Package]bool{} 506 all := []*Package{} 507 var walk func(*Package) 508 walk = func(p *Package) { 509 if seen[p] { 510 return 511 } 512 seen[p] = true 513 for _, p1 := range p.imports { 514 walk(p1) 515 } 516 all = append(all, p) 517 } 518 for _, root := range roots { 519 walk(root) 520 } 521 return all 522 } 523 524 // computeStale computes the Stale flag in the package dag that starts 525 // at the named pkgs (command-line arguments). 526 func computeStale(pkgs ...*Package) { 527 topRoot := map[string]bool{} 528 for _, p := range pkgs { 529 topRoot[p.Root] = true 530 } 531 532 for _, p := range packageList(pkgs) { 533 p.Stale = isStale(p, topRoot) 534 } 535 } 536 537 // isStale reports whether package p needs to be rebuilt. 538 func isStale(p *Package, topRoot map[string]bool) bool { 539 if p.Standard && (p.ImportPath == "unsafe" || buildContext.Compiler == "gccgo") { 540 // fake, builtin package 541 return false 542 } 543 if p.Error != nil { 544 return true 545 } 546 547 // A package without Go sources means we only found 548 // the installed .a file. Since we don't know how to rebuild 549 // it, it can't be stale, even if -a is set. This enables binary-only 550 // distributions of Go packages, although such binaries are 551 // only useful with the specific version of the toolchain that 552 // created them. 553 if len(p.gofiles) == 0 && !p.usesSwig() { 554 return false 555 } 556 557 if buildA || p.target == "" || p.Stale { 558 return true 559 } 560 561 // Package is stale if completely unbuilt. 562 var built time.Time 563 if fi, err := os.Stat(p.target); err == nil { 564 built = fi.ModTime() 565 } 566 if built.IsZero() { 567 return true 568 } 569 570 olderThan := func(file string) bool { 571 fi, err := os.Stat(file) 572 return err != nil || fi.ModTime().After(built) 573 } 574 575 // Package is stale if a dependency is, or if a dependency is newer. 576 for _, p1 := range p.deps { 577 if p1.Stale || p1.target != "" && olderThan(p1.target) { 578 return true 579 } 580 } 581 582 // As a courtesy to developers installing new versions of the compiler 583 // frequently, define that packages are stale if they are 584 // older than the compiler, and commands if they are older than 585 // the linker. This heuristic will not work if the binaries are 586 // back-dated, as some binary distributions may do, but it does handle 587 // a very common case. 588 // See issue 3036. 589 // Assume code in $GOROOT is up to date, since it may not be writeable. 590 // See issue 4106. 591 if p.Root != goroot { 592 if olderThan(buildToolchain.compiler()) { 593 return true 594 } 595 if p.build.IsCommand() && olderThan(buildToolchain.linker()) { 596 return true 597 } 598 } 599 600 // Have installed copy, probably built using current compilers, 601 // and built after its imported packages. The only reason now 602 // that we'd have to rebuild it is if the sources were newer than 603 // the package. If a package p is not in the same tree as any 604 // package named on the command-line, assume it is up-to-date 605 // no matter what the modification times on the source files indicate. 606 // This avoids rebuilding $GOROOT packages when people are 607 // working outside the Go root, and it effectively makes each tree 608 // listed in $GOPATH a separate compilation world. 609 // See issue 3149. 610 if p.Root != "" && !topRoot[p.Root] { 611 return false 612 } 613 614 srcs := stringList(p.GoFiles, p.CFiles, p.HFiles, p.SFiles, p.CgoFiles, p.SysoFiles) 615 for _, src := range srcs { 616 if olderThan(filepath.Join(p.Dir, src)) { 617 return true 618 } 619 } 620 621 for _, src := range stringList(p.SwigFiles, p.SwigCXXFiles) { 622 if olderThan(filepath.Join(p.Dir, src)) { 623 return true 624 } 625 soname := p.swigSoname(src) 626 fi, err := os.Stat(soname) 627 if err != nil { 628 return true 629 } 630 fiSrc, err := os.Stat(src) 631 if err != nil || fiSrc.ModTime().After(fi.ModTime()) { 632 return true 633 } 634 } 635 636 return false 637 } 638 639 var cwd, _ = os.Getwd() 640 641 var cmdCache = map[string]*Package{} 642 643 // loadPackage is like loadImport but is used for command-line arguments, 644 // not for paths found in import statements. In addition to ordinary import paths, 645 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 646 // in the Go command directory, as well as paths to those directories. 647 func loadPackage(arg string, stk *importStack) *Package { 648 if build.IsLocalImport(arg) { 649 dir := arg 650 if !filepath.IsAbs(dir) { 651 if abs, err := filepath.Abs(dir); err == nil { 652 // interpret relative to current directory 653 dir = abs 654 } 655 } 656 if sub, ok := hasSubdir(gorootSrc, dir); ok && strings.HasPrefix(sub, "cmd/") && !strings.Contains(sub[4:], "/") { 657 arg = sub 658 } 659 } 660 if strings.HasPrefix(arg, "cmd/") { 661 if p := cmdCache[arg]; p != nil { 662 return p 663 } 664 stk.push(arg) 665 defer stk.pop() 666 667 if strings.Contains(arg[4:], "/") { 668 p := &Package{ 669 Error: &PackageError{ 670 ImportStack: stk.copy(), 671 Err: fmt.Sprintf("invalid import path: cmd/... is reserved for Go commands"), 672 }, 673 } 674 return p 675 } 676 677 bp, err := buildContext.ImportDir(filepath.Join(gorootSrc, arg), 0) 678 bp.ImportPath = arg 679 bp.Goroot = true 680 bp.BinDir = gorootBin 681 if gobin != "" { 682 bp.BinDir = gobin 683 } 684 bp.Root = goroot 685 bp.SrcRoot = gorootSrc 686 p := new(Package) 687 cmdCache[arg] = p 688 p.load(stk, bp, err) 689 if p.Error == nil && p.Name != "main" { 690 p.Error = &PackageError{ 691 ImportStack: stk.copy(), 692 Err: fmt.Sprintf("expected package main but found package %s in %s", p.Name, p.Dir), 693 } 694 } 695 return p 696 } 697 698 // Wasn't a command; must be a package. 699 // If it is a local import path but names a standard package, 700 // we treat it as if the user specified the standard package. 701 // This lets you run go test ./ioutil in package io and be 702 // referring to io/ioutil rather than a hypothetical import of 703 // "./ioutil". 704 if build.IsLocalImport(arg) { 705 bp, _ := buildContext.ImportDir(filepath.Join(cwd, arg), build.FindOnly) 706 if bp.ImportPath != "" && bp.ImportPath != "." { 707 arg = bp.ImportPath 708 } 709 } 710 711 return loadImport(arg, cwd, stk, nil) 712 } 713 714 // packages returns the packages named by the 715 // command line arguments 'args'. If a named package 716 // cannot be loaded at all (for example, if the directory does not exist), 717 // then packages prints an error and does not include that 718 // package in the results. However, if errors occur trying 719 // to load dependencies of a named package, the named 720 // package is still returned, with p.Incomplete = true 721 // and details in p.DepsErrors. 722 func packages(args []string) []*Package { 723 var pkgs []*Package 724 for _, pkg := range packagesAndErrors(args) { 725 if pkg.Error != nil { 726 errorf("can't load package: %s", pkg.Error) 727 continue 728 } 729 pkgs = append(pkgs, pkg) 730 } 731 return pkgs 732 } 733 734 // packagesAndErrors is like 'packages' but returns a 735 // *Package for every argument, even the ones that 736 // cannot be loaded at all. 737 // The packages that fail to load will have p.Error != nil. 738 func packagesAndErrors(args []string) []*Package { 739 if len(args) > 0 && strings.HasSuffix(args[0], ".go") { 740 return []*Package{goFilesPackage(args)} 741 } 742 743 args = importPaths(args) 744 var pkgs []*Package 745 var stk importStack 746 var set = make(map[string]bool) 747 748 for _, arg := range args { 749 if !set[arg] { 750 pkgs = append(pkgs, loadPackage(arg, &stk)) 751 set[arg] = true 752 } 753 } 754 computeStale(pkgs...) 755 756 return pkgs 757 } 758 759 // packagesForBuild is like 'packages' but fails if any of 760 // the packages or their dependencies have errors 761 // (cannot be built). 762 func packagesForBuild(args []string) []*Package { 763 pkgs := packagesAndErrors(args) 764 printed := map[*PackageError]bool{} 765 for _, pkg := range pkgs { 766 if pkg.Error != nil { 767 errorf("can't load package: %s", pkg.Error) 768 } 769 for _, err := range pkg.DepsErrors { 770 // Since these are errors in dependencies, 771 // the same error might show up multiple times, 772 // once in each package that depends on it. 773 // Only print each once. 774 if !printed[err] { 775 printed[err] = true 776 errorf("%s", err) 777 } 778 } 779 } 780 exitIfErrors() 781 return pkgs 782 } 783 784 // hasSubdir reports whether dir is a subdirectory of 785 // (possibly multiple levels below) root. 786 // If so, it sets rel to the path fragment that must be 787 // appended to root to reach dir. 788 func hasSubdir(root, dir string) (rel string, ok bool) { 789 if p, err := filepath.EvalSymlinks(root); err == nil { 790 root = p 791 } 792 if p, err := filepath.EvalSymlinks(dir); err == nil { 793 dir = p 794 } 795 const sep = string(filepath.Separator) 796 root = filepath.Clean(root) 797 if !strings.HasSuffix(root, sep) { 798 root += sep 799 } 800 dir = filepath.Clean(dir) 801 if !strings.HasPrefix(dir, root) { 802 return "", false 803 } 804 return filepath.ToSlash(dir[len(root):]), true 805 }