fix(core): split-target should handle projects with colons in name better#34725
fix(core): split-target should handle projects with colons in name better#34725FrozenPandaz merged 11 commits intomasterfrom
Conversation
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ 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 71a7d43
☁️ Nx Cloud last updated this comment at |
| // substitutors that actually need it. Root-keyed substitutors are | ||
| // looked up by root directly and don't need the name at all. | ||
| if (this.substitutorsByUnresolvedName.has(previousName)) { | ||
| this.dirtyEntries.get(root).add(previousName); |
There was a problem hiding this comment.
TypeScript compilation error: this.dirtyEntries.get(root) returns Set<string> | undefined, but the code attempts to call .add() without a non-null assertion. Although line 614-616 ensures the entry exists, TypeScript cannot infer this.
Fix:
this.dirtyEntries.get(root)!.add(previousName);This will cause the build to fail.
| this.dirtyEntries.get(root).add(previousName); | |
| this.dirtyEntries.get(root)!.add(previousName); |
Spotted by Graphite
Is this helpful? React 👍 or 👎 to let us know.
3bae304 to
3aae869
Compare
3aae869 to
af4b552
Compare
There was a problem hiding this comment.
Nx Cloud has identified a flaky task in your failed CI:
🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.
🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.
🎓 Learn more about Self-Healing CI on nx.dev
…rooted when dep is drawn
Decompose the monolithic project-configuration-utils.ts (~1400 lines) into focused modules with a clear dependency DAG: - target-merging.ts: target-level merge utilities (leaf module) - target-normalization.ts: normalization, validation, target defaults - project-nodes-manager.ts: project-level merge and read operations Split the corresponding spec file into sibling spec files for each new module. All 143 tests continue to pass.
Point consumers directly at source modules instead of re-exporting through the old barrel file.
…pass bestMatch Replace sort-based precedence selection with a single-pass bestMatch to avoid unnecessary allocation. Thread currentProject from normalizeDependencyConfigDefinition through expandDependencyConfigSyntaxSugar and readProjectAndTargetFromTargetString so splitTarget can disambiguate bare-target matches.
…-Healing CI Rerun]
2d38b16 to
71a7d43
Compare
…tter (#34725) ## Current Behavior - `splitTarget` causes issues when a project name has more than one colon - Project name substitution is triggered when a project depends on the orginal name of a renamed project, even if the renamed project was renamed before the dep was registered That second one is hard to understand. Imagine the real scenario below: - @nx/gradle was reading settings.gradle.kts and naming the root project `nx` - The package.json inference plugin renames it to `@nx/nx-source` - The package.json inference plugin infers the `nx` project in `packages/nx` - The package.json inference plugin reads a config that has `dependsOn: [nx:build]` - The substitutors run, and update the dependsOn to `@nx/nx-source:build` ## Expected Behavior splitTarget follows the below precedence: - If splitting a target string thats embedded in a specific project configuration, targets on that project are preferred - Targets belonging to the project with the longest name that is valid from joining segments left to right - Targets that have the longest name from joining segments are preferred - Configuration is the remaining segments after picking off the longest valid project containing a valid target. Substitutors prefer registering by root if a project with a given name exists, and only register by name if no project with that root exists (e.g. if a plugin adds a dependsOn to a project that was inferred by a later plugin, this would be common if a custom plugin is reading project.json to get a name or smth). ## AI Summary > # Branch Analysis: `fix/split-target-fixes` vs `master` > > ## Summary > > | Metric | Lines | > |--------|------:| > | **Total raw diff (added+removed, non-test)** | 2,840 + 1,221 = 4,061 | > | **Lines that were just moved (file split)** | ~960 | > | **Truly new/changed lines (non-test)** | ~570 | > | **Test file changes (raw diff)** | 3,109 added / 2,242 removed | > > ## Commits > > | SHA | Message | > |-----|---------| > | `57ec87b3c4` | fix(core): split-target should handle projects with colons in name better | > | `af1ebc90ab` | fix(core): avoid renaming projects based on former name if they were rooted when dep is drawn | > | `b2fffc60c7` | cleanup(core): split project-configuration-utils into focused modules | > | `3bae3048d8` | fix(core): fixup name substitution manager | > > ## File Split: `project-configuration-utils.ts` -> 4 modules > > The original `project-configuration-utils.ts` (1,407 lines) was split into focused modules. **~960 lines were moved as-is** (identical minus whitespace/formatting) into the new files. The remaining changes are actual logic modifications. > > | File | Total Lines | Moved from original | Truly new/changed | > |------|------------:|--------------------:|------------------:| > | `project-configuration-utils.ts` (remaining) | 444 | ~395 | ~49 | > | `target-merging.ts` | 494 | ~430 | } | > | `target-normalization.ts` | 282 | ~250 | } ~111 combined | > | `project-nodes-manager.ts` | 365 | ~285 | } | > | **Subtotal** | 1,585 | ~1,360 | ~160 | > > Additionally, ~39 lines were removed from the original and not moved anywhere (dead code removal or refactored away). > > ## Actual Code Changes (non-test, excluding moved lines) > > ### Major changes > > | File | New | Removed | Net | Description | > |------|----:|--------:|----:|-------------| > | `split-target.ts` | ~211 | ~38 | +173 | New logic for handling projects with colons in names | > | `name-substitution-manager.ts` | ~152 | ~85 | +67 | Fix: avoid renaming rooted projects based on former name | > | Split files (combined, new logic only) | ~111 | — | +111 | New code introduced during the split refactor | > | `project-configuration-utils.ts` (new logic only) | ~49 | ~39 | +10 | Residual new code after split | > > ### Minor edits (import path updates, small fixes) > > | File | Added | Removed | > |------|------:|--------:| > | `parse-target-string.ts` | 7 | 1 | > | `command-line/show/target.ts` | 11 | 7 | > | `devkit-internals.ts` | 3 | 5 | > | `tasks-runner/utils.ts` | 5 | 3 | > | `build-project-graph.ts` | 2 | 4 | > | `error-types.ts` | 2 | 4 | > | `command-line/run/run-one.ts` | 2 | 1 | > | `ngcli-adapter.ts` | 1 | 1 | > | `convert-nx-executor.ts` | 1 | 1 | > | `project-configuration.ts` (generators) | 1 | 1 | > | `package-json.ts` | 1 | 1 | > | `settings.gradle.kts` | 1 | 1 | > | **Minor edits subtotal** | **37** | **30** | > > ### Other new files > > | File | Lines | Description | > |------|------:|-------------| > | `packages/devkit/CLAUDE.md` | 62 | Dev documentation | > | `__fixtures__/merge-create-nodes-args.json` | 100 | Test fixture data | > > ## Final Tally: True Non-Test Changes > > | Category | Lines | > |----------|------:| > | New logic in `split-target.ts` | ~211 | > | New logic in `name-substitution-manager.ts` | ~152 | > | New logic in split module files | ~111 | > | New logic in remaining `project-configuration-utils.ts` | ~49 | > | Minor import/path updates across 12 files | ~37 added / ~30 removed | > | New non-code files (CLAUDE.md, fixture JSON) | 162 | > | **Total truly new/changed lines** | **~570 added, ~160 removed** | > | Moved lines (file split, not real changes) | **~960** | ## Related Issue(s) <!-- Please link the issue being fixed so it gets closed when this is merged. --> Fixes # --------- Co-authored-by: FrozenPandaz <jasonjean1993@gmail.com> Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com> (cherry picked from commit 1fc3841)
|
This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request. |
Current Behavior
splitTargetcauses issues when a project name has more than one colonThat second one is hard to understand. Imagine the real scenario below:
nx@nx/nx-sourcenxproject inpackages/nxdependsOn: [nx:build]@nx/nx-source:buildExpected Behavior
splitTarget follows the below precedence:
Substitutors prefer registering by root if a project with a given name exists, and only register by name if no project with that root exists (e.g. if a plugin adds a dependsOn to a project that was inferred by a later plugin, this would be common if a custom plugin is reading project.json to get a name or smth).
AI Summary
Related Issue(s)
Fixes #