feat(core): add negation pattern support for plugin include/exclude#34160
feat(core): add negation pattern support for plugin include/exclude#34160
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit 33a380a
☁️ Nx Cloud last updated this comment at |
| // Process include patterns with negation support | ||
| if (include && include.length > 0) { | ||
| if (!matchesPatternArray(file, include)) { |
There was a problem hiding this comment.
@AgentEnder So to do this we have to move from .some to always checking all patterns.
This feels like it should be ok, but I worry that someone might have a project config doing something weird like enumerating all projects they want a plugin enabled for 😅
Thoughts?
There was a problem hiding this comment.
Hmm, in a repo I've not tuned at all, just using our generators to create some buildable and some non-buildable projects, the ts plugin is configureded as below:
{
"plugins": [
{
"plugin": "@nx/js/typescript",
"options": {
"typecheck": {
"targetName": "typecheck"
},
"build": {
"targetName": "build",
"configName": "tsconfig.lib.json",
"buildDepsName": "build-deps",
"watchDepsName": "watch-deps"
}
},
"exclude": [
"packages/model/*",
"packages/env-schemas/*",
"packages/schema-utils/*",
"e2e/*"
]
},
{
"plugin": "@nx/js/typescript",
"include": [
"packages/model/*",
"packages/env-schemas/*",
"packages/schema-utils/*"
],
"options": {
"typecheck": {
"targetName": "typecheck"
}
}
},
]
}There was a problem hiding this comment.
Added a check for negations in the patterns before doing the more expensive check. With this the current perf should at least be maintained for anyone not using negations.
There was a problem hiding this comment.
Important
At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.
Nx Cloud has identified a possible root cause for your failed CI:
We're classifying this react-native:test failure as environment_state because it's caused by a corrupted ESLint cache file (empty JSON file) in .nx/workspace-data/, not by the pattern matching changes in this PR. The failing project wasn't modified by this PR, and the error occurs in cache file reading logic that this PR doesn't touch. This requires clearing the workspace cache rather than code changes.
No code changes were suggested for this issue.
Trigger a rerun:
🎓 Learn more about Self-Healing CI on nx.dev
| if (!included) { | ||
| continue; | ||
| } | ||
| if (!includes(file)) { |
There was a problem hiding this comment.
I honestly kind of hate that we are doing this whole if matches, check matches, then check other matches thing, but its existing code and I don't know of a good way to combine them off the top of my head, nor that it'd be faster if we did... In any case, that's not your PRs fault. I think this is fine?
e15cb6e to
7e51623
Compare
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
Add support for negation patterns (patterns starting with '!') in the
include and exclude fields of plugin configurations. This allows more
precise control over which files plugins process.
Example usage:
```json
{
"plugin": "@nx/jest/plugin",
"exclude": ["**/*-e2e/**/*", "!**/toolkit-workspace-e2e/**/*"]
}
```
This will exclude all e2e projects except toolkit-workspace-e2e.
Implementation follows the same negation pattern algorithm used by
findMatchingProjects:
- Patterns are processed sequentially
- Patterns starting with '!' remove files from the match set
- Positive patterns add files to the match set
- Last matching pattern wins
- If first pattern is a negation, all files are matched initially
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
…clude Add documentation for the newly added negation pattern feature in plugin include/exclude configuration. Includes examples and explanation of how the patterns are processed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
…terns Add a fast path for pattern matching when no negation patterns are present. This maintains backward-compatible performance while supporting the new negation pattern feature. Performance impact (1500 files, 4 patterns): - Non-negation patterns: 18% faster than before (26.8ms vs 32.7ms) - With negation patterns: Acceptable overhead for new feature (23.6ms) The fast path uses short-circuit evaluation (.some()) which exits early on first match, while the slow path processes all patterns sequentially to handle negation logic correctly. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
Refactor pattern matching to check for negation patterns once upfront instead of on every file iteration. Creates specialized matcher functions that eliminate null checks and branching in the hot loop. Changes: - Split into matchesSimplePatterns (fast) and matchesNegationPatterns (full) - createIncludeMatcher() returns function that always returns true if empty - createExcludeMatcher() returns function that always returns false if empty - Eliminates null checks and conditional logic in the file iteration loop - Matchers created outside the file loop in findMatchingConfigFiles Performance impact (1500 files, 4 patterns): - Before: 32.1ms (checking negation per file) - After: 26.0ms (checking negation once) - Improvement: 19% faster 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
7e51623 to
21b661c
Compare
…34160) <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior Negation patterns are ignored in plugin configuration for the `include` and `exclude` properties. ## Expected Behavior - Negation patterns should work in the same way that they do for other `include`/`exclude` configurations **Example: Excluding all e2e projects except one** ```jsonc // nx.json { "plugins": [ { "plugin": "@nx/jest/plugin", "exclude": ["**/*-e2e/**/*", "!**/toolkit-workspace-e2e/**/*"], }, ], } ``` This will exclude all e2e projects except `toolkit-workspace-e2e`. **Example: Including packages except legacy ones** ```jsonc // nx.json { "plugins": [ { "plugin": "@nx/vite/plugin", "include": ["packages/**/*", "!packages/legacy/**/*"], }, ], } ``` **How negation patterns work:** - Patterns are processed in order from first to last - A pattern starting with `!` removes files from the match set - A pattern without `!` adds files to the match set - The last matching pattern determines if a file is included - If the first pattern is a negation, all files are matched initially --------- Co-authored-by: Claude Sonnet 4.5 <[email protected]>
…34160) <!-- Please make sure you have read the submission guidelines before posting an PR --> <!-- https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr --> <!-- Please make sure that your commit message follows our format --> <!-- Example: `fix(nx): must begin with lowercase` --> <!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. --> ## Current Behavior Negation patterns are ignored in plugin configuration for the `include` and `exclude` properties. ## Expected Behavior - Negation patterns should work in the same way that they do for other `include`/`exclude` configurations **Example: Excluding all e2e projects except one** ```jsonc // nx.json { "plugins": [ { "plugin": "@nx/jest/plugin", "exclude": ["**/*-e2e/**/*", "!**/toolkit-workspace-e2e/**/*"], }, ], } ``` This will exclude all e2e projects except `toolkit-workspace-e2e`. **Example: Including packages except legacy ones** ```jsonc // nx.json { "plugins": [ { "plugin": "@nx/vite/plugin", "include": ["packages/**/*", "!packages/legacy/**/*"], }, ], } ``` **How negation patterns work:** - Patterns are processed in order from first to last - A pattern starting with `!` removes files from the match set - A pattern without `!` adds files to the match set - The last matching pattern determines if a file is included - If the first pattern is a negation, all files are matched initially --------- Co-authored-by: Claude Sonnet 4.5 <[email protected]> (cherry picked from commit 754b01a)
Current Behavior
Negation patterns are ignored in plugin configuration for the
includeandexcludeproperties.Expected Behavior
include/excludeconfigurationsExample: Excluding all e2e projects except one
This will exclude all e2e projects except
toolkit-workspace-e2e.Example: Including packages except legacy ones
How negation patterns work:
!removes files from the match set!adds files to the match set