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. 6package load 7 8import ( 9 "bytes" 10 "context" 11 "encoding/json" 12 "errors" 13 "fmt" 14 "go/build" 15 "go/scanner" 16 "go/token" 17 "io/fs" 18 "os" 19 "path" 20 pathpkg "path" 21 "path/filepath" 22 "runtime" 23 "sort" 24 "strconv" 25 "strings" 26 "unicode" 27 "unicode/utf8" 28 29 "cmd/go/internal/base" 30 "cmd/go/internal/cfg" 31 "cmd/go/internal/fsys" 32 "cmd/go/internal/modinfo" 33 "cmd/go/internal/modload" 34 "cmd/go/internal/par" 35 "cmd/go/internal/search" 36 "cmd/go/internal/str" 37 "cmd/go/internal/trace" 38 "cmd/internal/sys" 39 40 "golang.org/x/mod/module" 41) 42 43var IgnoreImports bool // control whether we ignore imports in packages 44 45// A Package describes a single package found in a directory. 46type Package struct { 47 PackagePublic // visible in 'go list' 48 Internal PackageInternal // for use inside go command only 49} 50 51type PackagePublic struct { 52 // Note: These fields are part of the go command's public API. 53 // See list.go. It is okay to add fields, but not to change or 54 // remove existing ones. Keep in sync with list.go 55 Dir string `json:",omitempty"` // directory containing package sources 56 ImportPath string `json:",omitempty"` // import path of package in dir 57 ImportComment string `json:",omitempty"` // path in import comment on package statement 58 Name string `json:",omitempty"` // package name 59 Doc string `json:",omitempty"` // package documentation string 60 Target string `json:",omitempty"` // installed target for this package (may be executable) 61 Shlib string `json:",omitempty"` // the shared library that contains this package (only set when -linkshared) 62 Root string `json:",omitempty"` // Go root, Go path dir, or module root dir containing this package 63 ConflictDir string `json:",omitempty"` // Dir is hidden by this other directory 64 ForTest string `json:",omitempty"` // package is only for use in named test 65 Export string `json:",omitempty"` // file containing export data (set by go list -export) 66 BuildID string `json:",omitempty"` // build ID of the compiled package (set by go list -export) 67 Module *modinfo.ModulePublic `json:",omitempty"` // info about package's module, if any 68 Match []string `json:",omitempty"` // command-line patterns matching this package 69 Goroot bool `json:",omitempty"` // is this package found in the Go root? 70 Standard bool `json:",omitempty"` // is this package part of the standard Go library? 71 DepOnly bool `json:",omitempty"` // package is only as a dependency, not explicitly listed 72 BinaryOnly bool `json:",omitempty"` // package cannot be recompiled 73 Incomplete bool `json:",omitempty"` // was there an error loading this package or dependencies? 74 75 // Stale and StaleReason remain here *only* for the list command. 76 // They are only initialized in preparation for list execution. 77 // The regular build determines staleness on the fly during action execution. 78 Stale bool `json:",omitempty"` // would 'go install' do anything for this package? 79 StaleReason string `json:",omitempty"` // why is Stale true? 80 81 // Source files 82 // If you add to this list you MUST add to p.AllFiles (below) too. 83 // Otherwise file name security lists will not apply to any new additions. 84 GoFiles []string `json:",omitempty"` // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles) 85 CgoFiles []string `json:",omitempty"` // .go source files that import "C" 86 CompiledGoFiles []string `json:",omitempty"` // .go output from running cgo on CgoFiles 87 IgnoredGoFiles []string `json:",omitempty"` // .go source files ignored due to build constraints 88 IgnoredOtherFiles []string `json:",omitempty"` // non-.go source files ignored due to build constraints 89 CFiles []string `json:",omitempty"` // .c source files 90 CXXFiles []string `json:",omitempty"` // .cc, .cpp and .cxx source files 91 MFiles []string `json:",omitempty"` // .m source files 92 HFiles []string `json:",omitempty"` // .h, .hh, .hpp and .hxx source files 93 FFiles []string `json:",omitempty"` // .f, .F, .for and .f90 Fortran source files 94 SFiles []string `json:",omitempty"` // .s source files 95 SwigFiles []string `json:",omitempty"` // .swig files 96 SwigCXXFiles []string `json:",omitempty"` // .swigcxx files 97 SysoFiles []string `json:",omitempty"` // .syso system object files added to package 98 99 // Embedded files 100 EmbedPatterns []string `json:",omitempty"` // //go:embed patterns 101 EmbedFiles []string `json:",omitempty"` // files matched by EmbedPatterns 102 103 // Cgo directives 104 CgoCFLAGS []string `json:",omitempty"` // cgo: flags for C compiler 105 CgoCPPFLAGS []string `json:",omitempty"` // cgo: flags for C preprocessor 106 CgoCXXFLAGS []string `json:",omitempty"` // cgo: flags for C++ compiler 107 CgoFFLAGS []string `json:",omitempty"` // cgo: flags for Fortran compiler 108 CgoLDFLAGS []string `json:",omitempty"` // cgo: flags for linker 109 CgoPkgConfig []string `json:",omitempty"` // cgo: pkg-config names 110 111 // Dependency information 112 Imports []string `json:",omitempty"` // import paths used by this package 113 ImportMap map[string]string `json:",omitempty"` // map from source import to ImportPath (identity entries omitted) 114 Deps []string `json:",omitempty"` // all (recursively) imported dependencies 115 116 // Error information 117 // Incomplete is above, packed into the other bools 118 Error *PackageError `json:",omitempty"` // error loading this package (not dependencies) 119 DepsErrors []*PackageError `json:",omitempty"` // errors loading dependencies 120 121 // Test information 122 // If you add to this list you MUST add to p.AllFiles (below) too. 123 // Otherwise file name security lists will not apply to any new additions. 124 TestGoFiles []string `json:",omitempty"` // _test.go files in package 125 TestImports []string `json:",omitempty"` // imports from TestGoFiles 126 TestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns 127 TestEmbedFiles []string `json:",omitempty"` // files matched by TestEmbedPatterns 128 XTestGoFiles []string `json:",omitempty"` // _test.go files outside package 129 XTestImports []string `json:",omitempty"` // imports from XTestGoFiles 130 XTestEmbedPatterns []string `json:",omitempty"` // //go:embed patterns 131 XTestEmbedFiles []string `json:",omitempty"` // files matched by XTestEmbedPatterns 132} 133 134// AllFiles returns the names of all the files considered for the package. 135// This is used for sanity and security checks, so we include all files, 136// even IgnoredGoFiles, because some subcommands consider them. 137// The go/build package filtered others out (like foo_wrongGOARCH.s) 138// and that's OK. 139func (p *Package) AllFiles() []string { 140 files := str.StringList( 141 p.GoFiles, 142 p.CgoFiles, 143 // no p.CompiledGoFiles, because they are from GoFiles or generated by us 144 p.IgnoredGoFiles, 145 p.IgnoredOtherFiles, 146 p.CFiles, 147 p.CXXFiles, 148 p.MFiles, 149 p.HFiles, 150 p.FFiles, 151 p.SFiles, 152 p.SwigFiles, 153 p.SwigCXXFiles, 154 p.SysoFiles, 155 p.TestGoFiles, 156 p.XTestGoFiles, 157 ) 158 159 // EmbedFiles may overlap with the other files. 160 // Dedup, but delay building the map as long as possible. 161 // Only files in the current directory (no slash in name) 162 // need to be checked against the files variable above. 163 var have map[string]bool 164 for _, file := range p.EmbedFiles { 165 if !strings.Contains(file, "/") { 166 if have == nil { 167 have = make(map[string]bool) 168 for _, file := range files { 169 have[file] = true 170 } 171 } 172 if have[file] { 173 continue 174 } 175 } 176 files = append(files, file) 177 } 178 return files 179} 180 181// Desc returns the package "description", for use in b.showOutput. 182func (p *Package) Desc() string { 183 if p.ForTest != "" { 184 return p.ImportPath + " [" + p.ForTest + ".test]" 185 } 186 return p.ImportPath 187} 188 189type PackageInternal struct { 190 // Unexported fields are not part of the public API. 191 Build *build.Package 192 Imports []*Package // this package's direct imports 193 CompiledImports []string // additional Imports necessary when using CompiledGoFiles (all from standard library) 194 RawImports []string // this package's original imports as they appear in the text of the program 195 ForceLibrary bool // this package is a library (even if named "main") 196 CmdlineFiles bool // package built from files listed on command line 197 CmdlinePkg bool // package listed on command line 198 CmdlinePkgLiteral bool // package listed as literal on command line (not via wildcard) 199 Local bool // imported via local path (./ or ../) 200 LocalPrefix string // interpret ./ and ../ imports relative to this prefix 201 ExeName string // desired name for temporary executable 202 CoverMode string // preprocess Go source files with the coverage tool in this mode 203 CoverVars map[string]*CoverVar // variables created by coverage analysis 204 OmitDebug bool // tell linker not to write debug information 205 GobinSubdir bool // install target would be subdir of GOBIN 206 BuildInfo string // add this info to package main 207 TestmainGo *[]byte // content for _testmain.go 208 Embed map[string][]string // //go:embed comment mapping 209 210 Asmflags []string // -asmflags for this package 211 Gcflags []string // -gcflags for this package 212 Ldflags []string // -ldflags for this package 213 Gccgoflags []string // -gccgoflags for this package 214} 215 216// A NoGoError indicates that no Go files for the package were applicable to the 217// build for that package. 218// 219// That may be because there were no files whatsoever, or because all files were 220// excluded, or because all non-excluded files were test sources. 221type NoGoError struct { 222 Package *Package 223} 224 225func (e *NoGoError) Error() string { 226 if len(e.Package.IgnoredGoFiles) > 0 { 227 // Go files exist, but they were ignored due to build constraints. 228 return "build constraints exclude all Go files in " + e.Package.Dir 229 } 230 if len(e.Package.TestGoFiles)+len(e.Package.XTestGoFiles) > 0 { 231 // Test Go files exist, but we're not interested in them. 232 // The double-negative is unfortunate but we want e.Package.Dir 233 // to appear at the end of error message. 234 return "no non-test Go files in " + e.Package.Dir 235 } 236 return "no Go files in " + e.Package.Dir 237} 238 239// setLoadPackageDataError presents an error found when loading package data 240// as a *PackageError. It has special cases for some common errors to improve 241// messages shown to users and reduce redundancy. 242// 243// setLoadPackageDataError returns true if it's safe to load information about 244// imported packages, for example, if there was a parse error loading imports 245// in one file, but other files are okay. 246func (p *Package) setLoadPackageDataError(err error, path string, stk *ImportStack, importPos []token.Position) { 247 matchErr, isMatchErr := err.(*search.MatchError) 248 if isMatchErr && matchErr.Match.Pattern() == path { 249 if matchErr.Match.IsLiteral() { 250 // The error has a pattern has a pattern similar to the import path. 251 // It may be slightly different (./foo matching example.com/foo), 252 // but close enough to seem redundant. 253 // Unwrap the error so we don't show the pattern. 254 err = matchErr.Err 255 } 256 } 257 258 // Replace (possibly wrapped) *build.NoGoError with *load.NoGoError. 259 // The latter is more specific about the cause. 260 var nogoErr *build.NoGoError 261 if errors.As(err, &nogoErr) { 262 if p.Dir == "" && nogoErr.Dir != "" { 263 p.Dir = nogoErr.Dir 264 } 265 err = &NoGoError{Package: p} 266 } 267 268 // Take only the first error from a scanner.ErrorList. PackageError only 269 // has room for one position, so we report the first error with a position 270 // instead of all of the errors without a position. 271 var pos string 272 var isScanErr bool 273 if scanErr, ok := err.(scanner.ErrorList); ok && len(scanErr) > 0 { 274 isScanErr = true // For stack push/pop below. 275 276 scanPos := scanErr[0].Pos 277 scanPos.Filename = base.ShortPath(scanPos.Filename) 278 pos = scanPos.String() 279 err = errors.New(scanErr[0].Msg) 280 } 281 282 // Report the error on the importing package if the problem is with the import declaration 283 // for example, if the package doesn't exist or if the import path is malformed. 284 // On the other hand, don't include a position if the problem is with the imported package, 285 // for example there are no Go files (NoGoError), or there's a problem in the imported 286 // package's source files themselves (scanner errors). 287 // 288 // TODO(matloob): Perhaps make each of those the errors in the first group 289 // (including modload.ImportMissingError, ImportMissingSumError, and the 290 // corresponding "cannot find package %q in any of" GOPATH-mode error 291 // produced in build.(*Context).Import; modload.AmbiguousImportError, 292 // and modload.PackageNotInModuleError; and the malformed module path errors 293 // produced in golang.org/x/mod/module.CheckMod) implement an interface 294 // to make it easier to check for them? That would save us from having to 295 // move the modload errors into this package to avoid a package import cycle, 296 // and from having to export an error type for the errors produced in build. 297 if !isMatchErr && (nogoErr != nil || isScanErr) { 298 stk.Push(path) 299 defer stk.Pop() 300 } 301 302 p.Error = &PackageError{ 303 ImportStack: stk.Copy(), 304 Pos: pos, 305 Err: err, 306 } 307 308 if path != stk.Top() { 309 p.Error.setPos(importPos) 310 } 311} 312 313// Resolve returns the resolved version of imports, 314// which should be p.TestImports or p.XTestImports, NOT p.Imports. 315// The imports in p.TestImports and p.XTestImports are not recursively 316// loaded during the initial load of p, so they list the imports found in 317// the source file, but most processing should be over the vendor-resolved 318// import paths. We do this resolution lazily both to avoid file system work 319// and because the eventual real load of the test imports (during 'go test') 320// can produce better error messages if it starts with the original paths. 321// The initial load of p loads all the non-test imports and rewrites 322// the vendored paths, so nothing should ever call p.vendored(p.Imports). 323func (p *Package) Resolve(imports []string) []string { 324 if len(imports) > 0 && len(p.Imports) > 0 && &imports[0] == &p.Imports[0] { 325 panic("internal error: p.Resolve(p.Imports) called") 326 } 327 seen := make(map[string]bool) 328 var all []string 329 for _, path := range imports { 330 path = ResolveImportPath(p, path) 331 if !seen[path] { 332 seen[path] = true 333 all = append(all, path) 334 } 335 } 336 sort.Strings(all) 337 return all 338} 339 340// CoverVar holds the name of the generated coverage variables targeting the named file. 341type CoverVar struct { 342 File string // local file name 343 Var string // name of count struct 344} 345 346func (p *Package) copyBuild(pp *build.Package) { 347 p.Internal.Build = pp 348 349 if pp.PkgTargetRoot != "" && cfg.BuildPkgdir != "" { 350 old := pp.PkgTargetRoot 351 pp.PkgRoot = cfg.BuildPkgdir 352 pp.PkgTargetRoot = cfg.BuildPkgdir 353 pp.PkgObj = filepath.Join(cfg.BuildPkgdir, strings.TrimPrefix(pp.PkgObj, old)) 354 } 355 356 p.Dir = pp.Dir 357 p.ImportPath = pp.ImportPath 358 p.ImportComment = pp.ImportComment 359 p.Name = pp.Name 360 p.Doc = pp.Doc 361 p.Root = pp.Root 362 p.ConflictDir = pp.ConflictDir 363 p.BinaryOnly = pp.BinaryOnly 364 365 // TODO? Target 366 p.Goroot = pp.Goroot 367 p.Standard = p.Goroot && p.ImportPath != "" && search.IsStandardImportPath(p.ImportPath) 368 p.GoFiles = pp.GoFiles 369 p.CgoFiles = pp.CgoFiles 370 p.IgnoredGoFiles = pp.IgnoredGoFiles 371 p.IgnoredOtherFiles = pp.IgnoredOtherFiles 372 p.CFiles = pp.CFiles 373 p.CXXFiles = pp.CXXFiles 374 p.MFiles = pp.MFiles 375 p.HFiles = pp.HFiles 376 p.FFiles = pp.FFiles 377 p.SFiles = pp.SFiles 378 p.SwigFiles = pp.SwigFiles 379 p.SwigCXXFiles = pp.SwigCXXFiles 380 p.SysoFiles = pp.SysoFiles 381 p.CgoCFLAGS = pp.CgoCFLAGS 382 p.CgoCPPFLAGS = pp.CgoCPPFLAGS 383 p.CgoCXXFLAGS = pp.CgoCXXFLAGS 384 p.CgoFFLAGS = pp.CgoFFLAGS 385 p.CgoLDFLAGS = pp.CgoLDFLAGS 386 p.CgoPkgConfig = pp.CgoPkgConfig 387 // We modify p.Imports in place, so make copy now. 388 p.Imports = make([]string, len(pp.Imports)) 389 copy(p.Imports, pp.Imports) 390 p.Internal.RawImports = pp.Imports 391 p.TestGoFiles = pp.TestGoFiles 392 p.TestImports = pp.TestImports 393 p.XTestGoFiles = pp.XTestGoFiles 394 p.XTestImports = pp.XTestImports 395 if IgnoreImports { 396 p.Imports = nil 397 p.Internal.RawImports = nil 398 p.TestImports = nil 399 p.XTestImports = nil 400 } 401 p.EmbedPatterns = pp.EmbedPatterns 402 p.TestEmbedPatterns = pp.TestEmbedPatterns 403 p.XTestEmbedPatterns = pp.XTestEmbedPatterns 404} 405 406// A PackageError describes an error loading information about a package. 407type PackageError struct { 408 ImportStack []string // shortest path from package named on command line to this one 409 Pos string // position of error 410 Err error // the error itself 411 IsImportCycle bool // the error is an import cycle 412 Hard bool // whether the error is soft or hard; soft errors are ignored in some places 413 alwaysPrintStack bool // whether to always print the ImportStack 414} 415 416func (p *PackageError) Error() string { 417 // TODO(#43696): decide when to print the stack or the position based on 418 // the error type and whether the package is in the main module. 419 // Document the rationale. 420 if p.Pos != "" && (len(p.ImportStack) == 0 || !p.alwaysPrintStack) { 421 // Omit import stack. The full path to the file where the error 422 // is the most important thing. 423 return p.Pos + ": " + p.Err.Error() 424 } 425 426 // If the error is an ImportPathError, and the last path on the stack appears 427 // in the error message, omit that path from the stack to avoid repetition. 428 // If an ImportPathError wraps another ImportPathError that matches the 429 // last path on the stack, we don't omit the path. An error like 430 // "package A imports B: error loading C caused by B" would not be clearer 431 // if "imports B" were omitted. 432 if len(p.ImportStack) == 0 { 433 return p.Err.Error() 434 } 435 var optpos string 436 if p.Pos != "" { 437 optpos = "\n\t" + p.Pos 438 } 439 return "package " + strings.Join(p.ImportStack, "\n\timports ") + optpos + ": " + p.Err.Error() 440} 441 442func (p *PackageError) Unwrap() error { return p.Err } 443 444// PackageError implements MarshalJSON so that Err is marshaled as a string 445// and non-essential fields are omitted. 446func (p *PackageError) MarshalJSON() ([]byte, error) { 447 perr := struct { 448 ImportStack []string 449 Pos string 450 Err string 451 }{p.ImportStack, p.Pos, p.Err.Error()} 452 return json.Marshal(perr) 453} 454 455func (p *PackageError) setPos(posList []token.Position) { 456 if len(posList) == 0 { 457 return 458 } 459 pos := posList[0] 460 pos.Filename = base.ShortPath(pos.Filename) 461 p.Pos = pos.String() 462} 463 464// ImportPathError is a type of error that prevents a package from being loaded 465// for a given import path. When such a package is loaded, a *Package is 466// returned with Err wrapping an ImportPathError: the error is attached to 467// the imported package, not the importing package. 468// 469// The string returned by ImportPath must appear in the string returned by 470// Error. Errors that wrap ImportPathError (such as PackageError) may omit 471// the import path. 472type ImportPathError interface { 473 error 474 ImportPath() string 475} 476 477var ( 478 _ ImportPathError = (*importError)(nil) 479 _ ImportPathError = (*modload.ImportMissingError)(nil) 480 _ ImportPathError = (*modload.ImportMissingSumError)(nil) 481) 482 483type importError struct { 484 importPath string 485 err error // created with fmt.Errorf 486} 487 488func ImportErrorf(path, format string, args ...interface{}) ImportPathError { 489 err := &importError{importPath: path, err: fmt.Errorf(format, args...)} 490 if errStr := err.Error(); !strings.Contains(errStr, path) { 491 panic(fmt.Sprintf("path %q not in error %q", path, errStr)) 492 } 493 return err 494} 495 496func (e *importError) Error() string { 497 return e.err.Error() 498} 499 500func (e *importError) Unwrap() error { 501 // Don't return e.err directly, since we're only wrapping an error if %w 502 // was passed to ImportErrorf. 503 return errors.Unwrap(e.err) 504} 505 506func (e *importError) ImportPath() string { 507 return e.importPath 508} 509 510// An ImportStack is a stack of import paths, possibly with the suffix " (test)" appended. 511// The import path of a test package is the import path of the corresponding 512// non-test package with the suffix "_test" added. 513type ImportStack []string 514 515func (s *ImportStack) Push(p string) { 516 *s = append(*s, p) 517} 518 519func (s *ImportStack) Pop() { 520 *s = (*s)[0 : len(*s)-1] 521} 522 523func (s *ImportStack) Copy() []string { 524 return append([]string{}, *s...) 525} 526 527func (s *ImportStack) Top() string { 528 if len(*s) == 0 { 529 return "" 530 } 531 return (*s)[len(*s)-1] 532} 533 534// shorterThan reports whether sp is shorter than t. 535// We use this to record the shortest import sequence 536// that leads to a particular package. 537func (sp *ImportStack) shorterThan(t []string) bool { 538 s := *sp 539 if len(s) != len(t) { 540 return len(s) < len(t) 541 } 542 // If they are the same length, settle ties using string ordering. 543 for i := range s { 544 if s[i] != t[i] { 545 return s[i] < t[i] 546 } 547 } 548 return false // they are equal 549} 550 551// packageCache is a lookup cache for LoadImport, 552// so that if we look up a package multiple times 553// we return the same pointer each time. 554var packageCache = map[string]*Package{} 555 556// ClearPackageCache clears the in-memory package cache and the preload caches. 557// It is only for use by GOPATH-based "go get". 558// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function. 559func ClearPackageCache() { 560 for name := range packageCache { 561 delete(packageCache, name) 562 } 563 resolvedImportCache.Clear() 564 packageDataCache.Clear() 565} 566 567// ClearPackageCachePartial clears packages with the given import paths from the 568// in-memory package cache and the preload caches. It is only for use by 569// GOPATH-based "go get". 570// TODO(jayconrod): When GOPATH-based "go get" is removed, delete this function. 571func ClearPackageCachePartial(args []string) { 572 shouldDelete := make(map[string]bool) 573 for _, arg := range args { 574 shouldDelete[arg] = true 575 if p := packageCache[arg]; p != nil { 576 delete(packageCache, arg) 577 } 578 } 579 resolvedImportCache.DeleteIf(func(key interface{}) bool { 580 return shouldDelete[key.(importSpec).path] 581 }) 582 packageDataCache.DeleteIf(func(key interface{}) bool { 583 return shouldDelete[key.(string)] 584 }) 585} 586 587// ReloadPackageNoFlags is like LoadImport but makes sure 588// not to use the package cache. 589// It is only for use by GOPATH-based "go get". 590// TODO(rsc): When GOPATH-based "go get" is removed, delete this function. 591func ReloadPackageNoFlags(arg string, stk *ImportStack) *Package { 592 p := packageCache[arg] 593 if p != nil { 594 delete(packageCache, arg) 595 resolvedImportCache.DeleteIf(func(key interface{}) bool { 596 return key.(importSpec).path == p.ImportPath 597 }) 598 packageDataCache.Delete(p.ImportPath) 599 } 600 return LoadImport(context.TODO(), arg, base.Cwd, nil, stk, nil, 0) 601} 602 603// dirToImportPath returns the pseudo-import path we use for a package 604// outside the Go path. It begins with _/ and then contains the full path 605// to the directory. If the package lives in c:\home\gopher\my\pkg then 606// the pseudo-import path is _/c_/home/gopher/my/pkg. 607// Using a pseudo-import path like this makes the ./ imports no longer 608// a special case, so that all the code to deal with ordinary imports works 609// automatically. 610func dirToImportPath(dir string) string { 611 return pathpkg.Join("_", strings.Map(makeImportValid, filepath.ToSlash(dir))) 612} 613 614func makeImportValid(r rune) rune { 615 // Should match Go spec, compilers, and ../../go/parser/parser.go:/isValidImport. 616 const illegalChars = `!"#$%&'()*,:;<=>?[\]^{|}` + "`\uFFFD" 617 if !unicode.IsGraphic(r) || unicode.IsSpace(r) || strings.ContainsRune(illegalChars, r) { 618 return '_' 619 } 620 return r 621} 622 623// Mode flags for loadImport and download (in get.go). 624const ( 625 // ResolveImport means that loadImport should do import path expansion. 626 // That is, ResolveImport means that the import path came from 627 // a source file and has not been expanded yet to account for 628 // vendoring or possible module adjustment. 629 // Every import path should be loaded initially with ResolveImport, 630 // and then the expanded version (for example with the /vendor/ in it) 631 // gets recorded as the canonical import path. At that point, future loads 632 // of that package must not pass ResolveImport, because 633 // disallowVendor will reject direct use of paths containing /vendor/. 634 ResolveImport = 1 << iota 635 636 // ResolveModule is for download (part of "go get") and indicates 637 // that the module adjustment should be done, but not vendor adjustment. 638 ResolveModule 639 640 // GetTestDeps is for download (part of "go get") and indicates 641 // that test dependencies should be fetched too. 642 GetTestDeps 643) 644 645// LoadImport scans the directory named by path, which must be an import path, 646// but possibly a local import path (an absolute file system path or one beginning 647// with ./ or ../). A local relative path is interpreted relative to srcDir. 648// It returns a *Package describing the package found in that directory. 649// LoadImport does not set tool flags and should only be used by 650// this package, as part of a bigger load operation, and by GOPATH-based "go get". 651// TODO(rsc): When GOPATH-based "go get" is removed, unexport this function. 652func LoadImport(ctx context.Context, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { 653 return loadImport(ctx, nil, path, srcDir, parent, stk, importPos, mode) 654} 655 656func loadImport(ctx context.Context, pre *preload, path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { 657 if path == "" { 658 panic("LoadImport called with empty package path") 659 } 660 661 var parentPath, parentRoot string 662 parentIsStd := false 663 if parent != nil { 664 parentPath = parent.ImportPath 665 parentRoot = parent.Root 666 parentIsStd = parent.Standard 667 } 668 bp, loaded, err := loadPackageData(path, parentPath, srcDir, parentRoot, parentIsStd, mode) 669 if loaded && pre != nil && !IgnoreImports { 670 pre.preloadImports(bp.Imports, bp) 671 } 672 if bp == nil { 673 if importErr, ok := err.(ImportPathError); !ok || importErr.ImportPath() != path { 674 // Only add path to the error's import stack if it's not already present on the error. 675 stk.Push(path) 676 defer stk.Pop() 677 } 678 return &Package{ 679 PackagePublic: PackagePublic{ 680 ImportPath: path, 681 Error: &PackageError{ 682 ImportStack: stk.Copy(), 683 Err: err, 684 }, 685 }, 686 } 687 } 688 689 importPath := bp.ImportPath 690 p := packageCache[importPath] 691 if p != nil { 692 stk.Push(path) 693 p = reusePackage(p, stk) 694 stk.Pop() 695 } else { 696 p = new(Package) 697 p.Internal.Local = build.IsLocalImport(path) 698 p.ImportPath = importPath 699 packageCache[importPath] = p 700 701 // Load package. 702 // loadPackageData may return bp != nil even if an error occurs, 703 // in order to return partial information. 704 p.load(ctx, path, stk, importPos, bp, err) 705 706 if !cfg.ModulesEnabled && path != cleanImport(path) { 707 p.Error = &PackageError{ 708 ImportStack: stk.Copy(), 709 Err: ImportErrorf(path, "non-canonical import path %q: should be %q", path, pathpkg.Clean(path)), 710 } 711 p.Incomplete = true 712 p.Error.setPos(importPos) 713 } 714 } 715 716 // Checked on every import because the rules depend on the code doing the importing. 717 if perr := disallowInternal(srcDir, parent, parentPath, p, stk); perr != p { 718 perr.Error.setPos(importPos) 719 return perr 720 } 721 if mode&ResolveImport != 0 { 722 if perr := disallowVendor(srcDir, path, parentPath, p, stk); perr != p { 723 perr.Error.setPos(importPos) 724 return perr 725 } 726 } 727 728 if p.Name == "main" && parent != nil && parent.Dir != p.Dir { 729 perr := *p 730 perr.Error = &PackageError{ 731 ImportStack: stk.Copy(), 732 Err: ImportErrorf(path, "import %q is a program, not an importable package", path), 733 } 734 perr.Error.setPos(importPos) 735 return &perr 736 } 737 738 if p.Internal.Local && parent != nil && !parent.Internal.Local { 739 perr := *p 740 var err error 741 if path == "." { 742 err = ImportErrorf(path, "%s: cannot import current directory", path) 743 } else { 744 err = ImportErrorf(path, "local import %q in non-local package", path) 745 } 746 perr.Error = &PackageError{ 747 ImportStack: stk.Copy(), 748 Err: err, 749 } 750 perr.Error.setPos(importPos) 751 return &perr 752 } 753 754 return p 755} 756 757// loadPackageData loads information needed to construct a *Package. The result 758// is cached, and later calls to loadPackageData for the same package will return 759// the same data. 760// 761// loadPackageData returns a non-nil package even if err is non-nil unless 762// the package path is malformed (for example, the path contains "mod/" or "@"). 763// 764// loadPackageData returns a boolean, loaded, which is true if this is the 765// first time the package was loaded. Callers may preload imports in this case. 766func loadPackageData(path, parentPath, parentDir, parentRoot string, parentIsStd bool, mode int) (bp *build.Package, loaded bool, err error) { 767 if path == "" { 768 panic("loadPackageData called with empty package path") 769 } 770 771 if strings.HasPrefix(path, "mod/") { 772 // Paths beginning with "mod/" might accidentally 773 // look in the module cache directory tree in $GOPATH/pkg/mod/. 774 // This prefix is owned by the Go core for possible use in the 775 // standard library (since it does not begin with a domain name), 776 // so it's OK to disallow entirely. 777 return nil, false, fmt.Errorf("disallowed import path %q", path) 778 } 779 780 if strings.Contains(path, "@") { 781 return nil, false, errors.New("can only use path@version syntax with 'go get' and 'go install' in module-aware mode") 782 } 783 784 // Determine canonical package path and directory. 785 // For a local import the identifier is the pseudo-import path 786 // we create from the full directory to the package. 787 // Otherwise it is the usual import path. 788 // For vendored imports, it is the expanded form. 789 // 790 // Note that when modules are enabled, local import paths are normally 791 // canonicalized by modload.LoadPackages before now. However, if there's an 792 // error resolving a local path, it will be returned untransformed 793 // so that 'go list -e' reports something useful. 794 importKey := importSpec{ 795 path: path, 796 parentPath: parentPath, 797 parentDir: parentDir, 798 parentRoot: parentRoot, 799 parentIsStd: parentIsStd, 800 mode: mode, 801 } 802 r := resolvedImportCache.Do(importKey, func() interface{} { 803 var r resolvedImport 804 if build.IsLocalImport(path) { 805 r.dir = filepath.Join(parentDir, path) 806 r.path = dirToImportPath(r.dir) 807 } else if cfg.ModulesEnabled { 808 r.dir, r.path, r.err = modload.Lookup(parentPath, parentIsStd, path) 809 } else if mode&ResolveImport != 0 { 810 // We do our own path resolution, because we want to 811 // find out the key to use in packageCache without the 812 // overhead of repeated calls to buildContext.Import. 813 // The code is also needed in a few other places anyway. 814 r.path = resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd) 815 } else if mode&ResolveModule != 0 { 816 r.path = moduleImportPath(path, parentPath, parentDir, parentRoot) 817 } 818 if r.path == "" { 819 r.path = path 820 } 821 return r 822 }).(resolvedImport) 823 // Invariant: r.path is set to the resolved import path. If the path cannot 824 // be resolved, r.path is set to path, the source import path. 825 // r.path is never empty. 826 827 // Load the package from its directory. If we already found the package's 828 // directory when resolving its import path, use that. 829 data := packageDataCache.Do(r.path, func() interface{} { 830 loaded = true 831 var data packageData 832 if r.dir != "" { 833 var buildMode build.ImportMode 834 if !cfg.ModulesEnabled { 835 buildMode = build.ImportComment 836 } 837 data.p, data.err = cfg.BuildContext.ImportDir(r.dir, buildMode) 838 if data.p.Root == "" && cfg.ModulesEnabled { 839 if info := modload.PackageModuleInfo(path); info != nil { 840 data.p.Root = info.Dir 841 } 842 } 843 } else if r.err != nil { 844 data.p = new(build.Package) 845 data.err = r.err 846 } else if cfg.ModulesEnabled && path != "unsafe" { 847 data.p = new(build.Package) 848 data.err = fmt.Errorf("unknown import path %q: internal error: module loader did not resolve import", r.path) 849 } else { 850 buildMode := build.ImportComment 851 if mode&ResolveImport == 0 || r.path != path { 852 // Not vendoring, or we already found the vendored path. 853 buildMode |= build.IgnoreVendor 854 } 855 data.p, data.err = cfg.BuildContext.Import(r.path, parentDir, buildMode) 856 } 857 data.p.ImportPath = r.path 858 859 // Set data.p.BinDir in cases where go/build.Context.Import 860 // may give us a path we don't want. 861 if !data.p.Goroot { 862 if cfg.GOBIN != "" { 863 data.p.BinDir = cfg.GOBIN 864 } else if cfg.ModulesEnabled { 865 data.p.BinDir = modload.BinDir() 866 } 867 } 868 869 if !cfg.ModulesEnabled && data.err == nil && 870 data.p.ImportComment != "" && data.p.ImportComment != path && 871 !strings.Contains(path, "/vendor/") && !strings.HasPrefix(path, "vendor/") { 872 data.err = fmt.Errorf("code in directory %s expects import %q", data.p.Dir, data.p.ImportComment) 873 } 874 return data 875 }).(packageData) 876 877 return data.p, loaded, data.err 878} 879 880// importSpec describes an import declaration in source code. It is used as a 881// cache key for resolvedImportCache. 882type importSpec struct { 883 path string 884 parentPath, parentDir, parentRoot string 885 parentIsStd bool 886 mode int 887} 888 889// resolvedImport holds a canonical identifier for a package. It may also contain 890// a path to the package's directory and an error if one occurred. resolvedImport 891// is the value type in resolvedImportCache. 892type resolvedImport struct { 893 path, dir string 894 err error 895} 896 897// packageData holds information loaded from a package. It is the value type 898// in packageDataCache. 899type packageData struct { 900 p *build.Package 901 err error 902} 903 904// resolvedImportCache maps import strings (importSpec) to canonical package names 905// (resolvedImport). 906var resolvedImportCache par.Cache 907 908// packageDataCache maps canonical package names (string) to package metadata 909// (packageData). 910var packageDataCache par.Cache 911 912// preloadWorkerCount is the number of concurrent goroutines that can load 913// packages. Experimentally, there are diminishing returns with more than 914// 4 workers. This was measured on the following machines. 915// 916// * MacBookPro with a 4-core Intel Core i7 CPU 917// * Linux workstation with 6-core Intel Xeon CPU 918// * Linux workstation with 24-core Intel Xeon CPU 919// 920// It is very likely (though not confirmed) that this workload is limited 921// by memory bandwidth. We don't have a good way to determine the number of 922// workers that would saturate the bus though, so runtime.GOMAXPROCS 923// seems like a reasonable default. 924var preloadWorkerCount = runtime.GOMAXPROCS(0) 925 926// preload holds state for managing concurrent preloading of package data. 927// 928// A preload should be created with newPreload before loading a large 929// package graph. flush must be called when package loading is complete 930// to ensure preload goroutines are no longer active. This is necessary 931// because of global mutable state that cannot safely be read and written 932// concurrently. In particular, packageDataCache may be cleared by "go get" 933// in GOPATH mode, and modload.loaded (accessed via modload.Lookup) may be 934// modified by modload.LoadPackages. 935type preload struct { 936 cancel chan struct{} 937 sema chan struct{} 938} 939 940// newPreload creates a new preloader. flush must be called later to avoid 941// accessing global state while it is being modified. 942func newPreload() *preload { 943 pre := &preload{ 944 cancel: make(chan struct{}), 945 sema: make(chan struct{}, preloadWorkerCount), 946 } 947 return pre 948} 949 950// preloadMatches loads data for package paths matched by patterns. 951// When preloadMatches returns, some packages may not be loaded yet, but 952// loadPackageData and loadImport are always safe to call. 953func (pre *preload) preloadMatches(matches []*search.Match) { 954 for _, m := range matches { 955 for _, pkg := range m.Pkgs { 956 select { 957 case <-pre.cancel: 958 return 959 case pre.sema <- struct{}{}: 960 go func(pkg string) { 961 mode := 0 // don't use vendoring or module import resolution 962 bp, loaded, err := loadPackageData(pkg, "", base.Cwd, "", false, mode) 963 <-pre.sema 964 if bp != nil && loaded && err == nil && !IgnoreImports { 965 pre.preloadImports(bp.Imports, bp) 966 } 967 }(pkg) 968 } 969 } 970 } 971} 972 973// preloadImports queues a list of imports for preloading. 974// When preloadImports returns, some packages may not be loaded yet, 975// but loadPackageData and loadImport are always safe to call. 976func (pre *preload) preloadImports(imports []string, parent *build.Package) { 977 parentIsStd := parent.Goroot && parent.ImportPath != "" && search.IsStandardImportPath(parent.ImportPath) 978 for _, path := range imports { 979 if path == "C" || path == "unsafe" { 980 continue 981 } 982 select { 983 case <-pre.cancel: 984 return 985 case pre.sema <- struct{}{}: 986 go func(path string) { 987 bp, loaded, err := loadPackageData(path, parent.ImportPath, parent.Dir, parent.Root, parentIsStd, ResolveImport) 988 <-pre.sema 989 if bp != nil && loaded && err == nil && !IgnoreImports { 990 pre.preloadImports(bp.Imports, bp) 991 } 992 }(path) 993 } 994 } 995} 996 997// flush stops pending preload operations. flush blocks until preload calls to 998// loadPackageData have completed. The preloader will not make any new calls 999// to loadPackageData. 1000func (pre *preload) flush() { 1001 // flush is usually deferred. 1002 // Don't hang program waiting for workers on panic. 1003 if v := recover(); v != nil { 1004 panic(v) 1005 } 1006 1007 close(pre.cancel) 1008 for i := 0; i < preloadWorkerCount; i++ { 1009 pre.sema <- struct{}{} 1010 } 1011} 1012 1013func cleanImport(path string) string { 1014 orig := path 1015 path = pathpkg.Clean(path) 1016 if strings.HasPrefix(orig, "./") && path != ".." && !strings.HasPrefix(path, "../") { 1017 path = "./" + path 1018 } 1019 return path 1020} 1021 1022var isDirCache par.Cache 1023 1024func isDir(path string) bool { 1025 return isDirCache.Do(path, func() interface{} { 1026 fi, err := fsys.Stat(path) 1027 return err == nil && fi.IsDir() 1028 }).(bool) 1029} 1030 1031// ResolveImportPath returns the true meaning of path when it appears in parent. 1032// There are two different resolutions applied. 1033// First, there is Go 1.5 vendoring (golang.org/s/go15vendor). 1034// If vendor expansion doesn't trigger, then the path is also subject to 1035// Go 1.11 module legacy conversion (golang.org/issue/25069). 1036func ResolveImportPath(parent *Package, path string) (found string) { 1037 var parentPath, parentDir, parentRoot string 1038 parentIsStd := false 1039 if parent != nil { 1040 parentPath = parent.ImportPath 1041 parentDir = parent.Dir 1042 parentRoot = parent.Root 1043 parentIsStd = parent.Standard 1044 } 1045 return resolveImportPath(path, parentPath, parentDir, parentRoot, parentIsStd) 1046} 1047 1048func resolveImportPath(path, parentPath, parentDir, parentRoot string, parentIsStd bool) (found string) { 1049 if cfg.ModulesEnabled { 1050 if _, p, e := modload.Lookup(parentPath, parentIsStd, path); e == nil { 1051 return p 1052 } 1053 return path 1054 } 1055 found = vendoredImportPath(path, parentPath, parentDir, parentRoot) 1056 if found != path { 1057 return found 1058 } 1059 return moduleImportPath(path, parentPath, parentDir, parentRoot) 1060} 1061 1062// dirAndRoot returns the source directory and workspace root 1063// for the package p, guaranteeing that root is a path prefix of dir. 1064func dirAndRoot(path string, dir, root string) (string, string) { 1065 origDir, origRoot := dir, root 1066 dir = filepath.Clean(dir) 1067 root = filepath.Join(root, "src") 1068 if !str.HasFilePathPrefix(dir, root) || path != "command-line-arguments" && filepath.Join(root, path) != dir { 1069 // Look for symlinks before reporting error. 1070 dir = expandPath(dir) 1071 root = expandPath(root) 1072 } 1073 1074 if !str.HasFilePathPrefix(dir, root) || len(dir) <= len(root) || dir[len(root)] != filepath.Separator || path != "command-line-arguments" && !build.IsLocalImport(path) && filepath.Join(root, path) != dir { 1075 base.Fatalf("unexpected directory layout:\n"+ 1076 " import path: %s\n"+ 1077 " root: %s\n"+ 1078 " dir: %s\n"+ 1079 " expand root: %s\n"+ 1080 " expand dir: %s\n"+ 1081 " separator: %s", 1082 path, 1083 filepath.Join(origRoot, "src"), 1084 filepath.Clean(origDir), 1085 origRoot, 1086 origDir, 1087 string(filepath.Separator)) 1088 } 1089 1090 return dir, root 1091} 1092 1093// vendoredImportPath returns the vendor-expansion of path when it appears in parent. 1094// If parent is x/y/z, then path might expand to x/y/z/vendor/path, x/y/vendor/path, 1095// x/vendor/path, vendor/path, or else stay path if none of those exist. 1096// vendoredImportPath returns the expanded path or, if no expansion is found, the original. 1097func vendoredImportPath(path, parentPath, parentDir, parentRoot string) (found string) { 1098 if parentRoot == "" { 1099 return path 1100 } 1101 1102 dir, root := dirAndRoot(parentPath, parentDir, parentRoot) 1103 1104 vpath := "vendor/" + path 1105 for i := len(dir); i >= len(root); i-- { 1106 if i < len(dir) && dir[i] != filepath.Separator { 1107 continue 1108 } 1109 // Note: checking for the vendor directory before checking 1110 // for the vendor/path directory helps us hit the 1111 // isDir cache more often. It also helps us prepare a more useful 1112 // list of places we looked, to report when an import is not found. 1113 if !isDir(filepath.Join(dir[:i], "vendor")) { 1114 continue 1115 } 1116 targ := filepath.Join(dir[:i], vpath) 1117 if isDir(targ) && hasGoFiles(targ) { 1118 importPath := parentPath 1119 if importPath == "command-line-arguments" { 1120 // If parent.ImportPath is 'command-line-arguments'. 1121 // set to relative directory to root (also chopped root directory) 1122 importPath = dir[len(root)+1:] 1123 } 1124 // We started with parent's dir c:\gopath\src\foo\bar\baz\quux\xyzzy. 1125 // We know the import path for parent's dir. 1126 // We chopped off some number of path elements and 1127 // added vendor\path to produce c:\gopath\src\foo\bar\baz\vendor\path. 1128 // Now we want to know the import path for that directory. 1129 // Construct it by chopping the same number of path elements 1130 // (actually the same number of bytes) from parent's import path 1131 // and then append /vendor/path. 1132 chopped := len(dir) - i 1133 if chopped == len(importPath)+1 { 1134 // We walked up from c:\gopath\src\foo\bar 1135 // and found c:\gopath\src\vendor\path. 1136 // We chopped \foo\bar (length 8) but the import path is "foo/bar" (length 7). 1137 // Use "vendor/path" without any prefix. 1138 return vpath 1139 } 1140 return importPath[:len(importPath)-chopped] + "/" + vpath 1141 } 1142 } 1143 return path 1144} 1145 1146var ( 1147 modulePrefix = []byte("\nmodule ") 1148 goModPathCache par.Cache 1149) 1150 1151// goModPath returns the module path in the go.mod in dir, if any. 1152func goModPath(dir string) (path string) { 1153 return goModPathCache.Do(dir, func() interface{} { 1154 data, err := os.ReadFile(filepath.Join(dir, "go.mod")) 1155 if err != nil { 1156 return "" 1157 } 1158 var i int 1159 if bytes.HasPrefix(data, modulePrefix[1:]) { 1160 i = 0 1161 } else { 1162 i = bytes.Index(data, modulePrefix) 1163 if i < 0 { 1164 return "" 1165 } 1166 i++ 1167 } 1168 line := data[i:] 1169 1170 // Cut line at \n, drop trailing \r if present. 1171 if j := bytes.IndexByte(line, '\n'); j >= 0 { 1172 line = line[:j] 1173 } 1174 if line[len(line)-1] == '\r' { 1175 line = line[:len(line)-1] 1176 } 1177 line = line[len("module "):] 1178 1179 // If quoted, unquote. 1180 path = strings.TrimSpace(string(line)) 1181 if path != "" && path[0] == '"' { 1182 s, err := strconv.Unquote(path) 1183 if err != nil { 1184 return "" 1185 } 1186 path = s 1187 } 1188 return path 1189 }).(string) 1190} 1191 1192// findVersionElement returns the slice indices of the final version element /vN in path. 1193// If there is no such element, it returns -1, -1. 1194func findVersionElement(path string) (i, j int) { 1195 j = len(path) 1196 for i = len(path) - 1; i >= 0; i-- { 1197 if path[i] == '/' { 1198 if isVersionElement(path[i+1 : j]) { 1199 return i, j 1200 } 1201 j = i 1202 } 1203 } 1204 return -1, -1 1205} 1206 1207// isVersionElement reports whether s is a well-formed path version element: 1208// v2, v3, v10, etc, but not v0, v05, v1. 1209func isVersionElement(s string) bool { 1210 if len(s) < 2 || s[0] != 'v' || s[1] == '0' || s[1] == '1' && len(s) == 2 { 1211 return false 1212 } 1213 for i := 1; i < len(s); i++ { 1214 if s[i] < '0' || '9' < s[i] { 1215 return false 1216 } 1217 } 1218 return true 1219} 1220 1221// moduleImportPath translates import paths found in go modules 1222// back down to paths that can be resolved in ordinary builds. 1223// 1224// Define “new” code as code with a go.mod file in the same directory 1225// or a parent directory. If an import in new code says x/y/v2/z but 1226// x/y/v2/z does not exist and x/y/go.mod says “module x/y/v2”, 1227// then go build will read the import as x/y/z instead. 1228// See golang.org/issue/25069. 1229func moduleImportPath(path, parentPath, parentDir, parentRoot string) (found string) { 1230 if parentRoot == "" { 1231 return path 1232 } 1233 1234 // If there are no vN elements in path, leave it alone. 1235 // (The code below would do the same, but only after 1236 // some other file system accesses that we can avoid 1237 // here by returning early.) 1238 if i, _ := findVersionElement(path); i < 0 { 1239 return path 1240 } 1241 1242 dir, root := dirAndRoot(parentPath, parentDir, parentRoot) 1243 1244 // Consider dir and parents, up to and including root. 1245 for i := len(dir); i >= len(root); i-- { 1246 if i < len(dir) && dir[i] != filepath.Separator { 1247 continue 1248 } 1249 if goModPath(dir[:i]) != "" { 1250 goto HaveGoMod 1251 } 1252 } 1253 // This code is not in a tree with a go.mod, 1254 // so apply no changes to the path. 1255 return path 1256 1257HaveGoMod: 1258 // This import is in a tree with a go.mod. 1259 // Allow it to refer to code in GOPATH/src/x/y/z as x/y/v2/z 1260 // if GOPATH/src/x/y/go.mod says module "x/y/v2", 1261 1262 // If x/y/v2/z exists, use it unmodified. 1263 if bp, _ := cfg.BuildContext.Import(path, "", build.IgnoreVendor); bp.Dir != "" { 1264 return path 1265 } 1266 1267 // Otherwise look for a go.mod supplying a version element. 1268 // Some version-like elements may appear in paths but not 1269 // be module versions; we skip over those to look for module 1270 // versions. For example the module m/v2 might have a 1271 // package m/v2/api/v1/foo. 1272 limit := len(path) 1273 for limit > 0 { 1274 i, j := findVersionElement(path[:limit]) 1275 if i < 0 { 1276 return path 1277 } 1278 if bp, _ := cfg.BuildContext.Import(path[:i], "", build.IgnoreVendor); bp.Dir != "" { 1279 if mpath := goModPath(bp.Dir); mpath != "" { 1280 // Found a valid go.mod file, so we're stopping the search. 1281 // If the path is m/v2/p and we found m/go.mod that says 1282 // "module m/v2", then we return "m/p". 1283 if mpath == path[:j] { 1284 return path[:i] + path[j:] 1285 } 1286 // Otherwise just return the original path. 1287 // We didn't find anything worth rewriting, 1288 // and the go.mod indicates that we should 1289 // not consider parent directories. 1290 return path 1291 } 1292 } 1293 limit = i 1294 } 1295 return path 1296} 1297 1298// hasGoFiles reports whether dir contains any files with names ending in .go. 1299// For a vendor check we must exclude directories that contain no .go files. 1300// Otherwise it is not possible to vendor just a/b/c and still import the 1301// non-vendored a/b. See golang.org/issue/13832. 1302func hasGoFiles(dir string) bool { 1303 files, _ := os.ReadDir(dir) 1304 for _, f := range files { 1305 if !f.IsDir() && strings.HasSuffix(f.Name(), ".go") { 1306 return true 1307 } 1308 } 1309 return false 1310} 1311 1312// reusePackage reuses package p to satisfy the import at the top 1313// of the import stack stk. If this use causes an import loop, 1314// reusePackage updates p's error information to record the loop. 1315func reusePackage(p *Package, stk *ImportStack) *Package { 1316 // We use p.Internal.Imports==nil to detect a package that 1317 // is in the midst of its own loadPackage call 1318 // (all the recursion below happens before p.Internal.Imports gets set). 1319 if p.Internal.Imports == nil { 1320 if p.Error == nil { 1321 p.Error = &PackageError{ 1322 ImportStack: stk.Copy(), 1323 Err: errors.New("import cycle not allowed"), 1324 IsImportCycle: true, 1325 } 1326 } 1327 p.Incomplete = true 1328 } 1329 // Don't rewrite the import stack in the error if we have an import cycle. 1330 // If we do, we'll lose the path that describes the cycle. 1331 if p.Error != nil && !p.Error.IsImportCycle && stk.shorterThan(p.Error.ImportStack) { 1332 p.Error.ImportStack = stk.Copy() 1333 } 1334 return p 1335} 1336 1337// disallowInternal checks that srcDir (containing package importerPath, if non-empty) 1338// is allowed to import p. 1339// If the import is allowed, disallowInternal returns the original package p. 1340// If not, it returns a new package containing just an appropriate error. 1341func disallowInternal(srcDir string, importer *Package, importerPath string, p *Package, stk *ImportStack) *Package { 1342 // golang.org/s/go14internal: 1343 // An import of a path containing the element “internal” 1344 // is disallowed if the importing code is outside the tree 1345 // rooted at the parent of the “internal” directory. 1346 1347 // There was an error loading the package; stop here. 1348 if p.Error != nil { 1349 return p 1350 } 1351 1352 // The generated 'testmain' package is allowed to access testing/internal/..., 1353 // as if it were generated into the testing directory tree 1354 // (it's actually in a temporary directory outside any Go tree). 1355 // This cleans up a former kludge in passing functionality to the testing package. 1356 if str.HasPathPrefix(p.ImportPath, "testing/internal") && importerPath == "testmain" { 1357 return p 1358 } 1359 1360 // We can't check standard packages with gccgo. 1361 if cfg.BuildContext.Compiler == "gccgo" { 1362 if importer == nil { 1363 if p.Standard { 1364 return p 1365 } 1366 } else if importer.Standard || strings.HasPrefix(importerPath, "cmd/") { 1367 return p 1368 } 1369 } 1370 1371 // The sort package depends on internal/reflectlite, but during bootstrap 1372 // the path rewriting causes the normal internal checks to fail. 1373 // Instead, just ignore the internal rules during bootstrap. 1374 if p.Standard && strings.HasPrefix(importerPath, "bootstrap/") { 1375 return p 1376 } 1377 1378 // importerPath is empty: we started 1379 // with a name given on the command line, not an 1380 // import. Anything listed on the command line is fine. 1381 if importerPath == "" { 1382 return p 1383 } 1384 1385 // Check for "internal" element: three cases depending on begin of string and/or end of string. 1386 i, ok := findInternal(p.ImportPath) 1387 if !ok { 1388 return p 1389 } 1390 1391 // Internal is present. 1392 // Map import path back to directory corresponding to parent of internal. 1393 if i > 0 { 1394 i-- // rewind over slash in ".../internal" 1395 } 1396 1397 if p.Module == nil { 1398 parent := p.Dir[:i+len(p.Dir)-len(p.ImportPath)] 1399 1400 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1401 return p 1402 } 1403 1404 // Look for symlinks before reporting error. 1405 srcDir = expandPath(srcDir) 1406 parent = expandPath(parent) 1407 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1408 return p 1409 } 1410 } else { 1411 // p is in a module, so make it available based on the importer's import path instead 1412 // of the file path (https://golang.org/issue/23970). 1413 if importer.Internal.CmdlineFiles { 1414 // The importer is a list of command-line files. 1415 // Pretend that the import path is the import path of the 1416 // directory containing them. 1417 // If the directory is outside the main module, this will resolve to ".", 1418 // which is not a prefix of any valid module. 1419 importerPath = modload.DirImportPath(importer.Dir) 1420 } 1421 parentOfInternal := p.ImportPath[:i] 1422 if str.HasPathPrefix(importerPath, parentOfInternal) { 1423 return p 1424 } 1425 } 1426 1427 // Internal is present, and srcDir is outside parent's tree. Not allowed. 1428 perr := *p 1429 perr.Error = &PackageError{ 1430 alwaysPrintStack: true, 1431 ImportStack: stk.Copy(), 1432 Err: ImportErrorf(p.ImportPath, "use of internal package "+p.ImportPath+" not allowed"), 1433 } 1434 perr.Incomplete = true 1435 return &perr 1436} 1437 1438// findInternal looks for the final "internal" path element in the given import path. 1439// If there isn't one, findInternal returns ok=false. 1440// Otherwise, findInternal returns ok=true and the index of the "internal". 1441func findInternal(path string) (index int, ok bool) { 1442 // Three cases, depending on internal at start/end of string or not. 1443 // The order matters: we must return the index of the final element, 1444 // because the final one produces the most restrictive requirement 1445 // on the importer. 1446 switch { 1447 case strings.HasSuffix(path, "/internal"): 1448 return len(path) - len("internal"), true 1449 case strings.Contains(path, "/internal/"): 1450 return strings.LastIndex(path, "/internal/") + 1, true 1451 case path == "internal", strings.HasPrefix(path, "internal/"): 1452 return 0, true 1453 } 1454 return 0, false 1455} 1456 1457// disallowVendor checks that srcDir is allowed to import p as path. 1458// If the import is allowed, disallowVendor returns the original package p. 1459// If not, it returns a new package containing just an appropriate error. 1460func disallowVendor(srcDir string, path string, importerPath string, p *Package, stk *ImportStack) *Package { 1461 // If the importerPath is empty, we started 1462 // with a name given on the command line, not an 1463 // import. Anything listed on the command line is fine. 1464 if importerPath == "" { 1465 return p 1466 } 1467 1468 if perr := disallowVendorVisibility(srcDir, p, importerPath, stk); perr != p { 1469 return perr 1470 } 1471 1472 // Paths like x/vendor/y must be imported as y, never as x/vendor/y. 1473 if i, ok := FindVendor(path); ok { 1474 perr := *p 1475 perr.Error = &PackageError{ 1476 ImportStack: stk.Copy(), 1477 Err: ImportErrorf(path, "%s must be imported as %s", path, path[i+len("vendor/"):]), 1478 } 1479 perr.Incomplete = true 1480 return &perr 1481 } 1482 1483 return p 1484} 1485 1486// disallowVendorVisibility checks that srcDir is allowed to import p. 1487// The rules are the same as for /internal/ except that a path ending in /vendor 1488// is not subject to the rules, only subdirectories of vendor. 1489// This allows people to have packages and commands named vendor, 1490// for maximal compatibility with existing source trees. 1491func disallowVendorVisibility(srcDir string, p *Package, importerPath string, stk *ImportStack) *Package { 1492 // The stack does not include p.ImportPath. 1493 // If there's nothing on the stack, we started 1494 // with a name given on the command line, not an 1495 // import. Anything listed on the command line is fine. 1496 if importerPath == "" { 1497 return p 1498 } 1499 1500 // Check for "vendor" element. 1501 i, ok := FindVendor(p.ImportPath) 1502 if !ok { 1503 return p 1504 } 1505 1506 // Vendor is present. 1507 // Map import path back to directory corresponding to parent of vendor. 1508 if i > 0 { 1509 i-- // rewind over slash in ".../vendor" 1510 } 1511 truncateTo := i + len(p.Dir) - len(p.ImportPath) 1512 if truncateTo < 0 || len(p.Dir) < truncateTo { 1513 return p 1514 } 1515 parent := p.Dir[:truncateTo] 1516 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1517 return p 1518 } 1519 1520 // Look for symlinks before reporting error. 1521 srcDir = expandPath(srcDir) 1522 parent = expandPath(parent) 1523 if str.HasFilePathPrefix(filepath.Clean(srcDir), filepath.Clean(parent)) { 1524 return p 1525 } 1526 1527 // Vendor is present, and srcDir is outside parent's tree. Not allowed. 1528 perr := *p 1529 perr.Error = &PackageError{ 1530 ImportStack: stk.Copy(), 1531 Err: errors.New("use of vendored package not allowed"), 1532 } 1533 perr.Incomplete = true 1534 return &perr 1535} 1536 1537// FindVendor looks for the last non-terminating "vendor" path element in the given import path. 1538// If there isn't one, FindVendor returns ok=false. 1539// Otherwise, FindVendor returns ok=true and the index of the "vendor". 1540// 1541// Note that terminating "vendor" elements don't count: "x/vendor" is its own package, 1542// not the vendored copy of an import "" (the empty import path). 1543// This will allow people to have packages or commands named vendor. 1544// This may help reduce breakage, or it may just be confusing. We'll see. 1545func FindVendor(path string) (index int, ok bool) { 1546 // Two cases, depending on internal at start of string or not. 1547 // The order matters: we must return the index of the final element, 1548 // because the final one is where the effective import path starts. 1549 switch { 1550 case strings.Contains(path, "/vendor/"): 1551 return strings.LastIndex(path, "/vendor/") + 1, true 1552 case strings.HasPrefix(path, "vendor/"): 1553 return 0, true 1554 } 1555 return 0, false 1556} 1557 1558type TargetDir int 1559 1560const ( 1561 ToTool TargetDir = iota // to GOROOT/pkg/tool (default for cmd/*) 1562 ToBin // to bin dir inside package root (default for non-cmd/*) 1563 StalePath // an old import path; fail to build 1564) 1565 1566// InstallTargetDir reports the target directory for installing the command p. 1567func InstallTargetDir(p *Package) TargetDir { 1568 if strings.HasPrefix(p.ImportPath, "code.google.com/p/go.tools/cmd/") { 1569 return StalePath 1570 } 1571 if p.Goroot && strings.HasPrefix(p.ImportPath, "cmd/") && p.Name == "main" { 1572 switch p.ImportPath { 1573 case "cmd/go", "cmd/gofmt": 1574 return ToBin 1575 } 1576 return ToTool 1577 } 1578 return ToBin 1579} 1580 1581var cgoExclude = map[string]bool{ 1582 "runtime/cgo": true, 1583} 1584 1585var cgoSyscallExclude = map[string]bool{ 1586 "runtime/cgo": true, 1587 "runtime/race": true, 1588 "runtime/msan": true, 1589} 1590 1591var foldPath = make(map[string]string) 1592 1593// exeFromImportPath returns an executable name 1594// for a package using the import path. 1595// 1596// The executable name is the last element of the import path. 1597// In module-aware mode, an additional rule is used on import paths 1598// consisting of two or more path elements. If the last element is 1599// a vN path element specifying the major version, then the 1600// second last element of the import path is used instead. 1601func (p *Package) exeFromImportPath() string { 1602 _, elem := pathpkg.Split(p.ImportPath) 1603 if cfg.ModulesEnabled { 1604 // If this is example.com/mycmd/v2, it's more useful to 1605 // install it as mycmd than as v2. See golang.org/issue/24667. 1606 if elem != p.ImportPath && isVersionElement(elem) { 1607 _, elem = pathpkg.Split(pathpkg.Dir(p.ImportPath)) 1608 } 1609 } 1610 return elem 1611} 1612 1613// exeFromFiles returns an executable name for a package 1614// using the first element in GoFiles or CgoFiles collections without the prefix. 1615// 1616// Returns empty string in case of empty collection. 1617func (p *Package) exeFromFiles() string { 1618 var src string 1619 if len(p.GoFiles) > 0 { 1620 src = p.GoFiles[0] 1621 } else if len(p.CgoFiles) > 0 { 1622 src = p.CgoFiles[0] 1623 } else { 1624 return "" 1625 } 1626 _, elem := filepath.Split(src) 1627 return elem[:len(elem)-len(".go")] 1628} 1629 1630// DefaultExecName returns the default executable name for a package 1631func (p *Package) DefaultExecName() string { 1632 if p.Internal.CmdlineFiles { 1633 return p.exeFromFiles() 1634 } 1635 return p.exeFromImportPath() 1636} 1637 1638// load populates p using information from bp, err, which should 1639// be the result of calling build.Context.Import. 1640// stk contains the import stack, not including path itself. 1641func (p *Package) load(ctx context.Context, path string, stk *ImportStack, importPos []token.Position, bp *build.Package, err error) { 1642 p.copyBuild(bp) 1643 1644 // The localPrefix is the path we interpret ./ imports relative to. 1645 // Synthesized main packages sometimes override this. 1646 if p.Internal.Local { 1647 p.Internal.LocalPrefix = dirToImportPath(p.Dir) 1648 } 1649 1650 // setError sets p.Error if it hasn't already been set. We may proceed 1651 // after encountering some errors so that 'go list -e' has more complete 1652 // output. If there's more than one error, we should report the first. 1653 setError := func(err error) { 1654 if p.Error == nil { 1655 p.Error = &PackageError{ 1656 ImportStack: stk.Copy(), 1657 Err: err, 1658 } 1659 1660 // Add the importer's position information if the import position exists, and 1661 // the current package being examined is the importer. 1662 // If we have not yet accepted package p onto the import stack, 1663 // then the cause of the error is not within p itself: the error 1664 // must be either in an explicit command-line argument, 1665 // or on the importer side (indicated by a non-empty importPos). 1666 if path != stk.Top() && len(importPos) > 0 { 1667 p.Error.setPos(importPos) 1668 } 1669 } 1670 } 1671 1672 if err != nil { 1673 p.Incomplete = true 1674 p.setLoadPackageDataError(err, path, stk, importPos) 1675 } 1676 1677 useBindir := p.Name == "main" 1678 if !p.Standard { 1679 switch cfg.BuildBuildmode { 1680 case "c-archive", "c-shared", "plugin": 1681 useBindir = false 1682 } 1683 } 1684 1685 if useBindir { 1686 // Report an error when the old code.google.com/p/go.tools paths are used. 1687 if InstallTargetDir(p) == StalePath { 1688 // TODO(matloob): remove this branch, and StalePath itself. code.google.com/p/go is so 1689 // old, even this code checking for it is stale now! 1690 newPath := strings.Replace(p.ImportPath, "code.google.com/p/go.", "golang.org/x/", 1) 1691 e := ImportErrorf(p.ImportPath, "the %v command has moved; use %v instead.", p.ImportPath, newPath) 1692 setError(e) 1693 return 1694 } 1695 elem := p.DefaultExecName() 1696 full := cfg.BuildContext.GOOS + "_" + cfg.BuildContext.GOARCH + "/" + elem 1697 if cfg.BuildContext.GOOS != base.ToolGOOS || cfg.BuildContext.GOARCH != base.ToolGOARCH { 1698 // Install cross-compiled binaries to subdirectories of bin. 1699 elem = full 1700 } 1701 if p.Internal.Build.BinDir == "" && cfg.ModulesEnabled { 1702 p.Internal.Build.BinDir = modload.BinDir() 1703 } 1704 if p.Internal.Build.BinDir != "" { 1705 // Install to GOBIN or bin of GOPATH entry. 1706 p.Target = filepath.Join(p.Internal.Build.BinDir, elem) 1707 if !p.Goroot && strings.Contains(elem, "/") && cfg.GOBIN != "" { 1708 // Do not create $GOBIN/goos_goarch/elem. 1709 p.Target = "" 1710 p.Internal.GobinSubdir = true 1711 } 1712 } 1713 if InstallTargetDir(p) == ToTool { 1714 // This is for 'go tool'. 1715 // Override all the usual logic and force it into the tool directory. 1716 if cfg.BuildToolchainName == "gccgo" { 1717 p.Target = filepath.Join(base.ToolDir, elem) 1718 } else { 1719 p.Target = filepath.Join(cfg.GOROOTpkg, "tool", full) 1720 } 1721 } 1722 if p.Target != "" && cfg.BuildContext.GOOS == "windows" { 1723 p.Target += ".exe" 1724 } 1725 } else if p.Internal.Local { 1726 // Local import turned into absolute path. 1727 // No permanent install target. 1728 p.Target = "" 1729 } else { 1730 p.Target = p.Internal.Build.PkgObj 1731 if cfg.BuildLinkshared && p.Target != "" { 1732 // TODO(bcmills): The reliance on p.Target implies that -linkshared does 1733 // not work for any package that lacks a Target — such as a non-main 1734 // package in module mode. We should probably fix that. 1735 shlibnamefile := p.Target[:len(p.Target)-2] + ".shlibname" 1736 shlib, err := os.ReadFile(shlibnamefile) 1737 if err != nil && !os.IsNotExist(err) { 1738 base.Fatalf("reading shlibname: %v", err) 1739 } 1740 if err == nil { 1741 libname := strings.TrimSpace(string(shlib)) 1742 if cfg.BuildContext.Compiler == "gccgo" { 1743 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, "shlibs", libname) 1744 } else { 1745 p.Shlib = filepath.Join(p.Internal.Build.PkgTargetRoot, libname) 1746 } 1747 } 1748 } 1749 } 1750 1751 // Build augmented import list to add implicit dependencies. 1752 // Be careful not to add imports twice, just to avoid confusion. 1753 importPaths := p.Imports 1754 addImport := func(path string, forCompiler bool) { 1755 for _, p := range importPaths { 1756 if path == p { 1757 return 1758 } 1759 } 1760 importPaths = append(importPaths, path) 1761 if forCompiler { 1762 p.Internal.CompiledImports = append(p.Internal.CompiledImports, path) 1763 } 1764 } 1765 1766 // Cgo translation adds imports of "unsafe", "runtime/cgo" and "syscall", 1767 // except for certain packages, to avoid circular dependencies. 1768 if p.UsesCgo() { 1769 addImport("unsafe", true) 1770 } 1771 if p.UsesCgo() && (!p.Standard || !cgoExclude[p.ImportPath]) && cfg.BuildContext.Compiler != "gccgo" { 1772 addImport("runtime/cgo", true) 1773 } 1774 if p.UsesCgo() && (!p.Standard || !cgoSyscallExclude[p.ImportPath]) { 1775 addImport("syscall", true) 1776 } 1777 1778 // SWIG adds imports of some standard packages. 1779 if p.UsesSwig() { 1780 addImport("unsafe", true) 1781 if cfg.BuildContext.Compiler != "gccgo" { 1782 addImport("runtime/cgo", true) 1783 } 1784 addImport("syscall", true) 1785 addImport("sync", true) 1786 1787 // TODO: The .swig and .swigcxx files can use 1788 // %go_import directives to import other packages. 1789 } 1790 1791 // The linker loads implicit dependencies. 1792 if p.Name == "main" && !p.Internal.ForceLibrary { 1793 for _, dep := range LinkerDeps(p) { 1794 addImport(dep, false) 1795 } 1796 } 1797 1798 // Check for case-insensitive collisions of import paths. 1799 fold := str.ToFold(p.ImportPath) 1800 if other := foldPath[fold]; other == "" { 1801 foldPath[fold] = p.ImportPath 1802 } else if other != p.ImportPath { 1803 setError(ImportErrorf(p.ImportPath, "case-insensitive import collision: %q and %q", p.ImportPath, other)) 1804 return 1805 } 1806 1807 if !SafeArg(p.ImportPath) { 1808 setError(ImportErrorf(p.ImportPath, "invalid import path %q", p.ImportPath)) 1809 return 1810 } 1811 1812 // Errors after this point are caused by this package, not the importing 1813 // package. Pushing the path here prevents us from reporting the error 1814 // with the position of the import declaration. 1815 stk.Push(path) 1816 defer stk.Pop() 1817 1818 p.EmbedFiles, p.Internal.Embed, err = resolveEmbed(p.Dir, p.EmbedPatterns) 1819 if err != nil { 1820 p.Incomplete = true 1821 setError(err) 1822 embedErr := err.(*EmbedError) 1823 p.Error.setPos(p.Internal.Build.EmbedPatternPos[embedErr.Pattern]) 1824 } 1825 1826 // Check for case-insensitive collision of input files. 1827 // To avoid problems on case-insensitive files, we reject any package 1828 // where two different input files have equal names under a case-insensitive 1829 // comparison. 1830 inputs := p.AllFiles() 1831 f1, f2 := str.FoldDup(inputs) 1832 if f1 != "" { 1833 setError(fmt.Errorf("case-insensitive file name collision: %q and %q", f1, f2)) 1834 return 1835 } 1836 1837 // If first letter of input file is ASCII, it must be alphanumeric. 1838 // This avoids files turning into flags when invoking commands, 1839 // and other problems we haven't thought of yet. 1840 // Also, _cgo_ files must be generated by us, not supplied. 1841 // They are allowed to have //go:cgo_ldflag directives. 1842 // The directory scan ignores files beginning with _, 1843 // so we shouldn't see any _cgo_ files anyway, but just be safe. 1844 for _, file := range inputs { 1845 if !SafeArg(file) || strings.HasPrefix(file, "_cgo_") { 1846 setError(fmt.Errorf("invalid input file name %q", file)) 1847 return 1848 } 1849 } 1850 if name := pathpkg.Base(p.ImportPath); !SafeArg(name) { 1851 setError(fmt.Errorf("invalid input directory name %q", name)) 1852 return 1853 } 1854 1855 // Build list of imported packages and full dependency list. 1856 imports := make([]*Package, 0, len(p.Imports)) 1857 for i, path := range importPaths { 1858 if path == "C" { 1859 continue 1860 } 1861 p1 := LoadImport(ctx, path, p.Dir, p, stk, p.Internal.Build.ImportPos[path], ResolveImport) 1862 1863 path = p1.ImportPath 1864 importPaths[i] = path 1865 if i < len(p.Imports) { 1866 p.Imports[i] = path 1867 } 1868 1869 imports = append(imports, p1) 1870 if p1.Incomplete { 1871 p.Incomplete = true 1872 } 1873 } 1874 p.Internal.Imports = imports 1875 p.collectDeps() 1876 1877 // unsafe is a fake package. 1878 if p.Standard && (p.ImportPath == "unsafe" || cfg.BuildContext.Compiler == "gccgo") { 1879 p.Target = "" 1880 } 1881 1882 // If cgo is not enabled, ignore cgo supporting sources 1883 // just as we ignore go files containing import "C". 1884 if !cfg.BuildContext.CgoEnabled { 1885 p.CFiles = nil 1886 p.CXXFiles = nil 1887 p.MFiles = nil 1888 p.SwigFiles = nil 1889 p.SwigCXXFiles = nil 1890 // Note that SFiles are okay (they go to the Go assembler) 1891 // and HFiles are okay (they might be used by the SFiles). 1892 // Also Sysofiles are okay (they might not contain object 1893 // code; see issue #16050). 1894 } 1895 1896 // The gc toolchain only permits C source files with cgo or SWIG. 1897 if len(p.CFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() && cfg.BuildContext.Compiler == "gc" { 1898 setError(fmt.Errorf("C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CFiles, " "))) 1899 return 1900 } 1901 1902 // C++, Objective-C, and Fortran source files are permitted only with cgo or SWIG, 1903 // regardless of toolchain. 1904 if len(p.CXXFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1905 setError(fmt.Errorf("C++ source files not allowed when not using cgo or SWIG: %s", strings.Join(p.CXXFiles, " "))) 1906 return 1907 } 1908 if len(p.MFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1909 setError(fmt.Errorf("Objective-C source files not allowed when not using cgo or SWIG: %s", strings.Join(p.MFiles, " "))) 1910 return 1911 } 1912 if len(p.FFiles) > 0 && !p.UsesCgo() && !p.UsesSwig() { 1913 setError(fmt.Errorf("Fortran source files not allowed when not using cgo or SWIG: %s", strings.Join(p.FFiles, " "))) 1914 return 1915 } 1916 1917 if cfg.ModulesEnabled && p.Error == nil { 1918 mainPath := p.ImportPath 1919 if p.Internal.CmdlineFiles { 1920 mainPath = "command-line-arguments" 1921 } 1922 p.Module = modload.PackageModuleInfo(mainPath) 1923 if p.Name == "main" && len(p.DepsErrors) == 0 { 1924 p.Internal.BuildInfo = modload.PackageBuildInfo(mainPath, p.Deps) 1925 } 1926 } 1927} 1928 1929// An EmbedError indicates a problem with a go:embed directive. 1930type EmbedError struct { 1931 Pattern string 1932 Err error 1933} 1934 1935func (e *EmbedError) Error() string { 1936 return fmt.Sprintf("pattern %s: %v", e.Pattern, e.Err) 1937} 1938 1939func (e *EmbedError) Unwrap() error { 1940 return e.Err 1941} 1942 1943// ResolveEmbed resolves //go:embed patterns and returns only the file list. 1944// For use by go mod vendor to find embedded files it should copy into the 1945// vendor directory. 1946// TODO(#42504): Once go mod vendor uses load.PackagesAndErrors, just 1947// call (*Package).ResolveEmbed 1948func ResolveEmbed(dir string, patterns []string) ([]string, error) { 1949 files, _, err := resolveEmbed(dir, patterns) 1950 return files, err 1951} 1952 1953// resolveEmbed resolves //go:embed patterns to precise file lists. 1954// It sets files to the list of unique files matched (for go list), 1955// and it sets pmap to the more precise mapping from 1956// patterns to files. 1957func resolveEmbed(pkgdir string, patterns []string) (files []string, pmap map[string][]string, err error) { 1958 var pattern string 1959 defer func() { 1960 if err != nil { 1961 err = &EmbedError{ 1962 Pattern: pattern, 1963 Err: err, 1964 } 1965 } 1966 }() 1967 1968 // TODO(rsc): All these messages need position information for better error reports. 1969 pmap = make(map[string][]string) 1970 have := make(map[string]int) 1971 dirOK := make(map[string]bool) 1972 pid := 0 // pattern ID, to allow reuse of have map 1973 for _, pattern = range patterns { 1974 pid++ 1975 1976 // Check pattern is valid for //go:embed. 1977 if _, err := path.Match(pattern, ""); err != nil || !validEmbedPattern(pattern) { 1978 return nil, nil, fmt.Errorf("invalid pattern syntax") 1979 } 1980 1981 // Glob to find matches. 1982 match, err := fsys.Glob(pkgdir + string(filepath.Separator) + filepath.FromSlash(pattern)) 1983 if err != nil { 1984 return nil, nil, err 1985 } 1986 1987 // Filter list of matches down to the ones that will still exist when 1988 // the directory is packaged up as a module. (If p.Dir is in the module cache, 1989 // only those files exist already, but if p.Dir is in the current module, 1990 // then there may be other things lying around, like symbolic links or .git directories.) 1991 var list []string 1992 for _, file := range match { 1993 rel := filepath.ToSlash(file[len(pkgdir)+1:]) // file, relative to p.Dir 1994 1995 what := "file" 1996 info, err := fsys.Lstat(file) 1997 if err != nil { 1998 return nil, nil, err 1999 } 2000 if info.IsDir() { 2001 what = "directory" 2002 } 2003 2004 // Check that directories along path do not begin a new module 2005 // (do not contain a go.mod). 2006 for dir := file; len(dir) > len(pkgdir)+1 && !dirOK[dir]; dir = filepath.Dir(dir) { 2007 if _, err := fsys.Stat(filepath.Join(dir, "go.mod")); err == nil { 2008 return nil, nil, fmt.Errorf("cannot embed %s %s: in different module", what, rel) 2009 } 2010 if dir != file { 2011 if info, err := fsys.Lstat(dir); err == nil && !info.IsDir() { 2012 return nil, nil, fmt.Errorf("cannot embed %s %s: in non-directory %s", what, rel, dir[len(pkgdir)+1:]) 2013 } 2014 } 2015 dirOK[dir] = true 2016 if elem := filepath.Base(dir); isBadEmbedName(elem) { 2017 if dir == file { 2018 return nil, nil, fmt.Errorf("cannot embed %s %s: invalid name %s", what, rel, elem) 2019 } else { 2020 return nil, nil, fmt.Errorf("cannot embed %s %s: in invalid directory %s", what, rel, elem) 2021 } 2022 } 2023 } 2024 2025 switch { 2026 default: 2027 return nil, nil, fmt.Errorf("cannot embed irregular file %s", rel) 2028 2029 case info.Mode().IsRegular(): 2030 if have[rel] != pid { 2031 have[rel] = pid 2032 list = append(list, rel) 2033 } 2034 2035 case info.IsDir(): 2036 // Gather all files in the named directory, stopping at module boundaries 2037 // and ignoring files that wouldn't be packaged into a module. 2038 count := 0 2039 err := fsys.Walk(file, func(path string, info os.FileInfo, err error) error { 2040 if err != nil { 2041 return err 2042 } 2043 rel := filepath.ToSlash(path[len(pkgdir)+1:]) 2044 name := info.Name() 2045 if path != file && (isBadEmbedName(name) || name[0] == '.' || name[0] == '_') { 2046 // Ignore bad names, assuming they won't go into modules. 2047 // Also avoid hidden files that user may not know about. 2048 // See golang.org/issue/42328. 2049 if info.IsDir() { 2050 return fs.SkipDir 2051 } 2052 return nil 2053 } 2054 if info.IsDir() { 2055 if _, err := fsys.Stat(filepath.Join(path, "go.mod")); err == nil { 2056 return filepath.SkipDir 2057 } 2058 return nil 2059 } 2060 if !info.Mode().IsRegular() { 2061 return nil 2062 } 2063 count++ 2064 if have[rel] != pid { 2065 have[rel] = pid 2066 list = append(list, rel) 2067 } 2068 return nil 2069 }) 2070 if err != nil { 2071 return nil, nil, err 2072 } 2073 if count == 0 { 2074 return nil, nil, fmt.Errorf("cannot embed directory %s: contains no embeddable files", rel) 2075 } 2076 } 2077 } 2078 2079 if len(list) == 0 { 2080 return nil, nil, fmt.Errorf("no matching files found") 2081 } 2082 sort.Strings(list) 2083 pmap[pattern] = list 2084 } 2085 2086 for file := range have { 2087 files = append(files, file) 2088 } 2089 sort.Strings(files) 2090 return files, pmap, nil 2091} 2092 2093func validEmbedPattern(pattern string) bool { 2094 return pattern != "." && fs.ValidPath(pattern) 2095} 2096 2097// isBadEmbedName reports whether name is the base name of a file that 2098// can't or won't be included in modules and therefore shouldn't be treated 2099// as existing for embedding. 2100func isBadEmbedName(name string) bool { 2101 if err := module.CheckFilePath(name); err != nil { 2102 return true 2103 } 2104 switch name { 2105 // Empty string should be impossible but make it bad. 2106 case "": 2107 return true 2108 // Version control directories won't be present in module. 2109 case ".bzr", ".hg", ".git", ".svn": 2110 return true 2111 } 2112 return false 2113} 2114 2115// collectDeps populates p.Deps and p.DepsErrors by iterating over 2116// p.Internal.Imports. 2117// 2118// TODO(jayconrod): collectDeps iterates over transitive imports for every 2119// package. We should only need to visit direct imports. 2120func (p *Package) collectDeps() { 2121 deps := make(map[string]*Package) 2122 var q []*Package 2123 q = append(q, p.Internal.Imports...) 2124 for i := 0; i < len(q); i++ { 2125 p1 := q[i] 2126 path := p1.ImportPath 2127 // The same import path could produce an error or not, 2128 // depending on what tries to import it. 2129 // Prefer to record entries with errors, so we can report them. 2130 p0 := deps[path] 2131 if p0 == nil || p1.Error != nil && (p0.Error == nil || len(p0.Error.ImportStack) > len(p1.Error.ImportStack)) { 2132 deps[path] = p1 2133 for _, p2 := range p1.Internal.Imports { 2134 if deps[p2.ImportPath] != p2 { 2135 q = append(q, p2) 2136 } 2137 } 2138 } 2139 } 2140 2141 p.Deps = make([]string, 0, len(deps)) 2142 for dep := range deps { 2143 p.Deps = append(p.Deps, dep) 2144 } 2145 sort.Strings(p.Deps) 2146 for _, dep := range p.Deps { 2147 p1 := deps[dep] 2148 if p1 == nil { 2149 panic("impossible: missing entry in package cache for " + dep + " imported by " + p.ImportPath) 2150 } 2151 if p1.Error != nil { 2152 p.DepsErrors = append(p.DepsErrors, p1.Error) 2153 } 2154 } 2155} 2156 2157// SafeArg reports whether arg is a "safe" command-line argument, 2158// meaning that when it appears in a command-line, it probably 2159// doesn't have some special meaning other than its own name. 2160// Obviously args beginning with - are not safe (they look like flags). 2161// Less obviously, args beginning with @ are not safe (they look like 2162// GNU binutils flagfile specifiers, sometimes called "response files"). 2163// To be conservative, we reject almost any arg beginning with non-alphanumeric ASCII. 2164// We accept leading . _ and / as likely in file system paths. 2165// There is a copy of this function in cmd/compile/internal/gc/noder.go. 2166func SafeArg(name string) bool { 2167 if name == "" { 2168 return false 2169 } 2170 c := name[0] 2171 return '0' <= c && c <= '9' || 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || c == '.' || c == '_' || c == '/' || c >= utf8.RuneSelf 2172} 2173 2174// LinkerDeps returns the list of linker-induced dependencies for main package p. 2175func LinkerDeps(p *Package) []string { 2176 // Everything links runtime. 2177 deps := []string{"runtime"} 2178 2179 // External linking mode forces an import of runtime/cgo. 2180 if externalLinkingForced(p) && cfg.BuildContext.Compiler != "gccgo" { 2181 deps = append(deps, "runtime/cgo") 2182 } 2183 // On ARM with GOARM=5, it forces an import of math, for soft floating point. 2184 if cfg.Goarch == "arm" { 2185 deps = append(deps, "math") 2186 } 2187 // Using the race detector forces an import of runtime/race. 2188 if cfg.BuildRace { 2189 deps = append(deps, "runtime/race") 2190 } 2191 // Using memory sanitizer forces an import of runtime/msan. 2192 if cfg.BuildMSan { 2193 deps = append(deps, "runtime/msan") 2194 } 2195 2196 return deps 2197} 2198 2199// externalLinkingForced reports whether external linking is being 2200// forced even for programs that do not use cgo. 2201func externalLinkingForced(p *Package) bool { 2202 if !cfg.BuildContext.CgoEnabled { 2203 return false 2204 } 2205 2206 // Some targets must use external linking even inside GOROOT. 2207 switch cfg.BuildContext.GOOS { 2208 case "android": 2209 if cfg.BuildContext.GOARCH != "arm64" { 2210 return true 2211 } 2212 case "ios": 2213 return true 2214 } 2215 2216 // Currently build modes c-shared, pie (on systems that do not 2217 // support PIE with internal linking mode (currently all 2218 // systems: issue #18968)), plugin, and -linkshared force 2219 // external linking mode, as of course does 2220 // -ldflags=-linkmode=external. External linking mode forces 2221 // an import of runtime/cgo. 2222 // If there are multiple -linkmode options, the last one wins. 2223 pieCgo := cfg.BuildBuildmode == "pie" && !sys.InternalLinkPIESupported(cfg.BuildContext.GOOS, cfg.BuildContext.GOARCH) 2224 linkmodeExternal := false 2225 if p != nil { 2226 ldflags := BuildLdflags.For(p) 2227 for i := len(ldflags) - 1; i >= 0; i-- { 2228 a := ldflags[i] 2229 if a == "-linkmode=external" || 2230 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "external" { 2231 linkmodeExternal = true 2232 break 2233 } else if a == "-linkmode=internal" || 2234 a == "-linkmode" && i+1 < len(ldflags) && ldflags[i+1] == "internal" { 2235 break 2236 } 2237 } 2238 } 2239 2240 return cfg.BuildBuildmode == "c-shared" || cfg.BuildBuildmode == "plugin" || pieCgo || cfg.BuildLinkshared || linkmodeExternal 2241} 2242 2243// mkAbs rewrites list, which must be paths relative to p.Dir, 2244// into a sorted list of absolute paths. It edits list in place but for 2245// convenience also returns list back to its caller. 2246func (p *Package) mkAbs(list []string) []string { 2247 for i, f := range list { 2248 list[i] = filepath.Join(p.Dir, f) 2249 } 2250 sort.Strings(list) 2251 return list 2252} 2253 2254// InternalGoFiles returns the list of Go files being built for the package, 2255// using absolute paths. 2256func (p *Package) InternalGoFiles() []string { 2257 return p.mkAbs(str.StringList(p.GoFiles, p.CgoFiles, p.TestGoFiles)) 2258} 2259 2260// InternalXGoFiles returns the list of Go files being built for the XTest package, 2261// using absolute paths. 2262func (p *Package) InternalXGoFiles() []string { 2263 return p.mkAbs(p.XTestGoFiles) 2264} 2265 2266// InternalGoFiles returns the list of all Go files possibly relevant for the package, 2267// using absolute paths. "Possibly relevant" means that files are not excluded 2268// due to build tags, but files with names beginning with . or _ are still excluded. 2269func (p *Package) InternalAllGoFiles() []string { 2270 return p.mkAbs(str.StringList(p.IgnoredGoFiles, p.GoFiles, p.CgoFiles, p.TestGoFiles, p.XTestGoFiles)) 2271} 2272 2273// usesSwig reports whether the package needs to run SWIG. 2274func (p *Package) UsesSwig() bool { 2275 return len(p.SwigFiles) > 0 || len(p.SwigCXXFiles) > 0 2276} 2277 2278// usesCgo reports whether the package needs to run cgo 2279func (p *Package) UsesCgo() bool { 2280 return len(p.CgoFiles) > 0 2281} 2282 2283// PackageList returns the list of packages in the dag rooted at roots 2284// as visited in a depth-first post-order traversal. 2285func PackageList(roots []*Package) []*Package { 2286 seen := map[*Package]bool{} 2287 all := []*Package{} 2288 var walk func(*Package) 2289 walk = func(p *Package) { 2290 if seen[p] { 2291 return 2292 } 2293 seen[p] = true 2294 for _, p1 := range p.Internal.Imports { 2295 walk(p1) 2296 } 2297 all = append(all, p) 2298 } 2299 for _, root := range roots { 2300 walk(root) 2301 } 2302 return all 2303} 2304 2305// TestPackageList returns the list of packages in the dag rooted at roots 2306// as visited in a depth-first post-order traversal, including the test 2307// imports of the roots. This ignores errors in test packages. 2308func TestPackageList(ctx context.Context, roots []*Package) []*Package { 2309 seen := map[*Package]bool{} 2310 all := []*Package{} 2311 var walk func(*Package) 2312 walk = func(p *Package) { 2313 if seen[p] { 2314 return 2315 } 2316 seen[p] = true 2317 for _, p1 := range p.Internal.Imports { 2318 walk(p1) 2319 } 2320 all = append(all, p) 2321 } 2322 walkTest := func(root *Package, path string) { 2323 var stk ImportStack 2324 p1 := LoadImport(ctx, path, root.Dir, root, &stk, root.Internal.Build.TestImportPos[path], ResolveImport) 2325 if p1.Error == nil { 2326 walk(p1) 2327 } 2328 } 2329 for _, root := range roots { 2330 walk(root) 2331 for _, path := range root.TestImports { 2332 walkTest(root, path) 2333 } 2334 for _, path := range root.XTestImports { 2335 walkTest(root, path) 2336 } 2337 } 2338 return all 2339} 2340 2341// LoadImportWithFlags loads the package with the given import path and 2342// sets tool flags on that package. This function is useful loading implicit 2343// dependencies (like sync/atomic for coverage). 2344// TODO(jayconrod): delete this function and set flags automatically 2345// in LoadImport instead. 2346func LoadImportWithFlags(path, srcDir string, parent *Package, stk *ImportStack, importPos []token.Position, mode int) *Package { 2347 p := LoadImport(context.TODO(), path, srcDir, parent, stk, importPos, mode) 2348 setToolFlags(p) 2349 return p 2350} 2351 2352// ModResolveTests indicates whether calls to the module loader should also 2353// resolve test dependencies of the requested packages. 2354// 2355// If ModResolveTests is true, then the module loader needs to resolve test 2356// dependencies at the same time as packages; otherwise, the test dependencies 2357// of those packages could be missing, and resolving those missing dependencies 2358// could change the selected versions of modules that provide other packages. 2359// 2360// TODO(#40775): Change this from a global variable to an explicit function 2361// argument where needed. 2362var ModResolveTests bool 2363 2364// PackagesAndErrors returns the packages named by the command line arguments 2365// 'patterns'. If a named package cannot be loaded, PackagesAndErrors returns 2366// a *Package with the Error field describing the failure. If errors are found 2367// loading imported packages, the DepsErrors field is set. The Incomplete field 2368// may be set as well. 2369// 2370// To obtain a flat list of packages, use PackageList. 2371// To report errors loading packages, use ReportPackageErrors. 2372func PackagesAndErrors(ctx context.Context, patterns []string) []*Package { 2373 ctx, span := trace.StartSpan(ctx, "load.PackagesAndErrors") 2374 defer span.Done() 2375 2376 for _, p := range patterns { 2377 // Listing is only supported with all patterns referring to either: 2378 // - Files that are part of the same directory. 2379 // - Explicit package paths or patterns. 2380 if strings.HasSuffix(p, ".go") { 2381 // We need to test whether the path is an actual Go file and not a 2382 // package path or pattern ending in '.go' (see golang.org/issue/34653). 2383 if fi, err := fsys.Stat(p); err == nil && !fi.IsDir() { 2384 return []*Package{GoFilesPackage(ctx, patterns)} 2385 } 2386 } 2387 } 2388 2389 var matches []*search.Match 2390 if modload.Init(); cfg.ModulesEnabled { 2391 loadOpts := modload.PackageOpts{ 2392 ResolveMissingImports: true, 2393 LoadTests: ModResolveTests, 2394 SilenceErrors: true, 2395 } 2396 matches, _ = modload.LoadPackages(ctx, loadOpts, patterns...) 2397 } else { 2398 matches = search.ImportPaths(patterns) 2399 } 2400 2401 var ( 2402 pkgs []*Package 2403 stk ImportStack 2404 seenPkg = make(map[*Package]bool) 2405 ) 2406 2407 pre := newPreload() 2408 defer pre.flush() 2409 pre.preloadMatches(matches) 2410 2411 for _, m := range matches { 2412 for _, pkg := range m.Pkgs { 2413 if pkg == "" { 2414 panic(fmt.Sprintf("ImportPaths returned empty package for pattern %s", m.Pattern())) 2415 } 2416 p := loadImport(ctx, pre, pkg, base.Cwd, nil, &stk, nil, 0) 2417 p.Match = append(p.Match, m.Pattern()) 2418 p.Internal.CmdlinePkg = true 2419 if m.IsLiteral() { 2420 // Note: do not set = m.IsLiteral unconditionally 2421 // because maybe we'll see p matching both 2422 // a literal and also a non-literal pattern. 2423 p.Internal.CmdlinePkgLiteral = true 2424 } 2425 if seenPkg[p] { 2426 continue 2427 } 2428 seenPkg[p] = true 2429 pkgs = append(pkgs, p) 2430 } 2431 2432 if len(m.Errs) > 0 { 2433 // In addition to any packages that were actually resolved from the 2434 // pattern, there was some error in resolving the pattern itself. 2435 // Report it as a synthetic package. 2436 p := new(Package) 2437 p.ImportPath = m.Pattern() 2438 // Pass an empty ImportStack and nil importPos: the error arose from a pattern, not an import. 2439 var stk ImportStack 2440 var importPos []token.Position 2441 p.setLoadPackageDataError(m.Errs[0], m.Pattern(), &stk, importPos) 2442 p.Incomplete = true 2443 p.Match = append(p.Match, m.Pattern()) 2444 p.Internal.CmdlinePkg = true 2445 if m.IsLiteral() { 2446 p.Internal.CmdlinePkgLiteral = true 2447 } 2448 pkgs = append(pkgs, p) 2449 } 2450 } 2451 2452 // Now that CmdlinePkg is set correctly, 2453 // compute the effective flags for all loaded packages 2454 // (not just the ones matching the patterns but also 2455 // their dependencies). 2456 setToolFlags(pkgs...) 2457 2458 return pkgs 2459} 2460 2461// CheckPackageErrors prints errors encountered loading pkgs and their 2462// dependencies, then exits with a non-zero status if any errors were found. 2463func CheckPackageErrors(pkgs []*Package) { 2464 printed := map[*PackageError]bool{} 2465 for _, pkg := range pkgs { 2466 if pkg.Error != nil { 2467 base.Errorf("%v", pkg.Error) 2468 printed[pkg.Error] = true 2469 } 2470 for _, err := range pkg.DepsErrors { 2471 // Since these are errors in dependencies, 2472 // the same error might show up multiple times, 2473 // once in each package that depends on it. 2474 // Only print each once. 2475 if !printed[err] { 2476 printed[err] = true 2477 base.Errorf("%v", err) 2478 } 2479 } 2480 } 2481 base.ExitIfErrors() 2482 2483 // Check for duplicate loads of the same package. 2484 // That should be impossible, but if it does happen then 2485 // we end up trying to build the same package twice, 2486 // usually in parallel overwriting the same files, 2487 // which doesn't work very well. 2488 seen := map[string]bool{} 2489 reported := map[string]bool{} 2490 for _, pkg := range PackageList(pkgs) { 2491 if seen[pkg.ImportPath] && !reported[pkg.ImportPath] { 2492 reported[pkg.ImportPath] = true 2493 base.Errorf("internal error: duplicate loads of %s", pkg.ImportPath) 2494 } 2495 seen[pkg.ImportPath] = true 2496 } 2497 base.ExitIfErrors() 2498} 2499 2500func setToolFlags(pkgs ...*Package) { 2501 for _, p := range PackageList(pkgs) { 2502 p.Internal.Asmflags = BuildAsmflags.For(p) 2503 p.Internal.Gcflags = BuildGcflags.For(p) 2504 p.Internal.Ldflags = BuildLdflags.For(p) 2505 p.Internal.Gccgoflags = BuildGccgoflags.For(p) 2506 } 2507} 2508 2509// GoFilesPackage creates a package for building a collection of Go files 2510// (typically named on the command line). The target is named p.a for 2511// package p or named after the first Go file for package main. 2512func GoFilesPackage(ctx context.Context, gofiles []string) *Package { 2513 modload.Init() 2514 2515 for _, f := range gofiles { 2516 if !strings.HasSuffix(f, ".go") { 2517 pkg := new(Package) 2518 pkg.Internal.Local = true 2519 pkg.Internal.CmdlineFiles = true 2520 pkg.Name = f 2521 pkg.Error = &PackageError{ 2522 Err: fmt.Errorf("named files must be .go files: %s", pkg.Name), 2523 } 2524 return pkg 2525 } 2526 } 2527 2528 var stk ImportStack 2529 ctxt := cfg.BuildContext 2530 ctxt.UseAllFiles = true 2531 2532 // Synthesize fake "directory" that only shows the named files, 2533 // to make it look like this is a standard package or 2534 // command directory. So that local imports resolve 2535 // consistently, the files must all be in the same directory. 2536 var dirent []fs.FileInfo 2537 var dir string 2538 for _, file := range gofiles { 2539 fi, err := fsys.Stat(file) 2540 if err != nil { 2541 base.Fatalf("%s", err) 2542 } 2543 if fi.IsDir() { 2544 base.Fatalf("%s is a directory, should be a Go file", file) 2545 } 2546 dir1, _ := filepath.Split(file) 2547 if dir1 == "" { 2548 dir1 = "./" 2549 } 2550 if dir == "" { 2551 dir = dir1 2552 } else if dir != dir1 { 2553 base.Fatalf("named files must all be in one directory; have %s and %s", dir, dir1) 2554 } 2555 dirent = append(dirent, fi) 2556 } 2557 ctxt.ReadDir = func(string) ([]fs.FileInfo, error) { return dirent, nil } 2558 2559 if cfg.ModulesEnabled { 2560 modload.ImportFromFiles(ctx, gofiles) 2561 } 2562 2563 var err error 2564 if dir == "" { 2565 dir = base.Cwd 2566 } 2567 dir, err = filepath.Abs(dir) 2568 if err != nil { 2569 base.Fatalf("%s", err) 2570 } 2571 2572 bp, err := ctxt.ImportDir(dir, 0) 2573 pkg := new(Package) 2574 pkg.Internal.Local = true 2575 pkg.Internal.CmdlineFiles = true 2576 pkg.load(ctx, "command-line-arguments", &stk, nil, bp, err) 2577 pkg.Internal.LocalPrefix = dirToImportPath(dir) 2578 pkg.ImportPath = "command-line-arguments" 2579 pkg.Target = "" 2580 pkg.Match = gofiles 2581 2582 if pkg.Name == "main" { 2583 exe := pkg.DefaultExecName() + cfg.ExeSuffix 2584 2585 if cfg.GOBIN != "" { 2586 pkg.Target = filepath.Join(cfg.GOBIN, exe) 2587 } else if cfg.ModulesEnabled { 2588 pkg.Target = filepath.Join(modload.BinDir(), exe) 2589 } 2590 } 2591 2592 setToolFlags(pkg) 2593 2594 return pkg 2595} 2596