diff --git a/pkg/config/config.go b/pkg/config/config.go index 66a3b72b..5b7a753c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -6,7 +6,6 @@ import ( "errors" "fmt" "os" - "path/filepath" "reflect" "regexp" "strings" @@ -542,128 +541,28 @@ func shouldExcludeModule(ctx context.Context, root *pathlib.Path, goModPath *pat return false, nil } -func (c *Config) subPackages( - ctx context.Context, - pkgPath string, - pkgConfig *Config, - currentDepth int, -) ([]string, error) { +func (c *Config) subPackages(ctx context.Context, pkgPath string) ([]string, error) { log := zerolog.Ctx(ctx) - pkgs, err := packages.Load(&packages.Config{ Mode: packages.NeedName | packages.NeedFiles, - }, pkgPath) + }, pkgPath+"...") if err != nil { return nil, fmt.Errorf("failed to load packages: %w", err) } - pkg := pkgs[0] - - if currentDepth == 0 && len(pkg.GoFiles) == 0 { - log.Error(). - Err(ErrNoGoFilesFoundInRoot). - Str("documentation", logging.DocsURL("/notes/#error-no-go-files-found-in-root-search-path")). - Msg("package contains no go files") - return nil, ErrNoGoFilesFoundInRoot - } - representativeFile := pathlib.NewPath(pkg.GoFiles[0]) - searchRoot := representativeFile.Parent() - packageRootName := pathlib.NewPath(pkg.PkgPath) - packageRootPath := searchRoot - subPackages := []string{} - - walker, err := pathlib.NewWalk( - searchRoot, - pathlib.WalkAlgorithm(pathlib.AlgorithmPreOrderDepthFirst), - pathlib.WalkFollowSymlinks(false), - pathlib.WalkVisitDirs(false), - pathlib.WalkVisitFiles(true), - ) - if err != nil { - return nil, fmt.Errorf("failed to create filesystem walker: %w", err) - } - - visitedDirs := map[string]any{} - subdirectoriesWithGoFiles := []*pathlib.Path{} - - // We consider the searchRoot to already be visited because - // we know it's already in the configuration. - visitedDirs[searchRoot.String()] = nil - // Walk the filesystem path, starting at the root of the package we've - // been given. Note that this will always work because Go downloads - // the package when we call `packages.Load` - walkErr := walker.Walk(func(path *pathlib.Path, info os.FileInfo, err error) error { - pathLog := log.With().Stringer("path", path).Logger() - if err != nil { - return err - } - if path.Name() == "go.mod" { - pathLog.Debug().Msg("path contains go.mod file") - // Check if our current depth is 0. We do this to skip sub-modules, but not - // the root module. - shouldExclude, err := shouldExcludeModule(ctx, searchRoot, path) - if err != nil { - return err - } - - if shouldExclude { - return pathlib.ErrWalkSkipSubtree - } - } - - _, haveVisitedDir := visitedDirs[path.Parent().String()] - if !haveVisitedDir && strings.HasSuffix(path.Name(), ".go") { - - if !c.IncludeAutoGenerated { - autoGenerated, err := isAutoGenerated(path) - if err != nil { - pathLog.Err(err).Msg("failed to determine if file is auto-generated") - return err - } - if autoGenerated { - pathLog.Debug().Msg("skipping file as auto-generated") - return nil - } - } - - pathLog.Debug().Msg("subdirectory has a .go file") - goModPath := path.Parent().Join("go.mod") - goModExists, err := goModPath.Exists() - if err != nil { - pathLog.Err(err).Msg("failed to determine if go.mod exists") - return err - } - if goModExists { - shouldExclude, err := shouldExcludeModule(ctx, searchRoot, goModPath) - if err != nil { - return err - } - if shouldExclude { - return pathlib.ErrWalkSkipSubtree - } + convertPkgPath := func(pkgs []*packages.Package) []string { + paths := make([]string, 0, len(pkgs)) + for _, pkg := range pkgs { + log.Info().Any("pkg", pkg).Any("module", pkg.Module).Msg("iterating over package") + if len(pkg.GoFiles) == 0 { + continue } - subdirectoriesWithGoFiles = append(subdirectoriesWithGoFiles, path.Parent()) - visitedDirs[path.Parent().String()] = nil - } - return nil - }) - if walkErr != nil { - return nil, fmt.Errorf("error occurred during filesystem walk: %w", walkErr) - } - - // Parse the subdirectories we found into their respective fully qualified - // package paths - for _, d := range subdirectoriesWithGoFiles { - relativeFilesystemPath, err := d.RelativeTo(packageRootPath) - if err != nil { - log.Err(err).Stringer("root", packageRootPath).Stringer("subRoot", d).Msg("failed to make subroot relative to root") - return nil, fmt.Errorf("failed to make subroot relative to root: %w", err) + paths = append(paths, pkg.PkgPath) } - absolutePackageName := packageRootName.Join(relativeFilesystemPath.Parts()...) - subPackages = append(subPackages, filepath.ToSlash(absolutePackageName.String())) + return paths } - return subPackages, nil + return convertPkgPath(pkgs), nil } // discoverRecursivePackages parses the provided config for packages marked as @@ -697,7 +596,7 @@ func (c *Config) discoverRecursivePackages(ctx context.Context) error { pkgLog := log.With().Str("package-path", pkgPath).Logger() pkgCtx := pkgLog.WithContext(ctx) pkgLog.Debug().Msg("discovering sub-packages") - subPkgs, err := c.subPackages(pkgCtx, pkgPath, conf, 0) + subPkgs, err := c.subPackages(ctx, pkgPath) if err != nil { return fmt.Errorf("failed to get subpackages: %w", err) } diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 03f13fc5..9001a920 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -1012,7 +1012,7 @@ packages: config: recursive: True all: True`, - wantErr: ErrNoGoFilesFoundInRoot, + wantErr: nil, }, { name: "test with no subpackages present", diff --git a/pkg/parse.go b/pkg/parse.go index b1aec475..81ad0b44 100644 --- a/pkg/parse.go +++ b/pkg/parse.go @@ -93,6 +93,9 @@ func (p *Parser) ParsePackages(ctx context.Context, packageNames []string) error return err } for _, pkg := range packages { + if len(pkg.GoFiles) == 0 { + continue + } for _, err := range pkg.Errors { log.Err(err).Msg("encountered error when loading package") }