Skip to content

feat(migrate): more unsupported rule metadata for better clarity#8864

Merged
dyc3 merged 1 commit intomainfrom
dyc3/migrate-unsupported-rule-reasons
Jan 28, 2026
Merged

feat(migrate): more unsupported rule metadata for better clarity#8864
dyc3 merged 1 commit intomainfrom
dyc3/migrate-unsupported-rule-reasons

Conversation

@dyc3
Copy link
Contributor

@dyc3 dyc3 commented Jan 25, 2026

Summary

This improves the migrate command to give better reasons for why a rule was not migrated. It also lets us mark rules from plugins as well. I'm hoping that this makes it easier for users to make informed decisions on if they switch to biome.

I did all the labeling by hand, but I had gpt-5.2-codex/opus 4.5 partially do some of the tedious stuff like adjusting the printing, and refactoring RuleSource to be more generic. There's a lot of rules and some of my decisions here might be inconsistent.

Here's what the summary at the top looks like (full diagnostic is too big for one screen):

image

The big change here is that we don't just tell the user how many rules have direct biome counterparts, but instead we show how many rules are covered by biome overall. Previously for this project, the migrate command would only show the user that only 24% of rules could be migrated, but that doesn't really paint the full picture.

Additionally, we now tell the user what formatter options cover which rules:

image

Test Plan

Tested manually on a couple open source projects.

Docs

@changeset-bot
Copy link

changeset-bot bot commented Jan 25, 2026

🦋 Changeset detected

Latest commit: a5ea2c8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 13 packages
Name Type
@biomejs/biome Patch
@biomejs/cli-win32-x64 Patch
@biomejs/cli-win32-arm64 Patch
@biomejs/cli-darwin-x64 Patch
@biomejs/cli-darwin-arm64 Patch
@biomejs/cli-linux-x64 Patch
@biomejs/cli-linux-arm64 Patch
@biomejs/cli-linux-x64-musl Patch
@biomejs/cli-linux-arm64-musl Patch
@biomejs/wasm-web Patch
@biomejs/wasm-bundler Patch
@biomejs/wasm-nodejs Patch
@biomejs/backend-jsonrpc Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Contributor Author

dyc3 commented Jan 25, 2026

@github-actions github-actions bot added A-CLI Area: CLI A-Linter Area: linter labels Jan 25, 2026
Base automatically changed from dyc3/migrate-fix-missing-rules to main January 25, 2026 23:52
@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch from 04ec18c to ad5f621 Compare January 26, 2026 01:21
@github-actions github-actions bot added the A-Tooling Area: internal tools label Jan 26, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 26, 2026

Parser conformance results on

js/262

Test result main count This PR count Difference
Total 52864 52864 0
Passed 51646 51646 0
Failed 1176 1176 0
Panics 42 42 0
Coverage 97.70% 97.70% 0.00%

jsx/babel

Test result main count This PR count Difference
Total 38 38 0
Passed 37 37 0
Failed 1 1 0
Panics 0 0 0
Coverage 97.37% 97.37% 0.00%

symbols/microsoft

Test result main count This PR count Difference
Total 6300 6300 0
Passed 2085 2085 0
Failed 4215 4215 0
Panics 0 0 0
Coverage 33.10% 33.10% 0.00%

ts/babel

Test result main count This PR count Difference
Total 626 626 0
Passed 560 560 0
Failed 66 66 0
Panics 0 0 0
Coverage 89.46% 89.46% 0.00%

ts/microsoft

Test result main count This PR count Difference
Total 18855 18855 0
Passed 14054 14054 0
Failed 4800 4800 0
Panics 1 1 0
Coverage 74.54% 74.54% 0.00%

@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch from ad5f621 to 841a4c7 Compare January 26, 2026 20:20
@dyc3 dyc3 marked this pull request as ready for review January 26, 2026 20:43
@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch 2 times, most recently from 44a85a6 to a7f4f43 Compare January 26, 2026 20:46
@github-actions github-actions bot removed the A-Tooling Area: internal tools label Jan 26, 2026
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 26, 2026

Walkthrough

