feat: add --exclude-relative flag for path-based file exclusion#6741
feat: add --exclude-relative flag for path-based file exclusion#6741danielroymoore wants to merge 5 commits intomainfrom
Conversation
The existing --exclude flag only accepts basenames, which causes collateral exclusion in workspace-style projects where multiple files share the same name (e.g. package.json). This adds --exclude-relative to allow comma-separated relative paths for precise per-file exclusion in --all-projects and --yarn-workspaces scans. Made-with: Cursor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
- Resolve path once in findInDirectory instead of twice - Add case-insensitive path comparison for Windows - Trim whitespace from comma-separated exclude-relative paths - Fix Prettier formatting
This comment has been minimized.
This comment has been minimized.
Workspace processors (e.g. processPnpmWorkspaces) read pnpm-workspace.yaml directly and discover all workspace members, bypassing the --exclude-relative file-level exclusion applied during find(). Apply excludePaths as a post-filter on scannedProjects so projects matched by --exclude-relative are consistently removed. Made-with: Cursor
This comment has been minimized.
This comment has been minimized.
Made-with: Cursor
PR Reviewer Guide 🔍
|
Pull Request Submission Checklist
What does this PR do?
Adds a new
--exclude-relativeCLI flag that accepts comma-separated relative paths for excluding specific files and directories during--all-projectsand--yarn-workspacesscans. This complements the existing--excludeflag, which only matches basenames.The problem
The existing
--excludeflag matches by basename only (e.g.--exclude=package.jsonexcludes allpackage.jsonfiles). In workspace-style monorepos, this makes it impossible to exclude a specific package without excluding every package that shares the same manifest filename:--exclude=package.jsonexcludes all three. There was no way to target justpackages/api/package.json.What changed
New flag:
--exclude-relative--exclude-relative=packages/api/package.json,packages/web/package.json)--all-projectsor--yarn-workspaces(same constraint as--exclude)..)File discovery (
find-files.ts)excludePathstoFindFilesConfig— an array of resolved absolute pathsisExcludedPath()helper performs exact path matching, with case-insensitive comparison on WindowspathLib.resolvecalls)Plugin integration (
get-deps-from-plugin.ts)options.excludeRelativeinto resolved absolute paths and passes them asexcludePathstofind()excludePathsin analytics dataValidation & errors
ExcludeRelativeFlagInvalidInputErrorwith clear messaging about allowed input formatMissingOptionErrorwhen used without--all-projectsor--yarn-workspacesargs.tsregisters'exclude-relative'for camelCase transformationtypes.tsadds the option toOptionsandSupportedUserReachableFacingCliArgsTests
test/tap/find-files.test.ts): VerifiesexcludePathsexcludes specific files by absolute path, doesn't affect same-basename files at other paths, and can exclude entire directoriestest/jest/acceptance/cli-args.spec.ts): Validates error messages for missing--all-projects, absolute paths, and..traversaltest/jest/acceptance/snyk-test/all-projects.spec.ts): End-to-end tests with pnpm workspace fixture confirming single path exclusion, multiple path exclusion, and that non-targeted package.json files are unaffectedWhere should the reviewer start?
src/cli/main.ts— validation logic for the new flagsrc/lib/find-files.ts— core exclusion in the file discovery enginesrc/lib/plugins/get-deps-from-plugin.ts— integration with the plugin system and post-scan filteringHow should this be manually tested?
In a workspace monorepo with multiple
package.jsonfiles:Risk assessment: Low
--excludebehaviour or any other flags--exclude--exclude-relative; when absent, zero code paths are affectedCompanion PR
This is consumed by snyk/cli-extension-dep-graph#152, which replaces the
path.Splitworkaround in the orchestrator with--exclude-relativefor forwarding processed file exclusions to the legacy CLI.Trade-offs & callouts
--excludeis unchanged. Existing behaviour is fully preserved. Both flags can be used together —--excludefor basename patterns,--exclude-relativefor specific paths.Post-scan filtering in
get-deps-from-plugin.ts. Workspace parsers (e.g. pnpm) discover projects by reading workspace config files rather than walking the filesystem, so they bypass thefind()exclusion. An additional filter oninspectRes.scannedProjectscatches these. This is intentional and mirrors how--excludealready needs special handling for workspace-discovered projects.No glob support. The flag accepts literal relative paths only, not globs. This keeps the implementation simple and predictable. Glob support could be added later if needed.
Windows path handling.
isExcludedPath()uses case-insensitive comparison onwin32to match Windows filesystem semantics. On Unix, comparison is exact.