From 7bcc2b016742dc0357da7606636cddde83490b6e Mon Sep 17 00:00:00 2001 From: gVisor bot Date: Tue, 6 Aug 2024 02:24:59 -0700 Subject: [PATCH] Internal change. PiperOrigin-RevId: 659870484 --- tools/nogo/check/check.go | 41 ++++++++++++++++++++------------------- tools/nogo/cli/cli.go | 14 +++++++------ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/tools/nogo/check/check.go b/tools/nogo/check/check.go index 0f194c7b1..b00182f47 100644 --- a/tools/nogo/check/check.go +++ b/tools/nogo/check/check.go @@ -33,6 +33,7 @@ import ( "reflect" "regexp" "runtime/debug" + "slices" "strings" "sync" @@ -676,34 +677,33 @@ func (i *importer) allFactsAndFindings() (FindingSet, *facts.Bundle) { return findings, allFacts } -// FindRoot finds a package root. -func FindRoot(srcs []string, srcRootRegex string) (string, error) { +// FindRoots finds a package roots. +func FindRoots(srcs []string, srcRootRegex string) ([]string, error) { if srcRootRegex == "" { - return "", nil + return nil, nil } - // Calculate the root source directory. This is always a directory - // named 'src', of which we simply take the first we find. This is a - // bit fragile, but works for all currently known Go source - // configurations. + // Calculate the root source directories. This is always a directory + // named 'src'. It's possible that there are more than one of these + // directories. // // Note that there may be extra files outside of the root source // directory; we simply ignore those. re, err := regexp.Compile(srcRootRegex) if err != nil { - return "", fmt.Errorf("srcRootRegex is not valid: %w", err) + return nil, fmt.Errorf("srcRootRegex is not valid: %w", err) } - srcRootPrefix := "" + var srcRootPrefixes []string for _, filename := range srcs { - if s := re.FindString(filename); len(s) > len(srcRootPrefix) { - srcRootPrefix = s + if s := re.FindString(filename); s != "" && !slices.Contains(srcRootPrefixes, s) { + srcRootPrefixes = append(srcRootPrefixes, s) } } - if srcRootPrefix == "" { + if len(srcRootPrefixes) == 0 { // For whatever reason, we didn't identify a good common prefix to use here. - return "", fmt.Errorf("unable to identify src prefix for %v with regex %s", srcs, srcRootRegex) + return nil, fmt.Errorf("unable to identify src prefix for %v with regex %s", srcs, srcRootRegex) } - return srcRootPrefix, nil + return srcRootPrefixes, nil } // SplitPackages splits a typical package structure into packages. @@ -742,14 +742,15 @@ func SplitPackages(srcs []string, srcRootPrefix string) map[string][]string { continue } - // In Go's sources, vendored packages under cmd/vendor are imported via - // paths not containing cmd/vendor. - pkg = strings.TrimPrefix(pkg, "cmd/vendor/") - - // Place the special runtime package (functions emitted by the - // compiler itself) into the runtime packages. if strings.Contains(filename, "cmd/compile/internal/typecheck/_builtin/runtime.go") { + // Place the special runtime package (functions emitted by the + // compiler itself) into the runtime packages. pkg = "runtime" + } else if strings.HasPrefix(pkg, "cmd") { + // Ignore packages in cmd, these are packages that are needed to build Go + // programs (like the Go tool or the compiler), but they are not part of + // the standard library and can't be in the set of transitive dependencies. + continue } // Add to the package. diff --git a/tools/nogo/cli/cli.go b/tools/nogo/cli/cli.go index 1298b2785..7f57e4f1f 100644 --- a/tools/nogo/cli/cli.go +++ b/tools/nogo/cli/cli.go @@ -234,18 +234,20 @@ func (b *Bundle) Execute(ctx context.Context, fs *flag.FlagSet, args ...any) sub // Perform the analysis. if err := b.execute(func() (check.FindingSet, facts.Serializer, error) { // Discover the correct common root. - srcRootPrefix, err := check.FindRoot(fs.Args(), b.Root) + srcRootPrefixes, err := check.FindRoots(fs.Args(), b.Root) if err != nil { return nil, nil, err } // Split into packages. sources := make(map[string][]string) - for pkg, srcs := range check.SplitPackages(fs.Args(), srcRootPrefix) { - path := pkg - if b.Prefix != "" { - path = b.Prefix + "/" + path // Subpackage. + for _, srcRootPrefix := range srcRootPrefixes { + for pkg, srcs := range check.SplitPackages(fs.Args(), srcRootPrefix) { + path := pkg + if b.Prefix != "" { + path = b.Prefix + "/" + path // Subpackage. + } + sources[path] = append(sources[path], srcs...) } - sources[path] = append(sources[path], srcs...) } return check.Bundle(sources) }); err != nil {