This PR makes RuleSource lifetime-generic (RuleSource<'a>) and derives Copy, PartialEq, Eq and Hash. Display, ordering and URL/name generation were updated to be lifetime-aware and a const namespace() plus to_namespaced_rule_name() were added. The ESLint→Biome migration now records unsupported rules with explicit UnsupportedRuleReason variants (Stylistic, FormatterCovers, FormatterOption, KnownSourceNotImplemented, UnknownSource) and replaces the previous stylistic/unsupported sets with a BTreeMap of unsupported rules. A new unsupported_rules module exports a pre-sorted UNSUPPORTED_RULES constant and migration diagnostics were refactored to present a categorized breakdown of unsupported rules.

Possibly related PRs

Suggested labels

A-Tooling

Suggested reviewers

  • ematipico
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding metadata for unsupported rules during ESLint migration to provide better clarity on why rules aren't migrated.
Description check ✅ Passed The description is well-related to the changeset, explaining the motivation (better reasons for unsupported rules), implementation approach (manual labelling with AI assistance), and impact on user experience with example screenshots.

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

✨ Finishing touches
  • 📝 Generate docstrings

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

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Fix all issues with AI agents
In @.changeset/smooth-sites-sip.md:
- Line 5: Update the changeset summary to use present tense: change the phrase
"will now specify a reason why a rule was not migrated" to present-tense wording
such as "specifies a reason why a rule was not migrated" (or "now specifies why
a rule was not migrated") and similarly adjust "It will now specify" to "It now
specifies" in the .changeset/smooth-sites-sip.md summary referencing the `biome
migrate eslint` behavior so the message conforms to project tense conventions.

In `@crates/biome_cli/src/execute/migrate/eslint_to_biome.rs`:
- Around line 258-266: Replace the typo in the log message passed to
visitor.record_log in the eslint_to_biome migration: change "so you don't loose
the functionality" to "so you don't lose the functionality" in the markup!
string used when formatter_covers is non-empty (the call site is the
visitor.record_log invocation that logs "These rules enforce behavior completely
covered by the formatter (so you don't loose the functionality):").

In `@crates/biome_cli/src/execute/migrate/unsupported_rules.rs`:
- Around line 8-10: Update the header comment above the UNSUPPORTED_RULES
constant to accurately reflect that the list contains rules from core ESLint
plus plugins (e.g., Jest, React, Stylistic, TypeScript, Vue) and that it remains
sorted for binary search; locate the constant named UNSUPPORTED_RULES and revise
its preceding comment to mention these plugin sources and the sorting rationale
so the intent is clear.

Comment on lines +8 to +10
// Sorted ESLint unsupported rules.
/// The array is sorted to allow binary search.
pub const UNSUPPORTED_RULES: &[UnsupportedRule] = &[
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clarify the header comment to include plugin sources.

The list includes Jest/React/Stylistic/TypeScript/Vue rules too, so “ESLint” alone is a tad narrow.

✏️ Suggested tweak
-// Sorted ESLint unsupported rules.
+// Sorted ESLint and plugin unsupported rules.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Sorted ESLint unsupported rules.
/// The array is sorted to allow binary search.
pub const UNSUPPORTED_RULES: &[UnsupportedRule] = &[
// Sorted ESLint and plugin unsupported rules.
/// The array is sorted to allow binary search.
pub const UNSUPPORTED_RULES: &[UnsupportedRule] = &[
🤖 Prompt for AI Agents
In `@crates/biome_cli/src/execute/migrate/unsupported_rules.rs` around lines 8 -
10, Update the header comment above the UNSUPPORTED_RULES constant to accurately
reflect that the list contains rules from core ESLint plus plugins (e.g., Jest,
React, Stylistic, TypeScript, Vue) and that it remains sorted for binary search;
locate the constant named UNSUPPORTED_RULES and revise its preceding comment to
mention these plugin sources and the sorting rationale so the intent is clear.

@dyc3 dyc3 requested review from a team January 26, 2026 21:27
Copy link
Member

@Conaclos Conaclos left a comment

Choose a reason for hiding this comment

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

I love the improvements! Very nice work! I think we can slightly improve the diagnostic :)

@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch from a7f4f43 to b2cf77d Compare January 26, 2026 21:29
@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch from b2cf77d to 8b00900 Compare January 26, 2026 21:34
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@crates/biome_cli/src/execute/migrate/eslint_to_biome.rs`:
- Around line 131-170: The formatter_covers_count calculation incorrectly
includes UnsupportedRuleReason::Stylistic and
UnsupportedRuleReason::FormatterOption which inflates coverage; change the logic
in the computation of formatter_covers_count (the filter over self.unsupported)
to only count UnsupportedRuleReason::FormatterCovers, introduce separate
counters for Stylistic and FormatterOption (e.g., stylistic_count,
formatter_option_count) and then compute
total_migratable_count/total_covered_count/total_covered_percent using only the
appropriate buckets (exclude stylistic/formatter-option from "obsolete"
coverage), and update the user-facing messages that print
formatter_covers_count/total_covered_percent to reflect the new breakdown and
any mention of --include-inspired/--include-nursery behavior.

@Conaclos
Copy link
Member

Conaclos commented Jan 26, 2026

Also, I've just noticed that there are no tests for rules covered by the formatter.

@dyc3 dyc3 force-pushed the dyc3/migrate-unsupported-rule-reasons branch from 8b00900 to a5ea2c8 Compare January 26, 2026 21:47
@dyc3 dyc3 merged commit 5e97119 into main Jan 28, 2026
15 checks passed
@dyc3 dyc3 deleted the dyc3/migrate-unsupported-rule-reasons branch January 28, 2026 17:21
@github-actions github-actions bot mentioned this pull request Jan 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-CLI Area: CLI A-Linter Area: linter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants