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