From cfa3a3652da36727e11e593e2a3ababec82d2522 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 00:24:04 +0530 Subject: [PATCH 01/10] feat(walker): implement recursive directory walking with max depth Signed-off-by: ShigrafS --- utils/walker/git.go | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/utils/walker/git.go b/utils/walker/git.go index 59687a92..247487ac 100644 --- a/utils/walker/git.go +++ b/utils/walker/git.go @@ -29,6 +29,7 @@ type Git struct { fileInterceptor FileInterceptor dirInterceptor DirInterceptor referenceName plumbing.ReferenceName + maxDepth int } // NewGit returns a pointer to an instance of Git @@ -66,6 +67,11 @@ func (g *Git) MaxFileSize(size int64) *Git { return g } +func (g *Git) MaxDepth(depth int) *Git { + g.maxDepth = depth + return g +} + // ShowLogs enable the logs and returns a pointer // to the same Git instance func (g *Git) ShowLogs() *Git { @@ -183,14 +189,22 @@ func clonewalk(g *Git) error { } // If recurse mode is on, we will walk the tree if g.recurse { + pathSep := string(os.PathSeparator) + rootDepth := strings.Count(rootPath, pathSep) err = filepath.WalkDir(rootPath, func(path string, d fs.DirEntry, er error) error { - if d.IsDir() && g.dirInterceptor != nil { - return g.dirInterceptor(Directory{ - Name: d.Name(), - Path: path, - }) - } if d.IsDir() { + if g.dirInterceptor != nil { + return g.dirInterceptor(Directory{ + Name: d.Name(), + Path: path, + }) + } + if g.maxDepth > 0 { + currentDepth := strings.Count(path, pathSep) - rootDepth + if currentDepth >= g.maxDepth { + return filepath.SkipDir + } + } return nil } f, errInfo := d.Info() From b44792cb12159db1c34816e3e534c1e7087fdb32 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 00:24:10 +0530 Subject: [PATCH 02/10] feat(github): support recursive component generation in git repo Signed-off-by: ShigrafS --- generators/github/git_repo.go | 13 +++++++++++++ generators/github/package_manager.go | 4 +++- generators/github/scheme_interface.go | 8 +++++--- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/generators/github/git_repo.go b/generators/github/git_repo.go index a57c6217..74cd5df1 100644 --- a/generators/github/git_repo.go +++ b/generators/github/git_repo.go @@ -18,6 +18,8 @@ type GitRepo struct { // URL *url.URL PackageName string + Recursive bool + MaxDepth int } // Assumpations: 1. Always a K8s manifest @@ -55,9 +57,20 @@ func (gr GitRepo) GetContent() (models.Package, error) { Repo(repo). Branch(branch). Root(root). + MaxDepth(gr.MaxDepth). RegisterFileInterceptor(fileInterceptor(br)). RegisterDirInterceptor(dirInterceptor(br)) + if gr.Recursive { + if !strings.HasSuffix(root, "/**") { + gw = gw.Root(root + "/**") + } + } else { + if strings.HasSuffix(root, "/**") { + gw = gw.Root(strings.TrimSuffix(root, "/**")) + } + } + if version != "" { gw = gw.ReferenceName(fmt.Sprintf("refs/tags/%s", version)) } diff --git a/generators/github/package_manager.go b/generators/github/package_manager.go index df79bcae..b4c5a63c 100644 --- a/generators/github/package_manager.go +++ b/generators/github/package_manager.go @@ -11,6 +11,8 @@ import ( type GitHubPackageManager struct { PackageName string SourceURL string + Recursive bool + MaxDepth int } func (ghpm GitHubPackageManager) GetPackage() (models.Package, error) { @@ -21,7 +23,7 @@ func (ghpm GitHubPackageManager) GetPackage() (models.Package, error) { } protocol := url.Scheme - downloader := NewDownloaderForScheme(protocol, url, ghpm.PackageName) + downloader := NewDownloaderForScheme(protocol, url, ghpm) if downloader == nil { err = errors.New("unsupported protocol") return nil, ErrGenerateGitHubPackage(err, ghpm.PackageName) diff --git a/generators/github/scheme_interface.go b/generators/github/scheme_interface.go index cda361e7..c1c6d82e 100644 --- a/generators/github/scheme_interface.go +++ b/generators/github/scheme_interface.go @@ -10,19 +10,21 @@ type DownloaderScheme interface { GetContent() (models.Package, error) } -func NewDownloaderForScheme(scheme string, url *url.URL, packageName string) DownloaderScheme { +func NewDownloaderForScheme(scheme string, url *url.URL, gp GitHubPackageManager) DownloaderScheme { switch scheme { case "git": return GitRepo{ URL: url, - PackageName: packageName, + PackageName: gp.PackageName, + Recursive: gp.Recursive, + MaxDepth: gp.MaxDepth, } case "http": fallthrough case "https": return URL{ URL: url, - PackageName: packageName, + PackageName: gp.PackageName, } } return nil From 4d16898d38eb19a834772564e0353a37cb8b5ff2 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 00:24:15 +0530 Subject: [PATCH 03/10] feat(generators): add NewGeneratorWithOptions for recursion control Signed-off-by: ShigrafS --- generators/generator.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/generators/generator.go b/generators/generator.go index cbf4fe1a..f6594c63 100644 --- a/generators/generator.go +++ b/generators/generator.go @@ -14,7 +14,16 @@ const ( gitHub = "github" ) +type GeneratorOptions struct { + Recursive bool + MaxDepth int +} + func NewGenerator(registrant, url, packageName string) (models.PackageManager, error) { + return NewGeneratorWithOptions(registrant, url, packageName, GeneratorOptions{}) +} + +func NewGeneratorWithOptions(registrant, url, packageName string, opts GeneratorOptions) (models.PackageManager, error) { registrant = utils.ReplaceSpacesAndConvertToLowercase(registrant) switch registrant { case artifactHub: @@ -26,6 +35,8 @@ func NewGenerator(registrant, url, packageName string) (models.PackageManager, e return github.GitHubPackageManager{ PackageName: packageName, SourceURL: url, + Recursive: opts.Recursive, + MaxDepth: opts.MaxDepth, }, nil } return nil, ErrUnsupportedRegistrant(fmt.Errorf("generator not implemented for the registrant %s", registrant)) From 0518bfdfd3de3d7ed3bfb12534abe04bbc31db67 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 00:24:28 +0530 Subject: [PATCH 04/10] test(generators): verify generator options passing Signed-off-by: ShigrafS --- generators/generator_test.go | 64 +++++++++++++++++++++++++++++ generators/github/recursive_test.go | 36 ++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 generators/generator_test.go create mode 100644 generators/github/recursive_test.go diff --git a/generators/generator_test.go b/generators/generator_test.go new file mode 100644 index 00000000..ba446223 --- /dev/null +++ b/generators/generator_test.go @@ -0,0 +1,64 @@ +package generators + +import ( + "testing" + + "github.com/meshery/meshkit/generators/github" +) + +func TestNewGeneratorWithOptions(t *testing.T) { + tests := []struct { + name string + registrant string + url string + packageName string + opts GeneratorOptions + wantRec bool + wantDepth int + }{ + { + name: "Github Recursive", + registrant: "github", + url: "https://github.com/owner/repo", + packageName: "test", + opts: GeneratorOptions{ + Recursive: true, + MaxDepth: 5, + }, + wantRec: true, + wantDepth: 5, + }, + { + name: "Github Default", + registrant: "github", + url: "https://github.com/owner/repo", + packageName: "test", + opts: GeneratorOptions{ + Recursive: false, + MaxDepth: 0, + }, + wantRec: false, + wantDepth: 0, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pm, err := NewGeneratorWithOptions(tt.registrant, tt.url, tt.packageName, tt.opts) + if err != nil { + t.Fatalf("NewGeneratorWithOptions() error = %v", err) + } + + if ghpm, ok := pm.(github.GitHubPackageManager); ok { + if ghpm.Recursive != tt.wantRec { + t.Errorf("NewGeneratorWithOptions() Recursive = %v, want %v", ghpm.Recursive, tt.wantRec) + } + if ghpm.MaxDepth != tt.wantDepth { + t.Errorf("NewGeneratorWithOptions() MaxDepth = %v, want %v", ghpm.MaxDepth, tt.wantDepth) + } + } else { + t.Errorf("NewGeneratorWithOptions() returned unexpected type") + } + }) + } +} diff --git a/generators/github/recursive_test.go b/generators/github/recursive_test.go new file mode 100644 index 00000000..0028eaac --- /dev/null +++ b/generators/github/recursive_test.go @@ -0,0 +1,36 @@ +package github + +import ( + "net/url" + "testing" +) + +func TestRecursiveWalk(t *testing.T) { + gr := GitRepo{ + URL: &url.URL{Path: "/owner/repo/branch/root"}, + Recursive: true, + MaxDepth: 2, + PackageName: "test-package", + } + + if !gr.Recursive { + t.Error("GitRepo.Recursive should be true") + } + if gr.MaxDepth != 2 { + t.Errorf("GitRepo.MaxDepth should be 2, got %d", gr.MaxDepth) + } + + ghpm := GitHubPackageManager{ + PackageName: "test", + SourceURL: "https://github.com/owner/repo", + Recursive: true, + MaxDepth: 3, + } + + if !ghpm.Recursive { + t.Error("GitHubPackageManager.Recursive should be true") + } + if ghpm.MaxDepth != 3 { + t.Errorf("GitHubPackageManager.MaxDepth should be 3, got %d", ghpm.MaxDepth) + } +} From bff153f208d0f2a7f0f7e76a62a17ab1ecefc31a Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 14:19:52 +0530 Subject: [PATCH 05/10] fix(github): fix infinite recursion bug in git repo walker Signed-off-by: ShigrafS # Conflicts: # generators/github/git_repo.go --- generators/github/git_repo.go | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/generators/github/git_repo.go b/generators/github/git_repo.go index 74cd5df1..8025e6f4 100644 --- a/generators/github/git_repo.go +++ b/generators/github/git_repo.go @@ -56,20 +56,21 @@ func (gr GitRepo) GetContent() (models.Package, error) { Owner(owner). Repo(repo). Branch(branch). - Root(root). MaxDepth(gr.MaxDepth). RegisterFileInterceptor(fileInterceptor(br)). RegisterDirInterceptor(dirInterceptor(br)) + effectiveRoot := root if gr.Recursive { - if !strings.HasSuffix(root, "/**") { - gw = gw.Root(root + "/**") + if !strings.HasSuffix(effectiveRoot, "/**") { + effectiveRoot += "/**" } } else { - if strings.HasSuffix(root, "/**") { - gw = gw.Root(strings.TrimSuffix(root, "/**")) + if strings.HasSuffix(effectiveRoot, "/**") { + effectiveRoot = strings.TrimSuffix(effectiveRoot, "/**") } } + gw = gw.Root(effectiveRoot) if version != "" { gw = gw.ReferenceName(fmt.Sprintf("refs/tags/%s", version)) From 94454566e1792db9b26db0a23ae05f8413d07b27 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 14:19:57 +0530 Subject: [PATCH 06/10] fix(walker): fix off-by-one error in max depth logic Signed-off-by: ShigrafS --- utils/walker/git.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/walker/git.go b/utils/walker/git.go index 247487ac..095bbaa2 100644 --- a/utils/walker/git.go +++ b/utils/walker/git.go @@ -201,7 +201,7 @@ func clonewalk(g *Git) error { } if g.maxDepth > 0 { currentDepth := strings.Count(path, pathSep) - rootDepth - if currentDepth >= g.maxDepth { + if currentDepth > g.maxDepth { return filepath.SkipDir } } From 99978280eabfe80098fbce697bc7e3a0b0063265 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 2 Feb 2026 14:20:05 +0530 Subject: [PATCH 07/10] test(github): add functional recursive walk test Signed-off-by: ShigrafS # Conflicts: # generators/github/recursive_test.go --- generators/github/recursive_test.go | 157 ++++++++++++++++++++++++---- 1 file changed, 137 insertions(+), 20 deletions(-) diff --git a/generators/github/recursive_test.go b/generators/github/recursive_test.go index 0028eaac..18ecf9b2 100644 --- a/generators/github/recursive_test.go +++ b/generators/github/recursive_test.go @@ -1,36 +1,153 @@ package github import ( - "net/url" + "io/ioutil" + "os" + "path/filepath" + "strings" "testing" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/meshery/meshkit/utils/walker" ) -func TestRecursiveWalk(t *testing.T) { - gr := GitRepo{ - URL: &url.URL{Path: "/owner/repo/branch/root"}, - Recursive: true, - MaxDepth: 2, - PackageName: "test-package", +func TestRecursiveWalkFunctional(t *testing.T) { + tempDir, err := ioutil.TempDir("", "test-recursive-walk") + if err != nil { + t.Fatalf("Failed to create temp dir: %v", err) + } + defer os.RemoveAll(tempDir) + + r, err := git.PlainInit(tempDir, false) + if err != nil { + t.Fatalf("Failed to init git repo: %v", err) } + w, err := r.Worktree() + if err != nil { + t.Fatalf("Failed to get worktree: %v", err) + } + + createFile(t, tempDir, "root.yaml", "content") + createFile(t, tempDir, "level1/level1.yaml", "content") + createFile(t, tempDir, "level1/level2/level2.yaml", "content") - if !gr.Recursive { - t.Error("GitRepo.Recursive should be true") + _, err = w.Add(".") + if err != nil { + t.Fatalf("Failed to add files: %v", err) } - if gr.MaxDepth != 2 { - t.Errorf("GitRepo.MaxDepth should be 2, got %d", gr.MaxDepth) + _, err = w.Commit("Initial commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "Test", + Email: "test@example.com", + When: time.Now(), + }, + }) + if err != nil { + t.Fatalf("Failed to commit: %v", err) } - ghpm := GitHubPackageManager{ - PackageName: "test", - SourceURL: "https://github.com/owner/repo", - Recursive: true, - MaxDepth: 3, + tests := []struct { + name string + recursive bool + maxDepth int + wantFiles []string + }{ + { + name: "Non-recursive (Root only)", + recursive: false, + maxDepth: 0, + wantFiles: []string{"root.yaml"}, + }, + { + name: "Recursive Unlimited", + recursive: true, + maxDepth: 0, + wantFiles: []string{"root.yaml", "level1.yaml", "level2.yaml"}, + }, + { + name: "Recursive MaxDepth 1", + recursive: true, + maxDepth: 1, + wantFiles: []string{"root.yaml", "level1.yaml"}, + }, + { + name: "Recursive MaxDepth 2", + recursive: true, + maxDepth: 2, + wantFiles: []string{"root.yaml", "level1.yaml", "level2.yaml"}, + }, } - if !ghpm.Recursive { - t.Error("GitHubPackageManager.Recursive should be true") + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + repoPath := filepath.ToSlash(tempDir) + if !strings.HasPrefix(repoPath, "/") { + repoPath = "/" + repoPath + } + fileURL := "file://" + repoPath + + walkerInst := walker.NewGit(). + Owner(""). + Repo(""). + BaseURL(fileURL). + Branch("master"). + Root(""). + MaxDepth(tt.maxDepth) + + var collectedFiles []string + walkerInst.RegisterFileInterceptor(func(f walker.File) error { + collectedFiles = append(collectedFiles, f.Name) + return nil + }) + + if tt.recursive { + walkerInst.Root("/**") + } else { + walkerInst.Root("") + } + + err := walkerInst.Walk() + if err != nil { + t.Fatalf("Walk failed: %v", err) + } + + assertFilesEqual(t, collectedFiles, tt.wantFiles) + }) + } +} + +func assertFilesEqual(t *testing.T, got, want []string) { + gotMap := make(map[string]struct{}) + for _, f := range got { + gotMap[f] = struct{}{} + } + for _, f := range want { + if _, ok := gotMap[f]; !ok { + t.Errorf("missing expected file: %s", f) + } else { + delete(gotMap, f) + } + } + if len(gotMap) > 0 { + for f := range gotMap { + t.Errorf("unexpected file collected: %s", f) + } + } + if len(got) != len(want) { + t.Errorf("got %d files, want %d", len(got), len(want)) + } +} + +func createFile(t *testing.T, base, path, content string) { + fullPath := filepath.Join(base, path) + err := os.MkdirAll(filepath.Dir(fullPath), 0755) + if err != nil { + t.Fatalf("Failed to create dirs: %v", err) } - if ghpm.MaxDepth != 3 { - t.Errorf("GitHubPackageManager.MaxDepth should be 3, got %d", ghpm.MaxDepth) + err = ioutil.WriteFile(fullPath, []byte(content), 0644) + if err != nil { + t.Fatalf("Failed to create file: %v", err) } } From 349668976f0f631db81dd23392d414a13648e992 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 16 Feb 2026 13:59:14 +0530 Subject: [PATCH 08/10] feat(walker): implement file pattern filtering and fix depth logic Signed-off-by: ShigrafS --- utils/walker/git.go | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/utils/walker/git.go b/utils/walker/git.go index 095bbaa2..f6c3ed21 100644 --- a/utils/walker/git.go +++ b/utils/walker/git.go @@ -30,6 +30,7 @@ type Git struct { dirInterceptor DirInterceptor referenceName plumbing.ReferenceName maxDepth int + allowedExtensions []string } // NewGit returns a pointer to an instance of Git @@ -72,6 +73,25 @@ func (g *Git) MaxDepth(depth int) *Git { return g } +func (g *Git) AllowedExtensions(ext []string) *Git { + g.allowedExtensions = ext + return g +} + +func (g *Git) isAllowedFile(name string) bool { + if len(g.allowedExtensions) == 0 { + return true // no filtering + } + + ext := strings.ToLower(filepath.Ext(name)) + for _, allowed := range g.allowedExtensions { + if ext == allowed { + return true + } + } + return false +} + // ShowLogs enable the logs and returns a pointer // to the same Git instance func (g *Git) ShowLogs() *Git { @@ -189,22 +209,30 @@ func clonewalk(g *Git) error { } // If recurse mode is on, we will walk the tree if g.recurse { - pathSep := string(os.PathSeparator) - rootDepth := strings.Count(rootPath, pathSep) err = filepath.WalkDir(rootPath, func(path string, d fs.DirEntry, er error) error { if d.IsDir() { + if d.Name() == ".git" { + return filepath.SkipDir + } + if g.maxDepth > 0 { + rel, err := filepath.Rel(rootPath, path) + if err == nil && rel != "." { + currentDepth := strings.Count(rel, string(os.PathSeparator)) + 1 + if currentDepth > g.maxDepth { + return filepath.SkipDir + } + } + } + if g.dirInterceptor != nil { return g.dirInterceptor(Directory{ Name: d.Name(), Path: path, }) } - if g.maxDepth > 0 { - currentDepth := strings.Count(path, pathSep) - rootDepth - if currentDepth > g.maxDepth { - return filepath.SkipDir - } - } + return nil + } + if !g.isAllowedFile(d.Name()) { return nil } f, errInfo := d.Info() From 1ead4cdc35fb1f25ca508f5c815452d4d1664c65 Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 16 Feb 2026 13:59:22 +0530 Subject: [PATCH 09/10] feat(generators): propagate file extensions to walker Signed-off-by: ShigrafS --- generators/generator.go | 6 ++++-- generators/github/git_repo.go | 2 ++ generators/github/package_manager.go | 1 + generators/github/scheme_interface.go | 1 + 4 files changed, 8 insertions(+), 2 deletions(-) diff --git a/generators/generator.go b/generators/generator.go index f6594c63..4ce4ac9f 100644 --- a/generators/generator.go +++ b/generators/generator.go @@ -15,8 +15,9 @@ const ( ) type GeneratorOptions struct { - Recursive bool - MaxDepth int + Recursive bool + MaxDepth int + Extensions []string } func NewGenerator(registrant, url, packageName string) (models.PackageManager, error) { @@ -37,6 +38,7 @@ func NewGeneratorWithOptions(registrant, url, packageName string, opts Generator SourceURL: url, Recursive: opts.Recursive, MaxDepth: opts.MaxDepth, + Extensions: opts.Extensions, }, nil } return nil, ErrUnsupportedRegistrant(fmt.Errorf("generator not implemented for the registrant %s", registrant)) diff --git a/generators/github/git_repo.go b/generators/github/git_repo.go index 8025e6f4..b34864dd 100644 --- a/generators/github/git_repo.go +++ b/generators/github/git_repo.go @@ -20,6 +20,7 @@ type GitRepo struct { PackageName string Recursive bool MaxDepth int + Extensions []string } // Assumpations: 1. Always a K8s manifest @@ -57,6 +58,7 @@ func (gr GitRepo) GetContent() (models.Package, error) { Repo(repo). Branch(branch). MaxDepth(gr.MaxDepth). + AllowedExtensions(gr.Extensions). RegisterFileInterceptor(fileInterceptor(br)). RegisterDirInterceptor(dirInterceptor(br)) diff --git a/generators/github/package_manager.go b/generators/github/package_manager.go index b4c5a63c..1de97800 100644 --- a/generators/github/package_manager.go +++ b/generators/github/package_manager.go @@ -13,6 +13,7 @@ type GitHubPackageManager struct { SourceURL string Recursive bool MaxDepth int + Extensions []string } func (ghpm GitHubPackageManager) GetPackage() (models.Package, error) { diff --git a/generators/github/scheme_interface.go b/generators/github/scheme_interface.go index c1c6d82e..382c3196 100644 --- a/generators/github/scheme_interface.go +++ b/generators/github/scheme_interface.go @@ -18,6 +18,7 @@ func NewDownloaderForScheme(scheme string, url *url.URL, gp GitHubPackageManager PackageName: gp.PackageName, Recursive: gp.Recursive, MaxDepth: gp.MaxDepth, + Extensions: gp.Extensions, } case "http": fallthrough From 35beb6729920e97619dbfbfb2a9da5ae7e06cb3e Mon Sep 17 00:00:00 2001 From: ShigrafS Date: Mon, 16 Feb 2026 13:59:30 +0530 Subject: [PATCH 10/10] test(github): add tests for file filtering and depth Signed-off-by: ShigrafS --- generators/github/recursive_test.go | 79 ++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 23 deletions(-) diff --git a/generators/github/recursive_test.go b/generators/github/recursive_test.go index 18ecf9b2..bf2adc0c 100644 --- a/generators/github/recursive_test.go +++ b/generators/github/recursive_test.go @@ -30,7 +30,9 @@ func TestRecursiveWalkFunctional(t *testing.T) { } createFile(t, tempDir, "root.yaml", "content") + createFile(t, tempDir, "root.json", "content") createFile(t, tempDir, "level1/level1.yaml", "content") + createFile(t, tempDir, "level1/level1.txt", "content") createFile(t, tempDir, "level1/level2/level2.yaml", "content") _, err = w.Add(".") @@ -49,34 +51,60 @@ func TestRecursiveWalkFunctional(t *testing.T) { } tests := []struct { - name string - recursive bool - maxDepth int - wantFiles []string + name string + recursive bool + maxDepth int + extensions []string + wantFiles []string }{ { - name: "Non-recursive (Root only)", - recursive: false, - maxDepth: 0, - wantFiles: []string{"root.yaml"}, + name: "Non-recursive (Root only, all types)", + recursive: false, + maxDepth: 0, + extensions: nil, + wantFiles: []string{"root.yaml", "root.json"}, }, { - name: "Recursive Unlimited", - recursive: true, - maxDepth: 0, - wantFiles: []string{"root.yaml", "level1.yaml", "level2.yaml"}, + name: "Recursive Unlimited (All types)", + recursive: true, + maxDepth: 0, + extensions: nil, + wantFiles: []string{"root.yaml", "root.json", "level1.yaml", "level1.txt", "level2.yaml"}, }, { - name: "Recursive MaxDepth 1", - recursive: true, - maxDepth: 1, - wantFiles: []string{"root.yaml", "level1.yaml"}, + name: "Recursive MaxDepth 1 (All types)", + recursive: true, + maxDepth: 1, + extensions: nil, + wantFiles: []string{"root.yaml", "root.json", "level1.yaml", "level1.txt"}, }, { - name: "Recursive MaxDepth 2", - recursive: true, - maxDepth: 2, - wantFiles: []string{"root.yaml", "level1.yaml", "level2.yaml"}, + name: "Recursive MaxDepth 2 (All types)", + recursive: true, + maxDepth: 2, + extensions: nil, + wantFiles: []string{"root.yaml", "root.json", "level1.yaml", "level1.txt", "level2.yaml"}, + }, + { + name: "Recursive Filtered (.yaml only)", + recursive: true, + maxDepth: 0, + extensions: []string{".yaml"}, + wantFiles: []string{"root.yaml", "level1.yaml", "level2.yaml"}, + }, + { + name: "Recursive Filtered (.yaml, .json)", + recursive: true, + maxDepth: 0, + extensions: []string{".yaml", ".json"}, + wantFiles: []string{"root.yaml", "root.json", "level1.yaml", "level2.yaml"}, + }, + { + name: "Recursive MaxDepth 1 Filtered (.yaml)", + recursive: true, + maxDepth: 1, + extensions: []string{".yaml"}, + wantFiles: []string{"root.yaml", "level1.yaml"}, }, } @@ -94,7 +122,8 @@ func TestRecursiveWalkFunctional(t *testing.T) { BaseURL(fileURL). Branch("master"). Root(""). - MaxDepth(tt.maxDepth) + MaxDepth(tt.maxDepth). + AllowedExtensions(tt.extensions) var collectedFiles []string walkerInst.RegisterFileInterceptor(func(f walker.File) error { @@ -123,9 +152,11 @@ func assertFilesEqual(t *testing.T, got, want []string) { for _, f := range got { gotMap[f] = struct{}{} } + failed := false for _, f := range want { if _, ok := gotMap[f]; !ok { t.Errorf("missing expected file: %s", f) + failed = true } else { delete(gotMap, f) } @@ -133,10 +164,12 @@ func assertFilesEqual(t *testing.T, got, want []string) { if len(gotMap) > 0 { for f := range gotMap { t.Errorf("unexpected file collected: %s", f) + failed = true } } - if len(got) != len(want) { - t.Errorf("got %d files, want %d", len(got), len(want)) + if failed { + t.Errorf("Got: %v", got) + t.Errorf("Want: %v", want) } }