@@ -466,71 +466,95 @@ func (a *App) DeclaredTopLevelVars() map[string]interface{} {
466466 return ret
467467}
468468
469- // loadComponents loads metadata for all components for the app.
470- // The data is returned as a map keyed by component name. It does _not_ recurse
471- // into subdirectories.
469+ // loadComponents loads metadata for all components for the app. It first expands the components directory
470+ // for glob patterns and loads components from all directories that match. It does _not_ recurse
471+ // into subdirectories. The data is returned as a map keyed by component name.
472+ // Note that component names must be unique across all directories. Support for multiple directories is just a
473+ // way to partition classes of components and does not introduce any namespace semantics.
472474func (a * App ) loadComponents () (map [string ]Component , error ) {
473475 var list []Component
474- dir := strings .TrimSuffix (filepath .Clean (a .inner .Spec .ComponentsDir ), "/" )
475- err := filepath .Walk (dir , func (path string , info os.FileInfo , err error ) error {
476- if err != nil {
477- return err
478- }
479- if path == dir {
480- return nil
481- }
482- if info .IsDir () {
483- files , err := filepath .Glob (filepath .Join (path , "*" ))
476+ loadDirComponents := func (dir string ) error {
477+ err := filepath .Walk (dir , func (path string , info os.FileInfo , err error ) error {
484478 if err != nil {
485479 return err
486480 }
487- var staticFiles [] string
488- hasIndexJsonnet := false
489- hasIndexYAML := false
490- for _ , f := range files {
491- stat , err := os . Stat ( f )
481+ if path == dir {
482+ return nil
483+ }
484+ if info . IsDir () {
485+ files , err := filepath . Glob ( filepath . Join ( path , "*" ) )
492486 if err != nil {
493487 return err
494488 }
495- if stat .IsDir () {
496- continue
489+ var staticFiles []string
490+ hasIndexJsonnet := false
491+ hasIndexYAML := false
492+ for _ , f := range files {
493+ stat , err := os .Stat (f )
494+ if err != nil {
495+ return err
496+ }
497+ if stat .IsDir () {
498+ continue
499+ }
500+ switch filepath .Base (f ) {
501+ case "index.jsonnet" :
502+ hasIndexJsonnet = true
503+ case "index.yaml" :
504+ hasIndexYAML = true
505+ }
506+ if strings .HasSuffix (f , ".json" ) || strings .HasSuffix (f , ".yaml" ) {
507+ staticFiles = append (staticFiles , f )
508+ }
497509 }
498- switch filepath .Base (f ) {
499- case "index.jsonnet" :
500- hasIndexJsonnet = true
501- case "index.yaml" :
502- hasIndexYAML = true
503- }
504- if strings .HasSuffix (f , ".json" ) || strings .HasSuffix (f , ".yaml" ) {
505- staticFiles = append (staticFiles , f )
510+ switch {
511+ case hasIndexJsonnet :
512+ list = append (list , Component {
513+ Name : filepath .Base (path ),
514+ Files : []string {filepath .Join (path , "index.jsonnet" )},
515+ })
516+ case hasIndexYAML :
517+ list = append (list , Component {
518+ Name : filepath .Base (path ),
519+ Files : staticFiles ,
520+ })
506521 }
522+ return filepath .SkipDir
507523 }
508- switch {
509- case hasIndexJsonnet :
510- list = append (list , Component {
511- Name : filepath .Base (path ),
512- Files : []string {filepath .Join (path , "index.jsonnet" )},
513- })
514- case hasIndexYAML :
524+ extension := filepath .Ext (path )
525+ if supportedExtensions [extension ] {
515526 list = append (list , Component {
516- Name : filepath .Base (path ),
517- Files : staticFiles ,
527+ Name : strings . TrimSuffix ( filepath .Base (path ), extension ),
528+ Files : [] string { path } ,
518529 })
519530 }
520- return filepath .SkipDir
521- }
522- extension := filepath .Ext (path )
523- if supportedExtensions [extension ] {
524- list = append (list , Component {
525- Name : strings .TrimSuffix (filepath .Base (path ), extension ),
526- Files : []string {path },
527- })
528- }
529- return nil
530- })
531+ return nil
532+ })
533+ return err
534+ }
535+ ds , err := filepath .Glob (a .inner .Spec .ComponentsDir )
531536 if err != nil {
532537 return nil , err
533538 }
539+ var dirs []string
540+ for _ , d := range ds {
541+ s , err := os .Stat (d )
542+ if err != nil {
543+ return nil , err
544+ }
545+ if s .IsDir () {
546+ dirs = append (dirs , d )
547+ }
548+ }
549+ if len (dirs ) == 0 {
550+ return nil , fmt .Errorf ("no component directories found after expanding %s" , a .inner .Spec .ComponentsDir )
551+ }
552+ for _ , d := range dirs {
553+ err := loadDirComponents (d )
554+ if err != nil {
555+ return nil , err
556+ }
557+ }
534558 m := make (map [string ]Component , len (list ))
535559 for _ , c := range list {
536560 if old , ok := m [c .Name ]; ok {
0 commit comments