Skip to content

fix(project-detect): match packageKeys on boundaries, not substrings (preact→react)#2181

Merged
affaan-m merged 1 commit into
affaan-m:mainfrom
bymle:fix/project-detect-substring-framework
Jun 7, 2026
Merged

fix(project-detect): match packageKeys on boundaries, not substrings (preact→react)#2181
affaan-m merged 1 commit into
affaan-m:mainfrom
bymle:fix/project-detect-substring-framework

Conversation

@bymle

@bymle bymle commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Problem

Framework detection misclassifies dependencies whose name merely contains a framework key. project-detect.js reports preact — and even reactive — as react:

// package.json: { "dependencies": { "preact": "10.0.0" } }
detectProjectType(dir).frameworks // => ["react"]   (wrong)

Other collisions: svelte-check-only → svelte, nextranextjs.

Root cause

hasDep = rule.packageKeys.some(key => depList.some(dep => dep.toLowerCase().includes(key.toLowerCase())));

String.includes is unbounded substring matching with no name boundary.

Fix

Match only when the dependency equals the key, or the key is a prefix immediately followed by a delimiter (/ . _ -):

if (!d.startsWith(k)) return false;
return d.length === k.length || /[/._-]/.test(d[k.length]);

This still matches every real case — react-dom, @remix-run/node, spring-boot-starter, org.springframework.boot, github.com/labstack/echo/v4, phoenix_live_view — while excluding preact/reactive (and incidentally fixing nextra).

I kept all four delimiters (/ . _ -) so the dotted/scoped/underscored ecosystem keys (Spring, Go module paths, Elixir) keep working — happy to tune the delimiter set if you'd prefer something narrower.

Tests

Adds regression tests to tests/lib/project-detect.test.js: preact/reactive no longer map to react, and react-dom alone still does. Full file: 33 passed, 0 failed (the 2 new negative cases fail on current main).


Summary by cubic

Fix framework detection by matching packageKeys on name boundaries instead of substrings. This stops false positives like preact/reactivereact while keeping react-dom and @remix-run/node working.

  • Bug Fixes
    • Replace substring match with boundary check: equal to key or key followed by a delimiter (/ . _ -).
    • Add regression tests for negative and positive cases.

Written for commit b517a8a. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

Bug Fixes

  • Improved framework dependency detection with refined package matching logic, reducing false positives from similarly-named dependencies.

Tests

  • Added test cases to verify correct framework detection with similar-named packages and edge cases.

Framework detection matched a dependency against a framework's packageKeys
with unbounded substring containment (dep.includes(key)), so any dependency
whose name merely contained a key was misclassified: `preact` and even
`reactive` were both detected as `react`.

Match only when the dependency equals the key, or the key is a prefix
immediately followed by a delimiter (/ . _ -). This still matches every real
case (react-dom, @remix-run/node, spring-boot-starter, org.springframework.boot,
github.com/labstack/echo/v4, phoenix_live_view) while excluding preact/reactive
(and incidentally nextra). Adds regression tests.
@bymle bymle requested a review from affaan-m as a code owner June 7, 2026 00:45
@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c319b8d3-7584-4627-9f57-ff3b79c84fa3

📥 Commits

Reviewing files that changed from the base of the PR and between 7113b5b and b517a8a.

📒 Files selected for processing (2)
  • scripts/lib/project-detect.js
  • tests/lib/project-detect.test.js

📝 Walkthrough

Walkthrough

This PR fixes framework dependency detection by replacing naive substring matching with boundary-aware prefix matching. The logic now treats a dependency key as matching only when it equals the target (case-insensitive) or when it is a prefix immediately followed by a delimiter, preventing false positives like react matching inside reactive while preserving support for namespaced and templated packages.

Changes

Framework Detection Boundary Matching

Layer / File(s) Summary
Boundary-aware package key matching
scripts/lib/project-detect.js
Core matching logic replaces substring includes() with a boundary-aware predicate that checks for exact equality or prefix match followed by delimiters (/, ., _, -) to prevent false positives.
Edge case tests for substring safety
tests/lib/project-detect.test.js
Added three test cases verifying preact and reactive do not incorrectly trigger React detection, and confirming react-dom alone still maps to react.

🎯 2 (Simple) | ⏱️ ~10 minutes

🐰 A rabbit hops through code with care,
Matching bounds where delimiters share,
No more react in reactive fright,
Prefixes dance with cleaner sight,
Framework detection done just right! 🎯

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: fixing boundary-aware matching for packageKeys instead of substring matching, with a concrete example (preact→react) that illustrates the problem being solved.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 2 files

Re-trigger cubic

@affaan-m affaan-m merged commit 9c35aef into affaan-m:main Jun 7, 2026
3 checks passed
syarfandi pushed a commit to syarfandi/ECC that referenced this pull request Jun 9, 2026
…ffaan-m#2181)

Framework detection matched a dependency against a framework's packageKeys
with unbounded substring containment (dep.includes(key)), so any dependency
whose name merely contained a key was misclassified: `preact` and even
`reactive` were both detected as `react`.

Match only when the dependency equals the key, or the key is a prefix
immediately followed by a delimiter (/ . _ -). This still matches every real
case (react-dom, @remix-run/node, spring-boot-starter, org.springframework.boot,
github.com/labstack/echo/v4, phoenix_live_view) while excluding preact/reactive
(and incidentally nextra). Adds regression tests.

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants