@@ -18,6 +18,10 @@ type Config struct {
1818 // Paths to exclude from scanning (glob patterns supported)
1919 Paths []string `yaml:"paths,omitempty"`
2020
21+ // ShallowDirs are directories to scan at top level only (no recursion)
22+ // Files directly in these directories are scanned, but subdirectories are skipped
23+ ShallowDirs []string `yaml:"shallowDirs,omitempty"`
24+
2125 // Kernel parameters to exclude from scanning
2226 KernelParams []string `yaml:"kernelParams,omitempty"`
2327
@@ -42,6 +46,9 @@ type CLIOptions struct {
4246
4347 // IncludeProcesses enables process scanning (removes "process" from DisabledScanners)
4448 IncludeProcesses bool
49+
50+ // ShallowDirs adds directories to scan without recursion (from CLI)
51+ ShallowDirs []string
4552}
4653
4754// Load reads configuration from defaults, optional config file, and CLI options.
@@ -83,6 +90,11 @@ func Load(configPath string, opts CLIOptions) (*Config, error) {
8390 cfg .DisabledScanners = removeItems (cfg .DisabledScanners , []string {"process" })
8491 }
8592
93+ // Add CLI shallow dirs to config
94+ if len (opts .ShallowDirs ) > 0 {
95+ cfg .ShallowDirs = append (cfg .ShallowDirs , opts .ShallowDirs ... )
96+ }
97+
8698 return & cfg , nil
8799}
88100
@@ -108,6 +120,7 @@ func merge(base, file Config) Config {
108120
109121 // Append file exclusions to base exclusions (additive)
110122 result .Paths = append (result .Paths , file .Paths ... )
123+ result .ShallowDirs = append (result .ShallowDirs , file .ShallowDirs ... )
111124 result .KernelParams = append (result .KernelParams , file .KernelParams ... )
112125 result .DisabledScanners = append (result .DisabledScanners , file .DisabledScanners ... )
113126
@@ -188,3 +201,39 @@ func (c *Config) IsScannerDisabled(scannerType string) bool {
188201 }
189202 return false
190203}
204+
205+ // IsShallowDir checks if the given path is a shallow directory (should not recurse into).
206+ // Returns true if path exactly matches a shallow dir or is a subdirectory of one.
207+ func (c * Config ) IsShallowDir (path string ) bool {
208+ for _ , shallow := range c .ShallowDirs {
209+ // Normalize paths (remove trailing slashes)
210+ shallow = strings .TrimSuffix (shallow , "/" )
211+ path = strings .TrimSuffix (path , "/" )
212+
213+ // Check if this is exactly the shallow dir or a subdirectory
214+ if path == shallow || strings .HasPrefix (path , shallow + "/" ) {
215+ return true
216+ }
217+ }
218+ return false
219+ }
220+
221+ // GetShallowDirDepth returns the depth of the shallow directory that contains this path.
222+ // Returns -1 if path is not in any shallow directory.
223+ // Depth 0 = the shallow dir itself, depth 1 = immediate child, etc.
224+ func (c * Config ) GetShallowDirDepth (path string ) int {
225+ for _ , shallow := range c .ShallowDirs {
226+ shallow = strings .TrimSuffix (shallow , "/" )
227+ path = strings .TrimSuffix (path , "/" )
228+
229+ if path == shallow {
230+ return 0
231+ }
232+ if strings .HasPrefix (path , shallow + "/" ) {
233+ // Count the depth relative to shallow dir
234+ relPath := strings .TrimPrefix (path , shallow + "/" )
235+ return strings .Count (relPath , "/" ) + 1
236+ }
237+ }
238+ return - 1
239+ }
0 commit comments