github.com/gernest/nezuko@v0.1.2/internal/load/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 load loads packages. 6 package load 7 8 import ( 9 "bytes" 10 "fmt" 11 "go/token" 12 "io/ioutil" 13 "os" 14 pathpkg "path" 15 "path/filepath" 16 "sort" 17 "strconv" 18 "strings" 19 "unicode" 20 "unicode/utf8" 21 22 "github.com/gernest/nezuko/internal/build" 23 24 "github.com/gernest/nezuko/internal/base" 25 "github.com/gernest/nezuko/internal/cfg" 26 "github.com/gernest/nezuko/internal/modinfo" 27 "github.com/gernest/nezuko/internal/search" 28 "github.com/gernest/nezuko/internal/str" 29 ) 30 31 var ( 32 // module initialization hook; never nil, no-op if module use is disabled 33 ModInit func() 34 35 // module hooks; nil if module use is disabled 36 ModBinDir func() string // return effective bin directory 37 ModLookup func(path string) (dir, realPath string, err error) // lookup effective meaning of import 38 ModPackageModuleInfo func(path string) *modinfo.ModulePublic // return module info for Package struct 39 ModImportPaths func(args []string) []*search.Match // expand import paths 40 ModPackageBuildInfo func(main string, deps []string) string // return module info to embed in binary 41 ModInfoProg func(info string) []byte // wrap module info in .go code for binary 42 ModImportFromFiles func([]string) // update z.mod to add modules for imports in these files 43 ModDirImportPath func(string) string // return effective import path for directory 44 ) 45 46 var IgnoreImports bool // control whether we ignore imports in packages 47 48 // A Package describes a single package found in a directory. 49 type Package struct { 50 PackagePublic // visible in 'go list' 51 Internal PackageInternal // for use inside go command only 52 } 53 54 type PackagePublic struct { 55 // Note: These fields are part of the go command's public API. 56 // See list.go. It is okay to add fields, but not to change or 57 // remove existing ones. Keep in sync with list.go 58 Dir string `json:",omitempty"` // directory containing package sources 59 ImportPath string `json:",omitempty"` // import path of package in dir 60 ImportComment string `json:",omitempty"` // path in import comment on package statement 61 Name string `json:",omitempty"` // package name 62 Doc string `json:",omitempty"` // package documentation string 63 Target string `json:",omitempty"` // installed target for this package (may be executable) 64 Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared) 65 Root string `json:",omitempty"` // Go root or Go path dir containing this package 66 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory 67 ForTest string `json:",omitempty"` // package is only for use in named test 68 Export string `json:",omitempty"` // file containing export data (set by go list -export) 69 Module *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any 70 Match []string `json:",omitempty"` // command-line patterns matching this package 71 Goroot bool `json:",omitempty"` // is this package found in the Go root? 72 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 73 DepOnly bool `json:",omitempty"` // package is only as a dependency, not explicitly listed 74 BinaryOnly bool `json:",omitempty"` // package cannot be recompiled 75 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 76 77 // Stale and StaleReason remain here *only* for the list command. 78 // They are only initialized in preparation for list execution. 79 // The regular build determines staleness on the fly during action execution. 80 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 81 StaleReason string `json:",omitempty"` // why is Stale true? 82 83 // Source files 84 // If you add to this list you MUST add to p.AllFiles (below) too. 85 // Otherwise file name security lists will not apply to any new additions. 86 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 87 CgoFiles []string `json:",omitempty"` // .go source files that import "C" 88 CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles 89 IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints 90 CFiles []string `json:",omitempty"` // .c source files 91 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files 92 MFiles []string `json:",omitempty"` // .m source files 93 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files 94 FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files 95 SFiles []string `json:",omitempty"` // .s source files 96 SwigFiles []string `json:",omitempty"` // .swig files 97 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 98 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 99 100 // Cgo directives 101 CgoCFLAGS []string `json:",omitempty"` // cz: flags for C compiler 102 CgoCPPFLAGS []string `json:",omitempty"` // cz: flags for C preprocessor 103 CgoCXXFLAGS []string `json:",omitempty"` // cz: flags for C++ compiler 104 CgoFFLAGS []string `json:",omitempty"` // cz: flags for Fortran compiler 105 CgoLDFLAGS []string `json:",omitempty"` // cz: flags for linker 106 CgoPkgConfig []string `json:",omitempty"` // cz: pkg-config names 107 108 // Dependency information 109 Imports []string `json:",omitempty"` // import paths used by this package 110 ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted) 111 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 112 113 // Error information 114 // Incomplete is above, packed into the other bools 115 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 116 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 117 118 // Test information 119 // If you add to this list you MUST add to p.AllFiles (below) too. 120 // Otherwise file name security lists will not apply to any new additions. 121 TestGoFiles []string `json:",omitempty"` // _test.go files in package 122 TestImports []string `json:",omitempty"` // imports from TestGoFiles 123 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 124 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 125 } 126 127 // AllFiles returns the names of all the files considered for the package. 128 // This is used for sanity and security checks, so we include all files, 129 // even IgnoredGoFiles, because some subcommands consider them. 130 // The go/build package filtered others out (like foo_wrongGOARCH.s) 131 // and that's OK. 132 func (p *Package) AllFiles() []string { 133 return str.StringList( 134 p.GoFiles, 135 p.CgoFiles, 136 // no p.CompiledGoFiles, because they are from GoFiles or generated by us 137 p.IgnoredGoFiles, 138 p.CFiles, 139 p.CXXFiles, 140 p.MFiles, 141 p.HFiles, 142 p.FFiles, 143 p.SFiles, 144 p.SwigFiles, 145 p.SwigCXXFiles, 146 p.SysoFiles, 147 p.TestGoFiles, 148 p.XTestGoFiles, 149 ) 150 } 151 152 // Desc returns the package "description", for use in b.showOutput. 153 func (p *Package) Desc() string { 154 if p.ForTest != "" { 155 return p.ImportPath + " [" + p.ForTest + ".test]" 156 } 157 return p.ImportPath 158 } 159 160 type PackageInternal struct { 161 // Unexported fields are not part of the public API. 162 Build *build.Package 163 Imports []*Package // this package's direct imports 164 CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library) 165 RawImports []string // this package's original imports as they appear in the text of the program 166 ForceLibrary bool // this package is a library (even if named "main") 167 CmdlineFiles bool // package built from files listed on command line 168 CmdlinePkg bool // package listed on command line 169 CmdlinePkgLiteral bool // package listed as literal on command line (not via wildcard) 170 Local bool // imported via local path (./ or ../) 171 LocalPrefix string // interpret ./ and ../ imports relative to this prefix 172 ExeName string // desired name for temporary executable 173 CoverMode string // preprocess Go source files with the coverage tool in this mode 174 CoverVars map[string]*CoverVar // variables created by coverage analysis 175 OmitDebug bool // tell linker not to write debug information 176 GobinSubdir bool // install target would be subdir of GOBIN 177 BuildInfo string // add this info to package main 178 TestmainGo *[]byte // content for _testmain.go 179 180 Asmflags []string // -asmflags for this package 181 Gcflags []string // -gcflags for this package 182 Ldflags []string // -ldflags for this package 183 Gccgoflags []string // -gccgoflags for this package 184 } 185 186 type NoGoError struct { 187 Package *Package 188 } 189 190 func (e *NoGoError) Error() string { 191 // Count files beginning with _ and ., which we will pretend don't exist at all. 192 dummy := 0 193 for _, name := range e.Package.IgnoredGoFiles { 194 if strings.HasPrefix(name, "_") || strings.HasPrefix(name, ".") { 195 dummy++ 196 } 197 } 198 199 if len(e.Package.IgnoredGoFiles) > dummy { 200 // Go files exist, but they were ignored due to build constraints. 201 return "build constraints exclude all Go files in " + e.Package.Dir 202 } 203 if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 { 204 // Test Go files exist, but we're not interested in them. 205 // The double-negative is unfortunate but we want e.Package.Dir 206 // to appear at the end of error message. 207 return "no non-test Go files in " + e.Package.Dir 208 } 209 return "no Go files in " + e.Package.Dir 210 } 211 212 // Resolve returns the resolved version of imports, 213 // which should be p.TestImports or p.XTestImports, NOT p.Imports. 214 // The imports in p.TestImports and p.XTestImports are not recursively 215 // loaded during the initial load of p, so they list the imports found in 216 // the source file, but most processing should be over the vendor-resolved 217 // import paths. We do this resolution lazily both to avoid file system work 218 // and because the eventual real load of the test imports (during 'go test') 219 // can produce better error messages if it starts with the original paths. 220 // The initial load of p loads all the non-test imports and rewrites 221 // the vendored paths, so nothing should ever call p.vendored(p.Imports). 222 func (p *Package) Resolve(imports []string) []string { 223 if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] { 224 panic("internal error: p.Resolve(p.Imports) called") 225 } 226 seen := make(map[string]bool) 227 var all []string 228 for _, path := range imports { 229 path = ResolveImportPath(p, path) 230 if !seen[path] { 231 seen[path] = true 232 all = append(all, path) 233 } 234 } 235 sort.Strings(all) 236 return all 237 } 238 239 // CoverVar holds the name of the generated coverage variables targeting the named file. 240 type CoverVar struct { 241 File string // local file name 242 Var string // name of count struct 243 } 244 245 func (p *Package) copyBuild(pp *build.Package) { 246 p.Internal.Build = pp 247 248 p.Dir = pp.Dir 249 p.ImportPath = pp.ImportPath 250 p.ImportComment = pp.ImportComment 251 p.Name = pp.Name 252 p.Doc = pp.Doc 253 p.Root = pp.Root 254 255 p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath) 256 p.GoFiles = pp.GoFiles 257 // We modify p.Imports in place, so make copy now. 258 p.Imports = make([]string, len(pp.Imports)) 259 copy(p.Imports, pp.Imports) 260 p.Internal.RawImports = pp.Imports 261 if IgnoreImports { 262 p.Imports = nil 263 p.Internal.RawImports = nil 264 p.TestImports = nil 265 p.XTestImports = nil 266 } 267 } 268 269 // A PackageError describes an error loading information about a package. 270 type PackageError struct { 271 ImportStack []string // shortest path from package named on command line to this one 272 Pos string // position of error 273 Err string // the error itself 274 IsImportCycle bool `json:"-"` // the error is an import cycle 275 Hard bool `json:"-"` // whether the error is soft or hard; soft errors are ignored in some places 276 } 277 278 func (p *PackageError) Error() string { 279 // Import cycles deserve special treatment. 280 if p.IsImportCycle { 281 return fmt.Sprintf("%s\npackage %s\n", p.Err, strings.Join(p.ImportStack, "\n\timports ")) 282 } 283 if p.Pos != "" { 284 // Omit import stack. The full path to the file where the error 285 // is the most important thing. 286 return p.Pos + ": " + p.Err 287 } 288 if len(p.ImportStack) == 0 { 289 return p.Err 290 } 291 return "package " + strings.Join(p.ImportStack, "\n\timports ") + ": " + p.Err 292 } 293 294 // An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended. 295 // The import path of a test package is the import path of the corresponding 296 // non-test package with the suffix "_test" added. 297 type ImportStack []string 298 299 func (s *ImportStack) Push(p string) { 300 *s = append(*s, p) 301 } 302 303 func (s *ImportStack) Pop() { 304 *s = (*s)[0 : len(*s)-1] 305 } 306 307 func (s *ImportStack) Copy() []string { 308 return append([]string{}, *s...) 309 } 310 311 // shorterThan reports whether sp is shorter than t. 312 // We use this to record the shortest import sequence 313 // that leads to a particular package. 314 func (sp *ImportStack) shorterThan(t []string) bool { 315 s := *sp 316 if len(s) != len(t) { 317 return len(s) < len(t) 318 } 319 // If they are the same length, settle ties using string ordering. 320 for i := range s { 321 if s[i] != t[i] { 322 return s[i] < t[i] 323 } 324 } 325 return false // they are equal 326 } 327 328 // packageCache is a lookup cache for loadPackage, 329 // so that if we look up a package multiple times 330 // we return the same pointer each time. 331 var packageCache = map[string]*Package{} 332 333 func ClearPackageCache() { 334 for name := range packageCache { 335 delete(packageCache, name) 336 } 337 } 338 339 func ClearPackageCachePartial(args []string) { 340 for _, arg := range args { 341 p := packageCache[arg] 342 if p != nil { 343 delete(packageCache, p.Dir) 344 delete(packageCache, p.ImportPath) 345 } 346 } 347 } 348 349 // dirToImportPath returns the pseudo-import path we use for a package 350 // outside the Go path. It begins with _/ and then contains the full path 351 // to the directory. If the package lives in c:\home\gopher\my\pkg then 352 // the pseudo-import path is _/c_/home/gopher/my/pkg. 353 // Using a pseudo-import path like this makes the ./ imports no longer 354 // a special case, so that all the code to deal with ordinary imports works 355 // automatically. 356 func dirToImportPath(dir string) string { 357 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 358 } 359 360 func makeImportValid(r rune) rune { 361 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. 362 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 363 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 364 return '_' 365 } 366 return r 367 } 368 369 // Mode flags for loadImport and download (in get.go). 370 const ( 371 // ResolveImport means that loadImport should do import path expansion. 372 // That is, ResolveImport means that the import path came from 373 // a source file and has not been expanded yet to account for 374 // vendoring or possible module adjustment. 375 // Every import path should be loaded initially with ResolveImport, 376 // and then the expanded version (for example with the /vendor/ in it) 377 // gets recorded as the canonical import path. At that point, future loads 378 // of that package must not pass ResolveImport, because 379 // disallowVendor will reject direct use of paths containing /vendor/. 380 ResolveImport = 1 << iota 381 382 // ResolveModule is for download (part of "go get") and indicates 383 // that the module adjustment should be done, but not vendor adjustment. 384 ResolveModule 385 386 // GetTestDeps is for download (part of "go get") and indicates 387 // that test dependencies should be fetched too. 388 GetTestDeps 389 ) 390 391 // LoadImport scans the directory named by path, which must be an import path, 392 // but possibly a local import path (an absolute file system path or one beginning 393 // with ./ or ../). A local relative path is interpreted relative to srcDir. 394 // It returns a *Package describing the package found in that directory. 395 // LoadImport does not set tool flags and should only be used by 396 // this package, as part of a bigger load operation, and by GOPATH-based "go get". 397 // TODO(rsc): When GOPATH-based "go get" is removed, unexport this function. 398 func LoadImport(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { 399 if path == "" { 400 panic("LoadImport called with empty package path") 401 } 402 403 stk.Push(path) 404 defer stk.Pop() 405 406 if strings.HasPrefix(path, "mod/") { 407 // Paths beginning with "mod/" might accidentally 408 // look in the module cache directory tree in $GOPATH/pkg/mod/. 409 // This prefix is owned by the Go core for possible use in the 410 // standard library (since it does not begin with a domain name), 411 // so it's OK to disallow entirely. 412 return &Package{ 413 PackagePublic: PackagePublic{ 414 ImportPath: path, 415 Error: &PackageError{ 416 ImportStack: stk.Copy(), 417 Err: fmt.Sprintf("disallowed import path %q", path), 418 }, 419 }, 420 } 421 } 422 423 if strings.Contains(path, "@") { 424 var text string 425 if cfg.ModulesEnabled { 426 text = "can only use path@version syntax with 'go get'" 427 } else { 428 text = "cannot use path@version syntax in GOPATH mode" 429 } 430 return &Package{ 431 PackagePublic: PackagePublic{ 432 ImportPath: path, 433 Error: &PackageError{ 434 ImportStack: stk.Copy(), 435 Err: text, 436 }, 437 }, 438 } 439 } 440 441 parentPath := "" 442 if parent != nil { 443 parentPath = parent.ImportPath 444 } 445 446 // Determine canonical identifier for this package. 447 // For a local import the identifier is the pseudo-import path 448 // we create from the full directory to the package. 449 // Otherwise it is the usual import path. 450 // For vendored imports, it is the expanded form. 451 importPath := path 452 origPath := path 453 isLocal := build.IsLocalImport(path) 454 var modDir string 455 var modErr error 456 if isLocal { 457 importPath = dirToImportPath(filepath.Join(srcDir, path)) 458 } else if cfg.ModulesEnabled { 459 var p string 460 modDir, p, modErr = ModLookup(path) 461 if modErr == nil { 462 importPath = p 463 } 464 } else if mode&ResolveImport != 0 { 465 // We do our own path resolution, because we want to 466 // find out the key to use in packageCache without the 467 // overhead of repeated calls to buildContext.Import. 468 // The code is also needed in a few other places anyway. 469 path = ResolveImportPath(parent, path) 470 importPath = path 471 } else if mode&ResolveModule != 0 { 472 path = ModuleImportPath(parent, path) 473 importPath = path 474 } 475 476 p := packageCache[importPath] 477 if p != nil { 478 p = reusePackage(p, stk) 479 } else { 480 p = new(Package) 481 p.Internal.Local = isLocal 482 p.ImportPath = importPath 483 packageCache[importPath] = p 484 485 // Load package. 486 // Import always returns bp != nil, even if an error occurs, 487 // in order to return partial information. 488 var bp *build.Package 489 var err error 490 if modDir != "" { 491 bp, err = cfg.BuildContext.ImportDir(modDir, 0) 492 } else if modErr != nil { 493 bp = new(build.Package) 494 err = fmt.Errorf("unknown import path %q: %v", importPath, modErr) 495 } else if cfg.ModulesEnabled && path != "unsafe" { 496 bp = new(build.Package) 497 err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", importPath) 498 } else { 499 buildMode := build.ImportComment 500 if mode&ResolveImport == 0 || path != origPath { 501 // Not vendoring, or we already found the vendored path. 502 buildMode |= build.IgnoreVendor 503 } 504 bp, err = cfg.BuildContext.Import(path, srcDir, buildMode) 505 } 506 bp.ImportPath = importPath 507 if modDir == "" && err == nil && !isLocal && bp.ImportComment != "" && bp.ImportComment != path && 508 !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") { 509 err = fmt.Errorf("code in directory %s expects import %q", bp.Dir, bp.ImportComment) 510 } 511 p.load(stk, bp, err) 512 if p.Error != nil && p.Error.Pos == "" { 513 p = setErrorPos(p, importPos) 514 } 515 516 if modDir == "" && origPath != cleanImport(origPath) { 517 p.Error = &PackageError{ 518 ImportStack: stk.Copy(), 519 Err: fmt.Sprintf("non-canonical import path: %q should be %q", origPath, pathpkg.Clean(origPath)), 520 } 521 p.Incomplete = true 522 } 523 } 524 525 // Checked on every import because the rules depend on the code doing the importing. 526 if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p { 527 return setErrorPos(perr, importPos) 528 } 529 if mode&ResolveImport != 0 { 530 if perr := disallowVendor(srcDir, parent, parentPath, origPath, p, stk); perr != p { 531 return setErrorPos(perr, importPos) 532 } 533 } 534 535 if p.Name == "main" && parent != nil && parent.Dir != p.Dir { 536 perr := *p 537 perr.Error = &PackageError{ 538 ImportStack: stk.Copy(), 539 Err: fmt.Sprintf("import %q is a program, not an importable package", path), 540 } 541 return setErrorPos(&perr, importPos) 542 } 543 544 if p.Internal.Local && parent != nil && !parent.Internal.Local { 545 perr := *p 546 perr.Error = &PackageError{ 547 ImportStack: stk.Copy(), 548 Err: fmt.Sprintf("local import %q in non-local package", path), 549 } 550 return setErrorPos(&perr, importPos) 551 } 552 553 return p 554 } 555 556 func setErrorPos(p *Package, importPos []token.Position) *Package { 557 if len(importPos) > 0 { 558 pos := importPos[0] 559 pos.Filename = base.ShortPath(pos.Filename) 560 p.Error.Pos = pos.String() 561 } 562 return p 563 } 564 565 func cleanImport(path string) string { 566 orig := path 567 path = pathpkg.Clean(path) 568 if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") { 569 path = "./" + path 570 } 571 return path 572 } 573 574 var isDirCache = map[string]bool{} 575 576 func isDir(path string) bool { 577 result, ok := isDirCache[path] 578 if ok { 579 return result 580 } 581 582 fi, err := os.Stat(path) 583 result = err == nil && fi.IsDir() 584 isDirCache[path] = result 585 return result 586 } 587 588 // ResolveImportPath returns the true meaning of path when it appears in parent. 589 // There are two different resolutions applied. 590 // First, there is Go 1.5 vendoring (golang.org/s/go15vendor). 591 // If vendor expansion doesn't trigger, then the path is also subject to 592 // Go 1.11 module legacy conversion (golang.org/issue/25069). 593 func ResolveImportPath(parent *Package, path string) (found string) { 594 if cfg.ModulesEnabled { 595 if _, p, e := ModLookup(path); e == nil { 596 return p 597 } 598 return path 599 } 600 found = VendoredImportPath(parent, path) 601 if found != path { 602 return found 603 } 604 return ModuleImportPath(parent, path) 605 } 606 607 // dirAndRoot returns the source directory and workspace root 608 // for the package p, guaranteeing that root is a path prefix of dir. 609 func dirAndRoot(p *Package) (dir, root string) { 610 dir = filepath.Clean(p.Dir) 611 root = filepath.Join(p.Root, "src") 612 if !str.HasFilePathPrefix(dir, root) || p.ImportPath != "command-line-arguments" && filepath.Join(root, p.ImportPath) != dir { 613 // Look for symlinks before reporting error. 614 dir = expandPath(dir) 615 root = expandPath(root) 616 } 617 618 if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || p.ImportPath != "command-line-arguments" && !p.Internal.Local && filepath.Join(root, p.ImportPath) != dir { 619 base.Fatalf("unexpected directory layout:\n"+ 620 " import path: %s\n"+ 621 " root: %s\n"+ 622 " dir: %s\n"+ 623 " expand root: %s\n"+ 624 " expand dir: %s\n"+ 625 " separator: %s", 626 p.ImportPath, 627 filepath.Join(p.Root, "src"), 628 filepath.Clean(p.Dir), 629 root, 630 dir, 631 string(filepath.Separator)) 632 } 633 634 return dir, root 635 } 636 637 // VendoredImportPath returns the vendor-expansion of path when it appears in parent. 638 // If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path, 639 // x/vendor/path, vendor/path, or else stay path if none of those exist. 640 // VendoredImportPath returns the expanded path or, if no expansion is found, the original. 641 func VendoredImportPath(parent *Package, path string) (found string) { 642 if parent == nil || parent.Root == "" { 643 return path 644 } 645 646 dir, root := dirAndRoot(parent) 647 648 vpath := "vendor/" + path 649 for i := len(dir); i >= len(root); i-- { 650 if i < len(dir) && dir[i] != filepath.Separator { 651 continue 652 } 653 // Note: checking for the vendor directory before checking 654 // for the vendor/path directory helps us hit the 655 // isDir cache more often. It also helps us prepare a more useful 656 // list of places we looked, to report when an import is not found. 657 if !isDir(filepath.Join(dir[:i], "vendor")) { 658 continue 659 } 660 targ := filepath.Join(dir[:i], vpath) 661 if isDir(targ) && hasGoFiles(targ) { 662 importPath := parent.ImportPath 663 if importPath == "command-line-arguments" { 664 // If parent.ImportPath is 'command-line-arguments'. 665 // set to relative directory to root (also chopped root directory) 666 importPath = dir[len(root)+1:] 667 } 668 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy. 669 // We know the import path for parent's dir. 670 // We chopped off some number of path elements and 671 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path. 672 // Now we want to know the import path for that directory. 673 // Construct it by chopping the same number of path elements 674 // (actually the same number of bytes) from parent's import path 675 // and then append /vendor/path. 676 chopped := len(dir) - i 677 if chopped == len(importPath)+1 { 678 // We walked up from c:\gopath\src\foo\bar 679 // and found c:\gopath\src\vendor\path. 680 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7). 681 // Use "vendor/path" without any prefix. 682 return vpath 683 } 684 return importPath[:len(importPath)-chopped] + "/" + vpath 685 } 686 } 687 return path 688 } 689 690 var ( 691 modulePrefix = []byte("\nmodule ") 692 goModPathCache = make(map[string]string) 693 ) 694 695 // goModPath returns the module path in the z.mod in dir, if any. 696 func goModPath(dir string) (path string) { 697 path, ok := goModPathCache[dir] 698 if ok { 699 return path 700 } 701 defer func() { 702 goModPathCache[dir] = path 703 }() 704 705 data, err := ioutil.ReadFile(filepath.Join(dir, "z.mod")) 706 if err != nil { 707 return "" 708 } 709 var i int 710 if bytes.HasPrefix(data, modulePrefix[1:]) { 711 i = 0 712 } else { 713 i = bytes.Index(data, modulePrefix) 714 if i < 0 { 715 return "" 716 } 717 i++ 718 } 719 line := data[i:] 720 721 // Cut line at \n, drop trailing \r if present. 722 if j := bytes.IndexByte(line, '\n'); j >= 0 { 723 line = line[:j] 724 } 725 if line[len(line)-1] == '\r' { 726 line = line[:len(line)-1] 727 } 728 line = line[len("module "):] 729 730 // If quoted, unquote. 731 path = strings.TrimSpace(string(line)) 732 if path != "" && path[0] == '"' { 733 s, err := strconv.Unquote(path) 734 if err != nil { 735 return "" 736 } 737 path = s 738 } 739 return path 740 } 741 742 // findVersionElement returns the slice indices of the final version element /vN in path. 743 // If there is no such element, it returns -1, -1. 744 func findVersionElement(path string) (i, j int) { 745 j = len(path) 746 for i = len(path) - 1; i >= 0; i-- { 747 if path[i] == '/' { 748 if isVersionElement(path[i:j]) { 749 return i, j 750 } 751 j = i 752 } 753 } 754 return -1, -1 755 } 756 757 // isVersionElement reports whether s is a well-formed path version element: 758 // v2, v3, v10, etc, but not v0, v05, v1. 759 func isVersionElement(s string) bool { 760 if len(s) < 3 || s[0] != '/' || s[1] != 'v' || s[2] == '0' || s[2] == '1' && len(s) == 3 { 761 return false 762 } 763 for i := 2; i < len(s); i++ { 764 if s[i] < '0' || '9' < s[i] { 765 return false 766 } 767 } 768 return true 769 } 770 771 // ModuleImportPath translates import paths found in z modules 772 // back down to paths that can be resolved in ordinary builds. 773 // 774 // Define “new” code as code with a z.mod file in the same directory 775 // or a parent directory. If an import in new code says x/y/v2/z but 776 // x/y/v2/z does not exist and x/y/z.mod says “module x/y/v2”, 777 // then go build will read the import as x/y/z instead. 778 // See golang.org/issue/25069. 779 func ModuleImportPath(parent *Package, path string) (found string) { 780 if parent == nil || parent.Root == "" { 781 return path 782 } 783 784 // If there are no vN elements in path, leave it alone. 785 // (The code below would do the same, but only after 786 // some other file system accesses that we can avoid 787 // here by returning early.) 788 if i, _ := findVersionElement(path); i < 0 { 789 return path 790 } 791 792 dir, root := dirAndRoot(parent) 793 794 // Consider dir and parents, up to and including root. 795 for i := len(dir); i >= len(root); i-- { 796 if i < len(dir) && dir[i] != filepath.Separator { 797 continue 798 } 799 if goModPath(dir[:i]) != "" { 800 goto HaveGoMod 801 } 802 } 803 // This code is not in a tree with a z.mod, 804 // so apply no changes to the path. 805 return path 806 807 HaveGoMod: 808 // This import is in a tree with a z.mod. 809 // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z 810 // if GOPATH/src/x/y/z.mod says module "x/y/v2", 811 812 // If x/y/v2/z exists, use it unmodified. 813 if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" { 814 return path 815 } 816 817 // Otherwise look for a z.mod supplying a version element. 818 // Some version-like elements may appear in paths but not 819 // be module versions; we skip over those to look for module 820 // versions. For example the module m/v2 might have a 821 // package m/v2/api/v1/foo. 822 limit := len(path) 823 for limit > 0 { 824 i, j := findVersionElement(path[:limit]) 825 if i < 0 { 826 return path 827 } 828 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" { 829 if mpath := goModPath(bp.Dir); mpath != "" { 830 // Found a valid z.mod file, so we're stopping the search. 831 // If the path is m/v2/p and we found m/z.mod that says 832 // "module m/v2", then we return "m/p". 833 if mpath == path[:j] { 834 return path[:i] + path[j:] 835 } 836 // Otherwise just return the original path. 837 // We didn't find anything worth rewriting, 838 // and the z.mod indicates that we should 839 // not consider parent directories. 840 return path 841 } 842 } 843 limit = i 844 } 845 return path 846 } 847 848 // hasGoFiles reports whether dir contains any files with names ending in .go. 849 // For a vendor check we must exclude directories that contain no .go files. 850 // Otherwise it is not possible to vendor just a/b/c and still import the 851 // non-vendored a/b. See golang.org/issue/13832. 852 func hasGoFiles(dir string) bool { 853 fis, _ := ioutil.ReadDir(dir) 854 for _, fi := range fis { 855 if !fi.IsDir() && strings.HasSuffix(fi.Name(), ".go") { 856 return true 857 } 858 } 859 return false 860 } 861 862 // reusePackage reuses package p to satisfy the import at the top 863 // of the import stack stk. If this use causes an import loop, 864 // reusePackage updates p's error information to record the loop. 865 func reusePackage(p *Package, stk *ImportStack) *Package { 866 // We use p.Internal.Imports==nil to detect a package that 867 // is in the midst of its own loadPackage call 868 // (all the recursion below happens before p.Internal.Imports gets set). 869 if p.Internal.Imports == nil { 870 if p.Error == nil { 871 p.Error = &PackageError{ 872 ImportStack: stk.Copy(), 873 Err: "import cycle not allowed", 874 IsImportCycle: true, 875 } 876 } 877 p.Incomplete = true 878 } 879 // Don't rewrite the import stack in the error if we have an import cycle. 880 // If we do, we'll lose the path that describes the cycle. 881 if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) { 882 p.Error.ImportStack = stk.Copy() 883 } 884 return p 885 } 886 887 // disallowInternal checks that srcDir (containing package importerPath, if non-empty) 888 // is allowed to import p. 889 // If the import is allowed, disallowInternal returns the original package p. 890 // If not, it returns a new package containing just an appropriate error. 891 func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package { 892 // golang.org/s/go14internal: 893 // An import of a path containing the element “internal” 894 // is disallowed if the importing code is outside the tree 895 // rooted at the parent of the “internal” directory. 896 897 // There was an error loading the package; stop here. 898 if p.Error != nil { 899 return p 900 } 901 902 // The generated 'testmain' package is allowed to access testing/internal/..., 903 // as if it were generated into the testing directory tree 904 // (it's actually in a temporary directory outside any Go tree). 905 // This cleans up a former kludge in passing functionality to the testing package. 906 if strings.HasPrefix(p.ImportPath, "testing/internal") && len(*stk) >= 2 && (*stk)[len(*stk)-2] == "testmain" { 907 return p 908 } 909 910 // The stack includes p.ImportPath. 911 // If that's the only thing on the stack, we started 912 // with a name given on the command line, not an 913 // import. Anything listed on the command line is fine. 914 if len(*stk) == 1 { 915 return p 916 } 917 918 // Check for "internal" element: three cases depending on begin of string and/or end of string. 919 i, ok := findInternal(p.ImportPath) 920 if !ok { 921 return p 922 } 923 924 // Internal is present. 925 // Map import path back to directory corresponding to parent of internal. 926 if i > 0 { 927 i-- // rewind over slash in ".../internal" 928 } 929 930 if p.Module == nil { 931 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 932 933 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 934 return p 935 } 936 937 // Look for symlinks before reporting error. 938 srcDir = expandPath(srcDir) 939 parent = expandPath(parent) 940 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 941 return p 942 } 943 } else { 944 // p is in a module, so make it available based on the importer's import path instead 945 // of the file path (https://golang.org/issue/23970). 946 if importer.Internal.CmdlineFiles { 947 // The importer is a list of command-line files. 948 // Pretend that the import path is the import path of the 949 // directory containing them. 950 // If the directory is outside the main module, this will resolve to ".", 951 // which is not a prefix of any valid module. 952 importerPath = ModDirImportPath(importer.Dir) 953 } 954 parentOfInternal := p.ImportPath[:i] 955 if str.HasPathPrefix(importerPath, parentOfInternal) { 956 return p 957 } 958 } 959 960 // Internal is present, and srcDir is outside parent's tree. Not allowed. 961 perr := *p 962 perr.Error = &PackageError{ 963 ImportStack: stk.Copy(), 964 Err: "use of internal package " + p.ImportPath + " not allowed", 965 } 966 perr.Incomplete = true 967 return &perr 968 } 969 970 // findInternal looks for the final "internal" path element in the given import path. 971 // If there isn't one, findInternal returns ok=false. 972 // Otherwise, findInternal returns ok=true and the index of the "internal". 973 func findInternal(path string) (index int, ok bool) { 974 // Three cases, depending on internal at start/end of string or not. 975 // The order matters: we must return the index of the final element, 976 // because the final one produces the most restrictive requirement 977 // on the importer. 978 switch { 979 case strings.HasSuffix(path, "/internal"): 980 return len(path) - len("internal"), true 981 case strings.Contains(path, "/internal/"): 982 return strings.LastIndex(path, "/internal/") + 1, true 983 case path == "internal", strings.HasPrefix(path, "internal/"): 984 return 0, true 985 } 986 return 0, false 987 } 988 989 // disallowVendor checks that srcDir (containing package importerPath, if non-empty) 990 // is allowed to import p as path. 991 // If the import is allowed, disallowVendor returns the original package p. 992 // If not, it returns a new package containing just an appropriate error. 993 func disallowVendor(srcDir string, importer *Package, importerPath, path string, p *Package, stk *ImportStack) *Package { 994 // The stack includes p.ImportPath. 995 // If that's the only thing on the stack, we started 996 // with a name given on the command line, not an 997 // import. Anything listed on the command line is fine. 998 if len(*stk) == 1 { 999 return p 1000 } 1001 1002 if perr := disallowVendorVisibility(srcDir, p, stk); perr != p { 1003 return perr 1004 } 1005 1006 // Paths like x/vendor/y must be imported as y, never as x/vendor/y. 1007 if i, ok := FindVendor(path); ok { 1008 perr := *p 1009 perr.Error = &PackageError{ 1010 ImportStack: stk.Copy(), 1011 Err: "must be imported as " + path[i+len("vendor/"):], 1012 } 1013 perr.Incomplete = true 1014 return &perr 1015 } 1016 1017 return p 1018 } 1019 1020 // disallowVendorVisibility checks that srcDir is allowed to import p. 1021 // The rules are the same as for /internal/ except that a path ending in /vendor 1022 // is not subject to the rules, only subdirectories of vendor. 1023 // This allows people to have packages and commands named vendor, 1024 // for maximal compatibility with existing source trees. 1025 func disallowVendorVisibility(srcDir string, p *Package, stk *ImportStack) *Package { 1026 // The stack includes p.ImportPath. 1027 // If that's the only thing on the stack, we started 1028 // with a name given on the command line, not an 1029 // import. Anything listed on the command line is fine. 1030 if len(*stk) == 1 { 1031 return p 1032 } 1033 1034 // Check for "vendor" element. 1035 i, ok := FindVendor(p.ImportPath) 1036 if !ok { 1037 return p 1038 } 1039 1040 // Vendor is present. 1041 // Map import path back to directory corresponding to parent of vendor. 1042 if i > 0 { 1043 i-- // rewind over slash in ".../vendor" 1044 } 1045 truncateTo := i + len(p.Dir) - len(p.ImportPath) 1046 if truncateTo < 0 || len(p.Dir) < truncateTo { 1047 return p 1048 } 1049 parent := p.Dir[:truncateTo] 1050 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1051 return p 1052 } 1053 1054 // Look for symlinks before reporting error. 1055 srcDir = expandPath(srcDir) 1056 parent = expandPath(parent) 1057 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1058 return p 1059 } 1060 1061 // Vendor is present, and srcDir is outside parent's tree. Not allowed. 1062 perr := *p 1063 perr.Error = &PackageError{ 1064 ImportStack: stk.Copy(), 1065 Err: "use of vendored package not allowed", 1066 } 1067 perr.Incomplete = true 1068 return &perr 1069 } 1070 1071 // FindVendor looks for the last non-terminating "vendor" path element in the given import path. 1072 // If there isn't one, FindVendor returns ok=false. 1073 // Otherwise, FindVendor returns ok=true and the index of the "vendor". 1074 // 1075 // Note that terminating "vendor" elements don't count: "x/vendor" is its own package, 1076 // not the vendored copy of an import "" (the empty import path). 1077 // This will allow people to have packages or commands named vendor. 1078 // This may help reduce breakage, or it may just be confusing. We'll see. 1079 func FindVendor(path string) (index int, ok bool) { 1080 // Two cases, depending on internal at start of string or not. 1081 // The order matters: we must return the index of the final element, 1082 // because the final one is where the effective import path starts. 1083 switch { 1084 case strings.Contains(path, "/vendor/"): 1085 return strings.LastIndex(path, "/vendor/") + 1, true 1086 case strings.HasPrefix(path, "vendor/"): 1087 return 0, true 1088 } 1089 return 0, false 1090 } 1091 1092 type TargetDir int 1093 1094 const ( 1095 ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*) 1096 ToBin // to bin dir inside package root (default for non-cmd/*) 1097 StalePath // an old import path; fail to build 1098 ) 1099 1100 // InstallTargetDir reports the target directory for installing the command p. 1101 func InstallTargetDir(p *Package) TargetDir { 1102 if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") { 1103 return StalePath 1104 } 1105 if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" { 1106 switch p.ImportPath { 1107 case "cmd/go", "cmd/gofmt": 1108 return ToBin 1109 } 1110 return ToTool 1111 } 1112 return ToBin 1113 } 1114 1115 var cgoExclude = map[string]bool{ 1116 "runtime/cgo": true, 1117 } 1118 1119 var cgoSyscallExclude = map[string]bool{ 1120 "runtime/cgo": true, 1121 "runtime/race": true, 1122 "runtime/msan": true, 1123 } 1124 1125 var foldPath = make(map[string]string) 1126 1127 // DefaultExecName returns the default executable name 1128 // for a package with the import path importPath. 1129 // 1130 // The default executable name is the last element of the import path. 1131 // In module-aware mode, an additional rule is used. If the last element 1132 // is a vN path element specifying the major version, then the second last 1133 // element of the import path is used instead. 1134 func DefaultExecName(importPath string) string { 1135 _, elem := pathpkg.Split(importPath) 1136 if cfg.ModulesEnabled { 1137 // If this is example.com/mycmd/v2, it's more useful to install it as mycmd than as v2. 1138 // See golang.org/issue/24667. 1139 isVersion := func(v string) bool { 1140 if len(v) < 2 || v[0] != 'v' || v[1] < '1' || '9' < v[1] { 1141 return false 1142 } 1143 for i := 2; i < len(v); i++ { 1144 if c := v[i]; c < '0' || '9' < c { 1145 return false 1146 } 1147 } 1148 return true 1149 } 1150 if isVersion(elem) { 1151 _, elem = pathpkg.Split(pathpkg.Dir(importPath)) 1152 } 1153 } 1154 return elem 1155 } 1156 1157 // load populates p using information from bp, err, which should 1158 // be the result of calling build.Context.Import. 1159 func (p *Package) load(stk *ImportStack, bp *build.Package, err error) { 1160 p.copyBuild(bp) 1161 1162 // The localPrefix is the path we interpret ./ imports relative to. 1163 // Synthesized main packages sometimes override this. 1164 if p.Internal.Local { 1165 p.Internal.LocalPrefix = dirToImportPath(p.Dir) 1166 } 1167 1168 if err != nil { 1169 p.Incomplete = true 1170 err = base.ExpandScanner(err) 1171 p.Error = &PackageError{ 1172 ImportStack: stk.Copy(), 1173 Err: err.Error(), 1174 } 1175 return 1176 } 1177 1178 // Build augmented import list to add implicit dependencies. 1179 // Be careful not to add imports twice, just to avoid confusion. 1180 importPaths := p.Imports 1181 1182 // Check for case-insensitive collision of input files. 1183 // To avoid problems on case-insensitive files, we reject any package 1184 // where two different input files have equal names under a case-insensitive 1185 // comparison. 1186 inputs := p.AllFiles() 1187 f1, f2 := str.FoldDup(inputs) 1188 if f1 != "" { 1189 p.Error = &PackageError{ 1190 ImportStack: stk.Copy(), 1191 Err: fmt.Sprintf("case-insensitive file name collision: %q and %q", f1, f2), 1192 } 1193 return 1194 } 1195 1196 // If first letter of input file is ASCII, it must be alphanumeric. 1197 // This avoids files turning into flags when invoking commands, 1198 // and other problems we haven't thought of yet. 1199 // Also, _cgo_ files must be generated by us, not supplied. 1200 // They are allowed to have //go:cgo_ldflag directives. 1201 // The directory scan ignores files beginning with _, 1202 // so we shouldn't see any _cgo_ files anyway, but just be safe. 1203 for _, file := range inputs { 1204 if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") { 1205 p.Error = &PackageError{ 1206 ImportStack: stk.Copy(), 1207 Err: fmt.Sprintf("invalid input file name %q", file), 1208 } 1209 return 1210 } 1211 } 1212 if name := pathpkg.Base(p.ImportPath); !SafeArg(name) { 1213 p.Error = &PackageError{ 1214 ImportStack: stk.Copy(), 1215 Err: fmt.Sprintf("invalid input directory name %q", name), 1216 } 1217 return 1218 } 1219 if !SafeArg(p.ImportPath) { 1220 p.Error = &PackageError{ 1221 ImportStack: stk.Copy(), 1222 Err: fmt.Sprintf("invalid import path %q", p.ImportPath), 1223 } 1224 return 1225 } 1226 1227 // Build list of imported packages and full dependency list. 1228 imports := make([]*Package, 0, len(p.Imports)) 1229 for i, path := range importPaths { 1230 p1 := LoadImport(path, p.Dir, p, stk, nil, ResolveImport) 1231 if p.Standard && p.Error == nil && !p1.Standard && p1.Error == nil { 1232 p.Error = &PackageError{ 1233 ImportStack: stk.Copy(), 1234 Err: fmt.Sprintf("non-standard import %q in standard package %q", path, p.ImportPath), 1235 } 1236 } 1237 1238 path = p1.ImportPath 1239 importPaths[i] = path 1240 if i < len(p.Imports) { 1241 p.Imports[i] = path 1242 } 1243 1244 imports = append(imports, p1) 1245 if p1.Incomplete { 1246 p.Incomplete = true 1247 } 1248 } 1249 p.Internal.Imports = imports 1250 1251 deps := make(map[string]*Package) 1252 var q []*Package 1253 q = append(q, imports...) 1254 for i := 0; i < len(q); i++ { 1255 p1 := q[i] 1256 path := p1.ImportPath 1257 // The same import path could produce an error or not, 1258 // depending on what tries to import it. 1259 // Prefer to record entries with errors, so we can report them. 1260 p0 := deps[path] 1261 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) { 1262 deps[path] = p1 1263 for _, p2 := range p1.Internal.Imports { 1264 if deps[p2.ImportPath] != p2 { 1265 q = append(q, p2) 1266 } 1267 } 1268 } 1269 } 1270 1271 p.Deps = make([]string, 0, len(deps)) 1272 for dep := range deps { 1273 p.Deps = append(p.Deps, dep) 1274 } 1275 sort.Strings(p.Deps) 1276 for _, dep := range p.Deps { 1277 p1 := deps[dep] 1278 if p1 == nil { 1279 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 1280 } 1281 if p1.Error != nil { 1282 p.DepsErrors = append(p.DepsErrors, p1.Error) 1283 } 1284 } 1285 1286 setError := func(msg string) { 1287 p.Error = &PackageError{ 1288 ImportStack: stk.Copy(), 1289 Err: msg, 1290 } 1291 } 1292 1293 // Check for case-insensitive collisions of import paths. 1294 fold := str.ToFold(p.ImportPath) 1295 if other := foldPath[fold]; other == "" { 1296 foldPath[fold] = p.ImportPath 1297 } else if other != p.ImportPath { 1298 setError(fmt.Sprintf("case-insensitive import collision: %q and %q", p.ImportPath, other)) 1299 return 1300 } 1301 1302 if cfg.ModulesEnabled { 1303 mainPath := p.ImportPath 1304 if p.Internal.CmdlineFiles { 1305 mainPath = "command-line-arguments" 1306 } 1307 p.Module = ModPackageModuleInfo(mainPath) 1308 if p.Name == "main" { 1309 p.Internal.BuildInfo = ModPackageBuildInfo(mainPath, p.Deps) 1310 } 1311 } 1312 } 1313 1314 // SafeArg reports whether arg is a "safe" command-line argument, 1315 // meaning that when it appears in a command-line, it probably 1316 // doesn't have some special meaning other than its own name. 1317 // Obviously args beginning with - are not safe (they look like flags). 1318 // Less obviously, args beginning with @ are not safe (they look like 1319 // GNU binutils flagfile specifiers, sometimes called "response files"). 1320 // To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII. 1321 // We accept leading . _ and / as likely in file system paths. 1322 // There is a copy of this function in cmd/compile/internal/gc/noder.go. 1323 func SafeArg(name string) bool { 1324 if name == "" { 1325 return false 1326 } 1327 c := name[0] 1328 return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf 1329 } 1330 1331 // LinkerDeps returns the list of linker-induced dependencies for main package p. 1332 func LinkerDeps(p *Package) []string { 1333 // Everything links runtime. 1334 deps := []string{"runtime"} 1335 1336 // Using the race detector forces an import of runtime/race. 1337 if cfg.BuildRace { 1338 deps = append(deps, "runtime/race") 1339 } 1340 // Using memory sanitizer forces an import of runtime/msan. 1341 if cfg.BuildMSan { 1342 deps = append(deps, "runtime/msan") 1343 } 1344 1345 return deps 1346 } 1347 1348 // externalLinkingForced reports whether external linking is being 1349 // forced even for programs that do not use cgo. 1350 func externalLinkingForced(p *Package) bool { 1351 return false 1352 } 1353 1354 // mkAbs rewrites list, which must be paths relative to p.Dir, 1355 // into a sorted list of absolute paths. It edits list in place but for 1356 // convenience also returns list back to its caller. 1357 func (p *Package) mkAbs(list []string) []string { 1358 for i, f := range list { 1359 list[i] = filepath.Join(p.Dir, f) 1360 } 1361 sort.Strings(list) 1362 return list 1363 } 1364 1365 // InternalGoFiles returns the list of Go files being built for the package, 1366 // using absolute paths. 1367 func (p *Package) InternalGoFiles() []string { 1368 return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles)) 1369 } 1370 1371 // InternalXGoFiles returns the list of Go files being built for the XTest package, 1372 // using absolute paths. 1373 func (p *Package) InternalXGoFiles() []string { 1374 return p.mkAbs(p.XTestGoFiles) 1375 } 1376 1377 // InternalGoFiles returns the list of all Go files possibly relevant for the package, 1378 // using absolute paths. "Possibly relevant" means that files are not excluded 1379 // due to build tags, but files with names beginning with . or _ are still excluded. 1380 func (p *Package) InternalAllGoFiles() []string { 1381 var extra []string 1382 for _, f := range p.IgnoredGoFiles { 1383 if f != "" && f[0] != '.' || f[0] != '_' { 1384 extra = append(extra, f) 1385 } 1386 } 1387 return p.mkAbs(str.StringList(extra, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 1388 } 1389 1390 // usesSwig reports whether the package needs to run SWIG. 1391 func (p *Package) UsesSwig() bool { 1392 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 1393 } 1394 1395 // usesCgo reports whether the package needs to run cgo 1396 func (p *Package) UsesCgo() bool { 1397 return len(p.CgoFiles) > 0 1398 } 1399 1400 // PackageList returns the list of packages in the dag rooted at roots 1401 // as visited in a depth-first post-order traversal. 1402 func PackageList(roots []*Package) []*Package { 1403 seen := map[*Package]bool{} 1404 all := []*Package{} 1405 var walk func(*Package) 1406 walk = func(p *Package) { 1407 if seen[p] { 1408 return 1409 } 1410 seen[p] = true 1411 for _, p1 := range p.Internal.Imports { 1412 walk(p1) 1413 } 1414 all = append(all, p) 1415 } 1416 for _, root := range roots { 1417 walk(root) 1418 } 1419 return all 1420 } 1421 1422 var cmdCache = map[string]*Package{} 1423 1424 func ClearCmdCache() { 1425 for name := range cmdCache { 1426 delete(cmdCache, name) 1427 } 1428 } 1429 1430 // LoadPackage loads the package named by arg. 1431 func LoadPackage(arg string, stk *ImportStack) *Package { 1432 p := loadPackage(arg, stk) 1433 setToolFlags(p) 1434 return p 1435 } 1436 1437 // LoadPackageNoFlags is like LoadPackage 1438 // but does not guarantee that the build tool flags are set in the result. 1439 // It is only for use by GOPATH-based "go get" 1440 // and is only appropriate for preliminary loading of packages. 1441 // A real load using LoadPackage or (more likely) 1442 // Packages, PackageAndErrors, or PackagesForBuild 1443 // must be done before passing the package to any build 1444 // steps, so that the tool flags can be set properly. 1445 // TODO(rsc): When GOPATH-based "go get" is removed, delete this function. 1446 func LoadPackageNoFlags(arg string, stk *ImportStack) *Package { 1447 return loadPackage(arg, stk) 1448 } 1449 1450 // loadPackage is like loadImport but is used for command-line arguments, 1451 // not for paths found in import statements. In addition to ordinary import paths, 1452 // loadPackage accepts pseudo-paths beginning with cmd/ to denote commands 1453 // in the Go command directory, as well as paths to those directories. 1454 func loadPackage(arg string, stk *ImportStack) *Package { 1455 if arg == "" { 1456 panic("loadPackage called with empty package path") 1457 } 1458 1459 // Wasn't a command; must be a package. 1460 // If it is a local import path but names a standard package, 1461 // we treat it as if the user specified the standard package. 1462 // This lets you run go test ./ioutil in package io and be 1463 // referring to io/ioutil rather than a hypothetical import of 1464 // "./ioutil". 1465 if build.IsLocalImport(arg) || filepath.IsAbs(arg) { 1466 dir := arg 1467 if !filepath.IsAbs(arg) { 1468 dir = filepath.Join(base.Cwd, arg) 1469 } 1470 bp, _ := cfg.BuildContext.ImportDir(dir, 0) 1471 if bp.ImportPath != "" && bp.ImportPath != "." { 1472 arg = bp.ImportPath 1473 } 1474 } 1475 1476 return LoadImport(arg, base.Cwd, nil, stk, nil, 0) 1477 } 1478 1479 // Packages returns the packages named by the 1480 // command line arguments 'args'. If a named package 1481 // cannot be loaded at all (for example, if the directory does not exist), 1482 // then packages prints an error and does not include that 1483 // package in the results. However, if errors occur trying 1484 // to load dependencies of a named package, the named 1485 // package is still returned, with p.Incomplete = true 1486 // and details in p.DepsErrors. 1487 func Packages(args []string) []*Package { 1488 var pkgs []*Package 1489 for _, pkg := range PackagesAndErrors(args) { 1490 if pkg.Error != nil { 1491 base.Errorf("can't load package: %s", pkg.Error) 1492 continue 1493 } 1494 pkgs = append(pkgs, pkg) 1495 } 1496 return pkgs 1497 } 1498 1499 // PackagesAndErrors is like 'packages' but returns a 1500 // *Package for every argument, even the ones that 1501 // cannot be loaded at all. 1502 // The packages that fail to load will have p.Error != nil. 1503 func PackagesAndErrors(patterns []string) []*Package { 1504 if len(patterns) > 0 && strings.HasSuffix(patterns[0], ".go") { 1505 return []*Package{GoFilesPackage(patterns)} 1506 } 1507 1508 matches := ImportPaths(patterns) 1509 var ( 1510 pkgs []*Package 1511 stk ImportStack 1512 seenPkg = make(map[*Package]bool) 1513 ) 1514 1515 for _, m := range matches { 1516 for _, pkg := range m.Pkgs { 1517 if pkg == "" { 1518 panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern)) 1519 } 1520 p := loadPackage(pkg, &stk) 1521 p.Match = append(p.Match, m.Pattern) 1522 p.Internal.CmdlinePkg = true 1523 if m.Literal { 1524 // Note: do not set = m.Literal unconditionally 1525 // because maybe we'll see p matching both 1526 // a literal and also a non-literal pattern. 1527 p.Internal.CmdlinePkgLiteral = true 1528 } 1529 if seenPkg[p] { 1530 continue 1531 } 1532 seenPkg[p] = true 1533 pkgs = append(pkgs, p) 1534 } 1535 } 1536 1537 // Now that CmdlinePkg is set correctly, 1538 // compute the effective flags for all loaded packages 1539 // (not just the ones matching the patterns but also 1540 // their dependencies). 1541 setToolFlags(pkgs...) 1542 1543 return pkgs 1544 } 1545 1546 func setToolFlags(pkgs ...*Package) { 1547 for _, p := range PackageList(pkgs) { 1548 p.Internal.Asmflags = BuildAsmflags.For(p) 1549 p.Internal.Gcflags = BuildGcflags.For(p) 1550 p.Internal.Ldflags = BuildLdflags.For(p) 1551 p.Internal.Gccgoflags = BuildGccgoflags.For(p) 1552 } 1553 } 1554 1555 func ImportPaths(args []string) []*search.Match { 1556 if ModInit(); cfg.ModulesEnabled { 1557 return ModImportPaths(args) 1558 } 1559 return search.ImportPaths(args) 1560 } 1561 1562 // PackagesForBuild is like Packages but exits 1563 // if any of the packages or their dependencies have errors 1564 // (cannot be built). 1565 func PackagesForBuild(args []string) []*Package { 1566 pkgs := PackagesAndErrors(args) 1567 printed := map[*PackageError]bool{} 1568 for _, pkg := range pkgs { 1569 if pkg.Error != nil { 1570 base.Errorf("can't load package: %s", pkg.Error) 1571 printed[pkg.Error] = true 1572 } 1573 for _, err := range pkg.DepsErrors { 1574 // Since these are errors in dependencies, 1575 // the same error might show up multiple times, 1576 // once in each package that depends on it. 1577 // Only print each once. 1578 if !printed[err] { 1579 printed[err] = true 1580 base.Errorf("%s", err) 1581 } 1582 } 1583 } 1584 base.ExitIfErrors() 1585 1586 // Check for duplicate loads of the same package. 1587 // That should be impossible, but if it does happen then 1588 // we end up trying to build the same package twice, 1589 // usually in parallel overwriting the same files, 1590 // which doesn't work very well. 1591 seen := map[string]bool{} 1592 reported := map[string]bool{} 1593 for _, pkg := range PackageList(pkgs) { 1594 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] { 1595 reported[pkg.ImportPath] = true 1596 base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath) 1597 } 1598 seen[pkg.ImportPath] = true 1599 } 1600 base.ExitIfErrors() 1601 1602 return pkgs 1603 } 1604 1605 // GoFilesPackage creates a package for building a collection of Go files 1606 // (typically named on the command line). The target is named p.a for 1607 // package p or named after the first Go file for package main. 1608 func GoFilesPackage(gofiles []string) *Package { 1609 ModInit() 1610 1611 for _, f := range gofiles { 1612 if !strings.HasSuffix(f, ".go") { 1613 base.Fatalf("named files must be .go files") 1614 } 1615 } 1616 1617 var stk ImportStack 1618 ctxt := cfg.BuildContext 1619 1620 // Synthesize fake "directory" that only shows the named files, 1621 // to make it look like this is a standard package or 1622 // command directory. So that local imports resolve 1623 // consistently, the files must all be in the same directory. 1624 var dirent []os.FileInfo 1625 var dir string 1626 for _, file := range gofiles { 1627 fi, err := os.Stat(file) 1628 if err != nil { 1629 base.Fatalf("%s", err) 1630 } 1631 if fi.IsDir() { 1632 base.Fatalf("%s is a directory, should be a Go file", file) 1633 } 1634 dir1, _ := filepath.Split(file) 1635 if dir1 == "" { 1636 dir1 = "./" 1637 } 1638 if dir == "" { 1639 dir = dir1 1640 } else if dir != dir1 { 1641 base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1) 1642 } 1643 dirent = append(dirent, fi) 1644 } 1645 ctxt.ReadDir = func(string) ([]os.FileInfo, error) { return dirent, nil } 1646 1647 if cfg.ModulesEnabled { 1648 ModImportFromFiles(gofiles) 1649 } 1650 1651 var err error 1652 if dir == "" { 1653 dir = base.Cwd 1654 } 1655 dir, err = filepath.Abs(dir) 1656 if err != nil { 1657 base.Fatalf("%s", err) 1658 } 1659 1660 bp, err := ctxt.ImportDir(dir, 0) 1661 pkg := new(Package) 1662 pkg.Internal.Local = true 1663 pkg.Internal.CmdlineFiles = true 1664 stk.Push("main") 1665 pkg.load(&stk, bp, err) 1666 stk.Pop() 1667 pkg.Internal.LocalPrefix = dirToImportPath(dir) 1668 pkg.ImportPath = "command-line-arguments" 1669 pkg.Target = "" 1670 pkg.Match = gofiles 1671 1672 if pkg.Name == "main" { 1673 _, elem := filepath.Split(gofiles[0]) 1674 exe := elem[:len(elem)-len(".go")] + cfg.ExeSuffix 1675 if cfg.BuildO == "" { 1676 cfg.BuildO = exe 1677 } 1678 pkg.Target = filepath.Join(ModBinDir(), exe) 1679 } 1680 1681 setToolFlags(pkg) 1682 1683 return pkg 1684 }