feat(tui): skip IaC caches (.terraform, .terragrunt-cache, ...) in recursive @-search
Add Terraform/Terragrunt/Pulumi/Serverless/CDK provider and module caches to the recursive walk skip list. These hold copies of downloaded providers and generated module trees that would otherwise dominate the entry budget with non-source files.
- commit
- e7439baaa6878d1b9c0821c266907254fdad430c
- author
- Raymond Gasper · · 2026-06-09 19:48 UTC
- parent
- 7ac6034
- signature
- unsigned
2 files · +42 -0
M packages/agent/modes/file_suggest.go +9 -0
| @@ -36,6 +36,15 @@ var recursiveSkipDirs = map[string]bool{ | |||
| 36 | 36 | ".idea": true, | |
| 37 | 37 | ".vscode": true, | |
| 38 | 38 | "__pycache__": true, | |
| 39 | + | // Infrastructure-as-code provider/module caches. These hold copies | |
| 40 | + | // of downloaded providers and generated module trees and can grow | |
| 41 | + | // to hundreds of MB or deeply nested duplicates of the source. | |
| 42 | + | ".terraform": true, | |
| 43 | + | ".terragrunt-cache": true, | |
| 44 | + | ".terraform.d": true, | |
| 45 | + | ".pulumi": true, | |
| 46 | + | ".serverless": true, | |
| 47 | + | "cdk.out": true, | |
| 39 | 48 | } | |
| 40 | 49 | ||
| 41 | 50 | // fileSuggester provides an @-triggered file/directory picker popup. | |
| @@ -36,6 +36,15 @@ var recursiveSkipDirs = map[string]bool{ | |||||
| 36 | ".idea": true, | 36 | ".idea": true, | ||
| 37 | ".vscode": true, | 37 | ".vscode": true, | ||
| 38 | "__pycache__": true, | 38 | "__pycache__": true, | ||
| 39 | + | // Infrastructure-as-code provider/module caches. These hold copies | |||
| 40 | + | // of downloaded providers and generated module trees and can grow | |||
| 41 | + | // to hundreds of MB or deeply nested duplicates of the source. | |||
| 42 | + | ".terraform": true, | |||
| 43 | + | ".terragrunt-cache": true, | |||
| 44 | + | ".terraform.d": true, | |||
| 45 | + | ".pulumi": true, | |||
| 46 | + | ".serverless": true, | |||
| 47 | + | "cdk.out": true, | |||
| 39 | } | 48 | } | ||
| 40 | 49 | ||||
| 41 | // fileSuggester provides an @-triggered file/directory picker popup. | 50 | // fileSuggester provides an @-triggered file/directory picker popup. | ||
M packages/agent/modes/file_suggest_test.go +33 -0
| @@ -171,6 +171,39 @@ func TestFileSuggesterRecursiveSkipsHeavyDirs(t *testing.T) { | |||
| 171 | 171 | } | |
| 172 | 172 | } | |
| 173 | 173 | ||
| 174 | + | // TestFileSuggesterRecursiveSkipsIaCCaches ensures infrastructure-as- | |
| 175 | + | // code provider/module caches are pruned so a recursive walk doesn't | |
| 176 | + | // drown in copies of downloaded providers or generated modules. | |
| 177 | + | func TestFileSuggesterRecursiveSkipsIaCCaches(t *testing.T) { | |
| 178 | + | tmp := t.TempDir() | |
| 179 | + | for _, dir := range []string{".terraform", ".terragrunt-cache", "cdk.out"} { | |
| 180 | + | nested := filepath.Join(tmp, dir, "deep") | |
| 181 | + | if err := os.MkdirAll(nested, 0o755); err != nil { | |
| 182 | + | t.Fatal(err) | |
| 183 | + | } | |
| 184 | + | if err := os.WriteFile(filepath.Join(nested, "junk.tf"), []byte("x"), 0o644); err != nil { | |
| 185 | + | t.Fatal(err) | |
| 186 | + | } | |
| 187 | + | } | |
| 188 | + | if err := os.WriteFile(filepath.Join(tmp, "main.tf"), []byte("x"), 0o644); err != nil { | |
| 189 | + | t.Fatal(err) | |
| 190 | + | } | |
| 191 | + | s := newFileSuggester() | |
| 192 | + | s.SetCWD(tmp) | |
| 193 | + | s.SetRecursive(true) | |
| 194 | + | ||
| 195 | + | for _, e := range s.scan() { | |
| 196 | + | for _, skip := range []string{".terraform", ".terragrunt-cache", "cdk.out"} { | |
| 197 | + | if e.rel == skip || strings.HasPrefix(e.rel, skip+string(filepath.Separator)) { | |
| 198 | + | t.Fatalf("recursive scan descended into %s: %#v", skip, e) | |
| 199 | + | } | |
| 200 | + | } | |
| 201 | + | } | |
| 202 | + | if !containsEntry(s.scan(), "main.tf", false) { | |
| 203 | + | t.Fatal("recursive scan missing main.tf") | |
| 204 | + | } | |
| 205 | + | } | |
| 206 | + | ||
| 174 | 207 | // TestFileSuggesterToggleResetsCache verifies SetRecursive drops the | |
| 175 | 208 | // cached scan so the next matches() reflects the new mode. | |
| 176 | 209 | func TestFileSuggesterToggleResetsCache(t *testing.T) { | |
| @@ -171,6 +171,39 @@ func TestFileSuggesterRecursiveSkipsHeavyDirs(t *testing.T) { | |||||
| 171 | } | 171 | } | ||
| 172 | } | 172 | } | ||
| 173 | 173 | ||||
| 174 | + | // TestFileSuggesterRecursiveSkipsIaCCaches ensures infrastructure-as- | |||
| 175 | + | // code provider/module caches are pruned so a recursive walk doesn't | |||
| 176 | + | // drown in copies of downloaded providers or generated modules. | |||
| 177 | + | func TestFileSuggesterRecursiveSkipsIaCCaches(t *testing.T) { | |||
| 178 | + | tmp := t.TempDir() | |||
| 179 | + | for _, dir := range []string{".terraform", ".terragrunt-cache", "cdk.out"} { | |||
| 180 | + | nested := filepath.Join(tmp, dir, "deep") | |||
| 181 | + | if err := os.MkdirAll(nested, 0o755); err != nil { | |||
| 182 | + | t.Fatal(err) | |||
| 183 | + | } | |||
| 184 | + | if err := os.WriteFile(filepath.Join(nested, "junk.tf"), []byte("x"), 0o644); err != nil { | |||
| 185 | + | t.Fatal(err) | |||
| 186 | + | } | |||
| 187 | + | } | |||
| 188 | + | if err := os.WriteFile(filepath.Join(tmp, "main.tf"), []byte("x"), 0o644); err != nil { | |||
| 189 | + | t.Fatal(err) | |||
| 190 | + | } | |||
| 191 | + | s := newFileSuggester() | |||
| 192 | + | s.SetCWD(tmp) | |||
| 193 | + | s.SetRecursive(true) | |||
| 194 | + | ||||
| 195 | + | for _, e := range s.scan() { | |||
| 196 | + | for _, skip := range []string{".terraform", ".terragrunt-cache", "cdk.out"} { | |||
| 197 | + | if e.rel == skip || strings.HasPrefix(e.rel, skip+string(filepath.Separator)) { | |||
| 198 | + | t.Fatalf("recursive scan descended into %s: %#v", skip, e) | |||
| 199 | + | } | |||
| 200 | + | } | |||
| 201 | + | } | |||
| 202 | + | if !containsEntry(s.scan(), "main.tf", false) { | |||
| 203 | + | t.Fatal("recursive scan missing main.tf") | |||
| 204 | + | } | |||
| 205 | + | } | |||
| 206 | + | ||||
| 174 | // TestFileSuggesterToggleResetsCache verifies SetRecursive drops the | 207 | // TestFileSuggesterToggleResetsCache verifies SetRecursive drops the | ||
| 175 | // cached scan so the next matches() reflects the new mode. | 208 | // cached scan so the next matches() reflects the new mode. | ||
| 176 | func TestFileSuggesterToggleResetsCache(t *testing.T) { | 209 | func TestFileSuggesterToggleResetsCache(t *testing.T) { | ||