-
Notifications
You must be signed in to change notification settings - Fork 649
Move eslint-plugin-primer-react into monorepo #7464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
…repo Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
… README Co-authored-by: siddharthkp <1863771+siddharthkp@users.noreply.github.com>
packages/eslint-plugin-primer-react/src/rules/new-color-css-vars.js
Dismissed
Show dismissed
Hide dismissed
| @@ -0,0 +1,19 @@ | |||
| const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/ | |||
Check failure
Code scanning / CodeQL
Inefficient regular expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
In general, to fix inefficient regular expressions with nested quantifiers, you either (1) restructure the pattern to avoid ambiguous or overlapping quantified pieces, or (2) remove unnecessary laziness/quantifiers so the engine does a single, straightforward pass. Here, the camelReg, pascalReg, and kebabReg patterns all use a trailing *? or +? where a simple greedy */+ is sufficient, and the groups they wrap are not actually ambiguous. Removing the laziness and unnecessary non‑capturing groups yields simpler, strictly linear patterns that avoid the flagged nested‑quantifier shape.
Concretely, we can:
- Replace
camelRegwith a standard camelCase pattern that does not use a lazy outer quantifier:^[a-z]+(?:[A-Z0-9][a-z0-9]+)*$. - Replace
pascalRegsimilarly:^(?:[A-Z0-9][a-z0-9]+)+$. - Replace
kebabRegwith^[a-z]+(?:-[a-z0-9]+)*$.
These are equivalent to the originals except that the outer repetition is greedy rather than lazy, which does not change matching behavior in these anchored (^...$) patterns. No additional imports or helper methods are required; we only update the three regex literals on lines 1–3 in packages/eslint-plugin-primer-react/src/utils/casing-matches.js.
-
Copy modified lines R1-R3
| @@ -1,6 +1,6 @@ | ||
| const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/ | ||
| const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/ | ||
| const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/ | ||
| const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*$/ | ||
| const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+$/ | ||
| const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*$/ | ||
|
|
||
| function casingMatches(name, type) { | ||
| switch (type) { |
| @@ -0,0 +1,19 @@ | |||
| const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/ | |||
| const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/ | |||
Check failure
Code scanning / CodeQL
Inefficient regular expression High
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 2 days ago
In general, to fix inefficient regular expressions you should remove ambiguous nested quantifiers—patterns like (...+)+ or (...*)*—by simplifying the grouping or restructuring the expression so the engine does not need to backtrack exponentially. Often, removing an unnecessary outer */+ or converting a repeated complex group into a simpler character class or linear sequence is enough.
In this file, the problematic regex is:
const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/The outer +? applies to the whole group (?:[A-Z0-9][a-z0-9]+), and inside that group [a-z0-9]+ is itself quantified. This nested “one or more of (one uppercase/digit followed by one or more lowercase/digit)” can lead to heavy backtracking when the match fails late (as described by CodeQL). Functionally, this pattern is intended to match PascalCase identifiers: a leading capital or digit, followed by any number of lowercase letters/digits, and then repeated for multiple “words”. However, the outer +? is redundant for the semantics you want: multiple repetitions of that group are already covered by allowing the inner “tail” to be arbitrarily long.
A simpler, equivalent, and safer expression is to require exactly one leading [A-Z0-9] and then allow any number of [a-z0-9] characters after it:
const pascalReg = /^[A-Z0-9][a-z0-9]*$/This matches any non-empty string whose first character is an uppercase letter or digit and whose remaining characters (possibly none) are lowercase letters or digits. That is consistent with the intended Pascal-style casing used here (and also slightly more permissive than the original, since the original required at least one trailing [a-z0-9]; if preserving that exact behavior is required, you can instead use ^[A-Z0-9][a-z0-9]+$, which still removes the nested quantifier). This change only affects line 2 in packages/eslint-plugin-primer-react/src/utils/casing-matches.js; no imports or helper methods are needed.
-
Copy modified line R2
| @@ -1,5 +1,5 @@ | ||
| const camelReg = /^[a-z]+(?:[A-Z0-9][a-z0-9]+)*?$/ | ||
| const pascalReg = /^(?:[A-Z0-9][a-z0-9]+)+?$/ | ||
| const pascalReg = /^[A-Z0-9][a-z0-9]*$/ | ||
| const kebabReg = /^[a-z]+(?:-[a-z0-9]+)*?$/ | ||
|
|
||
| function casingMatches(name, type) { |
| function casingMatches(name, type) { | ||
| switch (type) { | ||
| case 'camel': | ||
| return camelReg.test(name) |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
regular expression
library input
This
regular expression
library input
This
regular expression
library input
This
regular expression
library input
| case 'camel': | ||
| return camelReg.test(name) | ||
| case 'pascal': | ||
| return pascalReg.test(name) |
Check failure
Code scanning / CodeQL
Polynomial regular expression used on uncontrolled data High
regular expression
library input
This
regular expression
library input
This
regular expression
library input
This
Consolidates
eslint-plugin-primer-reactfrom its standalone repository intopackages/eslint-plugin-primer-react/within the monorepo.Package Structure
packages/eslint-plugin-primer-react/.prettierignore,.nvmrc,.changeset/, etc.)devDependencies, now workspace-linkedESLint Configuration
Added exceptions in
eslint.config.mjsfor the plugin package:require/module.exports) - standard for ESLint pluginsDocumentation
primer/eslint-plugin-primer-reacttoprimer/reactChangelog
Changed
eslint-plugin-primer-reactfrom standalone repository topackages/eslint-plugin-primer-react/Rollout strategy
Testing & Reviewing
All 23 ESLint rules with 376 tests maintained and passing. Plugin loads correctly as workspace package.
Merge checklist
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.