Skip to content

Commit c8fc4d4

Browse files
authored
Merge pull request #695 from k8s-infra-cherrypick-robot/cherry-pick-687-to-release-0.9
🏃 Simplify the LoadRootsWithConfig logic
2 parents 7c994fc + cd25c0b commit c8fc4d4

File tree

1 file changed

+42
-64
lines changed

1 file changed

+42
-64
lines changed

pkg/loader/loader.go

Lines changed: 42 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ func (l *loader) parseFile(filename string, src []byte) (*ast.File, error) {
323323
// populated. Additional information, like ASTs and type-checking information,
324324
// can be accessed via methods on individual packages.
325325
func LoadRoots(roots ...string) ([]*Package, error) {
326-
return LoadRootsWithConfig(nil, roots...)
326+
return LoadRootsWithConfig(&packages.Config{}, roots...)
327327
}
328328

329329
// LoadRootsWithConfig functions like LoadRoots, except that it allows passing
@@ -366,41 +366,30 @@ func LoadRoots(roots ...string) ([]*Package, error) {
366366
//
367367
// 5. Load the filesystem path roots and return the load packages for the
368368
// package/module roots AND the filesystem path roots.
369-
//
370-
//nolint:gocyclo
371-
func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Package, retErr error) {
369+
func LoadRootsWithConfig(cfg *packages.Config, roots ...string) ([]*Package, error) {
370+
l := &loader{
371+
cfg: cfg,
372+
packages: make(map[*packages.Package]*Package),
373+
}
374+
l.cfg.Mode |= packages.LoadImports | packages.NeedTypesSizes
375+
if l.cfg.Fset == nil {
376+
l.cfg.Fset = token.NewFileSet()
377+
}
378+
// put our build flags first so that callers can override them
379+
l.cfg.BuildFlags = append([]string{"-tags", "ignore_autogenerated"}, l.cfg.BuildFlags...)
380+
381+
// Visit the import graphs of the loaded, root packages. If an imported
382+
// package refers to another loaded, root package, then replace the
383+
// instance of the imported package with a reference to the loaded, root
384+
// package. This is required to make kubebuilder markers work correctly
385+
// when multiple root paths are loaded and types from one path reference
386+
// types from another root path.
372387
defer func() {
373-
if retErr != nil {
374-
return
375-
}
376-
for i := range result {
377-
visitImports(result, result[i], nil)
388+
for i := range l.Roots {
389+
visitImports(l.Roots, l.Roots[i], nil)
378390
}
379391
}()
380392

381-
newLoader := func(cfg *packages.Config, cfgDir string) *loader {
382-
if cfg == nil {
383-
cfg = &packages.Config{
384-
Dir: cfgDir,
385-
}
386-
}
387-
l := &loader{
388-
cfg: cfg,
389-
packages: map[*packages.Package]*Package{},
390-
}
391-
l.cfg.Mode |= packages.LoadImports | packages.NeedTypesSizes
392-
if l.cfg.Fset == nil {
393-
l.cfg.Fset = token.NewFileSet()
394-
}
395-
// put our build flags first so that callers can override them
396-
l.cfg.BuildFlags = append([]string{"-tags", "ignore_autogenerated"}, l.cfg.BuildFlags...)
397-
398-
return l
399-
}
400-
401-
// initialize the default loader
402-
l := newLoader(cfg, "")
403-
404393
// uniquePkgIDs is used to keep track of the discovered packages to be nice
405394
// and try and prevent packages from showing up twice when nested module
406395
// support is enabled. there is not harm that comes from this per se, but
@@ -412,7 +401,7 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Packa
412401
// if validatePkgFn is nil, a package will be returned in the slice,
413402
// otherwise the package is only returned if the result of
414403
// validatePkgFn(pkg.ID) is truthy
415-
loadPackages := func(l *loader, roots ...string) ([]*Package, error) {
404+
loadPackages := func(roots ...string) ([]*Package, error) {
416405
rawPkgs, err := packages.Load(l.cfg, roots...)
417406
if err != nil {
418407
return nil, err
@@ -430,11 +419,12 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Packa
430419

431420
// if no roots were provided then load the current package and return early
432421
if len(roots) == 0 {
433-
pkgs, err := loadPackages(l)
422+
pkgs, err := loadPackages()
434423
if err != nil {
435424
return nil, err
436425
}
437-
return pkgs, nil
426+
l.Roots = append(l.Roots, pkgs...)
427+
return l.Roots, nil
438428
}
439429

440430
// pkgRoots is a slice of roots that are package/modules and fspRoots
@@ -460,39 +450,34 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Packa
460450
// system path roots due to them needing a custom, calculated value for the
461451
// cfg.Dir field
462452
if len(pkgRoots) > 0 {
463-
pkgs, err := loadPackages(l, pkgRoots...)
453+
pkgs, err := loadPackages(pkgRoots...)
464454
if err != nil {
465455
return nil, err
466456
}
467-
result = append(result, pkgs...)
457+
l.Roots = append(l.Roots, pkgs...)
468458
}
469459

470460
// if there are no filesystem path roots then go ahead and return early
471461
if len(fspRoots) == 0 {
472-
return result, nil
462+
return l.Roots, nil
473463
}
474464

475465
//
476466
// at this point we are handling filesystem path roots
477467
//
478468

479-
// store the value of cfg.Dir so we can use it later if it is non-empty.
480-
// we need to store it now as the value of cfg.Dir will be updated by
481-
// a loop below
482-
var cfgDir string
483-
if cfg != nil {
484-
cfgDir = cfg.Dir
485-
}
486-
487469
// ensure the cfg.Dir field is reset to its original value upon
488470
// returning from this function. it should honestly be fine if it is
489471
// not given most callers will not send in the cfg parameter directly,
490472
// as it's largely for testing, but still, let's be good stewards.
491473
defer func(d string) {
492-
if cfg != nil {
493-
cfg.Dir = d
494-
}
495-
}(cfgDir)
474+
cfg.Dir = d
475+
}(cfg.Dir)
476+
477+
// store the value of cfg.Dir so we can use it later if it is non-empty.
478+
// we need to store it now as the value of cfg.Dir will be updated by
479+
// a loop below
480+
cfgDir := cfg.Dir
496481

497482
// addNestedGoModulesToRoots is given to filepath.WalkDir and adds the
498483
// directory part of p to the list of filesystem path roots IFF p is the
@@ -591,16 +576,9 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Packa
591576
b = "."
592577
}
593578

594-
// create the loader for this filesystem path. this is required in order
595-
// to properly load the files as AST later in various workflows,
596-
// including CRD generation
597-
var fspLoader *loader
598-
if cfg == nil {
599-
fspLoader = newLoader(nil, d)
600-
} else {
601-
fspLoader = l
602-
fspLoader.cfg.Dir = d
603-
}
579+
// update the loader configuration's Dir field to the directory part of
580+
// the root
581+
l.cfg.Dir = d
604582

605583
// update the root to be "./..." or "./."
606584
// (with OS-specific filepath separator). please note filepath.Join
@@ -609,14 +587,14 @@ func LoadRootsWithConfig(cfg *packages.Config, roots ...string) (result []*Packa
609587
r = fmt.Sprintf(".%s%s", string(filepath.Separator), b)
610588

611589
// load the packages from the roots
612-
pkgs, err := loadPackages(fspLoader, r)
590+
pkgs, err := loadPackages(r)
613591
if err != nil {
614592
return nil, err
615593
}
616-
result = append(result, pkgs...)
594+
l.Roots = append(l.Roots, pkgs...)
617595
}
618596

619-
return result, nil
597+
return l.Roots, nil
620598
}
621599

622600
// visitImports walks a dependency graph, replacing imported package
@@ -634,8 +612,8 @@ func visitImports(rootPkgs []*Package, pkg *Package, seen sets.String) {
634612
}
635613
}
636614
if !seen.Has(importedPkgID) {
637-
visitImports(rootPkgs, importedPkg, seen)
638615
seen.Insert(importedPkgID)
616+
visitImports(rootPkgs, importedPkg, seen)
639617
}
640618
}
641619
}

0 commit comments

Comments
 (0)