-
-
Notifications
You must be signed in to change notification settings - Fork 719
feat(analyse/json): add noDuplicateDependencies
rule
#7142
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
Conversation
🦋 Changeset detectedLatest commit: 033b270 The changes in this PR will be included in the next version bump. This PR includes changesets to release 13 packages
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 |
noDuplicateDependencies
rule
d3ee76f
to
f49c3e8
Compare
WalkthroughAdds a nursery lint rule Possibly related PRs
Suggested reviewers
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 💡 Knowledge Base configuration:
You can enable these sources in your CodeRabbit configuration. ⛔ Files ignored due to path filters (5)
📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (2)**/*.{rs,toml}📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
crates/biome_*/**📄 CodeRabbit inference engine (CLAUDE.md)
Files:
🧠 Learnings (4)📓 Common learnings
📚 Learning: 2025-09-05T09:13:58.901Z
Applied to files:
📚 Learning: 2025-08-11T11:50:12.090Z
Applied to files:
📚 Learning: 2025-09-05T09:13:58.901Z
Applied to files:
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
🔇 Additional comments (1)
✨ Finishing Touches
🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
f49c3e8
to
6e1419f
Compare
6e1419f
to
cfcdb11
Compare
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
CodSpeed Performance ReportMerging #7142 will degrade performances by 6.91%Comparing Summary
Benchmarks breakdown
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
crates/biome_json_analyze/src/lint/nursery.rs (1)
1-3
: Remove duplicate generated file commentThe "Generated file, do not edit by hand" comment appears twice. This duplication should be fixed in the codegen script.
🧹 Nitpick comments (4)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json (1)
1-6
: Optional: give the versions a realistic placeholder.Using an empty string as a version works for the test harness but a dummy semver such as
"0.0.0"
makes the fixture self-explanatory to new contributors..changeset/seven-bats-write.md (1)
5-7
: Rephrase for clarity & bump version?
- Style: “detects if there isn’t a dependency listed twice” is a double negative. Suggest:
-Added the new nursery rule `noDuplicateDependencies`, which detects if there isn't a dependency listed twice. +Added the new nursery rule `noDuplicateDependencies`, which reports when the same dependency is declared more than once.
- Semver: adding a new lint rule is a user-visible feature, usually tagged as minor, not patch. Consider:
-"@biomejs/biome": patch +"@biomejs/biome": minorcrates/biome_configuration/src/analyzer/linter/rules.rs (2)
4479-4768
: Systematic addition looks correct.The
no_duplicate_dependencies
rule is properly integrated into theget_enabled_rules
method with correct index handling. All subsequent indices have been appropriately incremented.Consider refactoring this repetitive pattern using a macro or helper function to reduce maintenance burden and potential for index errors.
4793-5082
: Systematic addition looks correct.The
no_duplicate_dependencies
rule is properly integrated into theget_disabled_rules
method with correct index handling.Same refactoring opportunity as in
get_enabled_rules
- consider using a macro or helper to reduce repetition.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json.snap
is excluded by!**/*.snap
📒 Files selected for processing (13)
.changeset/seven-bats-write.md
(1 hunks)crates/biome_analyze/src/rule.rs
(5 hunks)crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
(1 hunks)crates/biome_configuration/src/analyzer/linter/rules.rs
(12 hunks)crates/biome_diagnostics_categories/src/categories.rs
(1 hunks)crates/biome_json_analyze/src/lint/nursery.rs
(1 hunks)crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
(1 hunks)crates/biome_rule_options/src/lib.rs
(1 hunks)crates/biome_rule_options/src/no_duplicate_dependencies.rs
(1 hunks)packages/@biomejs/backend-jsonrpc/src/workspace.ts
(5 hunks)packages/@biomejs/biome/configuration_schema.json
(3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just format
Format Rust and TOML files using
just f
(alias forjust format
).
Files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
**/*.rs
📄 CodeRabbit Inference Engine (CONTRIBUTING.md)
Update documentation for new features or changes, using inline rustdoc for rules, assists, and their options.
Files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
.changeset/*.md
📄 CodeRabbit Inference Engine (CONTRIBUTING.md)
.changeset/*.md
: Changeset descriptions should be about user-facing changes, use past tense for what you did, present tense for Biome behavior, reference issues/rules/assists with links, include code blocks when applicable, and end every sentence with a full stop.
Headers in changesets should use####
or#####
only; other headers may break the changelog.
Files:
.changeset/seven-bats-write.md
🧠 Learnings (60)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: You are encouraged to split the work for a new rule into multiple PRs and describe your plan in an issue if unfamiliar with Biome's APIs.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_duplicate*_*.rs : Rules that report duplicate entities should use the `noDuplicate<Concept>` naming convention (e.g., `noDuplicateObjectKeys`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When deprecating a rule, specify the reason using the `deprecated:` field in the `declare_lint_rule!` macro.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : New rules must be placed inside the `nursery` group for incubation before promotion.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_redundant*_*.rs : Rules that report redundant code should use the `noRedundant<Concept>` naming convention (e.g., `noRedundantUseStrict`).
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a rule provides a code action, add the `fix_kind` metadata to the `declare_lint_rule!` macro and implement the `action` function.
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Create new lint rules using `just new-js-lintrule`, `just new-css-lintrule`, `just new-json-lintrule`, or `just new-graphql-lintrule`, and the rule name must be camelCase
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `version` field in `declare_lint_rule!` must be set to `next` for new rules.
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Applies to crates/biome_lint_rules/**/*.rs : Linter rules must have a `version` metadata field in their implementation, set to "next" for new rules and updated to the new version when releasing.
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Assign the `domains` field in `declare_lint_rule!` if the rule belongs to a specific domain (e.g., testing, framework).
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_duplicate*_*.rs : rules that report ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_duplicate*_*.rs : Rules that report duplicate entities should use the `noDuplicate<Concept>` naming convention (e.g., `noDuplicateObjectKeys`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_rule_options/lib/*.rs : rule options must be placed inside the...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/*.rs : Rule options must be placed inside the `biome_rule_options` crate, with a file named after the rule (e.g., `use_this_convention.rs`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : new rules must be placed inside ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : New rules must be placed inside the `nursery` group for incubation before promotion.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_redundant*_*.rs : rules that report ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_redundant*_*.rs : Rules that report redundant code should use the `noRedundant<Concept>` naming convention (e.g., `noRedundantUseStrict`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : rule options must be documented ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule options must be documented in the `## Options` section of the rule's documentation, with each option having its own header and example.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
packages/@biomejs/biome/configuration_schema.json
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : the `version` field in `declare_...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `version` field in `declare_lint_rule!` must be set to `next` for new rules.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_rule_options/lib/*.rs : use boxed slices (`box<[box]>`) i...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/*.rs : Use boxed slices (`Box<[Box<str>]>`) instead of `Vec<String>` for string arrays in rule options to save memory.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : if a lint rule is ported from an...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a lint rule is ported from another ecosystem (e.g., ESLint), add a `sources` metadata field in `declare_lint_rule!` referencing the original rule.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : when deprecating a rule, specify...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When deprecating a rule, specify the reason using the `deprecated:` field in the `declare_lint_rule!` macro.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no*_*.rs : rules that forbid a single c...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no*_*.rs : Rules that forbid a single concept should be named using the `no<Concept>` prefix (e.g., `noDebugger` for disallowing `debugger` statements).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_useless*_*.rs : rules that report un...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_useless*_*.rs : Rules that report unnecessary code should use the `noUseless<Concept>` naming convention (e.g., `noUselessConstructor`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unused*_*.rs : rules that report unu...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unused*_*.rs : Rules that report unused entities should use the `noUnused<Concept>` naming convention (e.g., `noUnusedVariables`).
Applied to files:
crates/biome_rule_options/src/lib.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : when banning certain functions o...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When banning certain functions or variables, always check if the variable is global using the semantic model to avoid false positives.
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_undeclared*_*.rs : rules that report...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_undeclared*_*.rs : Rules that report undeclared entities should use the `noUndeclared<Concept>` naming convention (e.g., `noUndeclaredVariables`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use*_*.rs : rules that mandate a single...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use*_*.rs : Rules that mandate a single concept should be named using the `use<Concept>` prefix (e.g., `useValidLang` for mandating valid HTML `lang` attribute values).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to **/cargo.toml : use path dependencies for dev-dependencies in cargo.toml to avoid requiri...
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Applies to **/Cargo.toml : Use path dependencies for dev-dependencies in Cargo.toml to avoid requiring published versions.
Applied to files:
crates/biome_rule_options/src/lib.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unknown*_*.rs : rules that report un...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unknown*_*.rs : Rules that report unknown entities (e.g., CSS units) should use the `noUnknown<Concept>` naming convention (e.g., `noUnknownUnit`).
Applied to files:
crates/biome_rule_options/src/lib.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : update the `language` field in `...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Update the `language` field in `declare_lint_rule!` to match the language the rule applies to (e.g., `js`, `jsx`, `ts`, `tsx`).
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
.changeset/seven-bats-write.md
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : set the `severity` field in `dec...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Set the `severity` field in `declare_lint_rule!` to `Severity::Warning` or `Severity::Error` as appropriate for the rule.
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : if a rule provides a code action...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : If a rule provides a code action, add the `fix_kind` metadata to the `declare_lint_rule!` macro and implement the `action` function.
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : assign the `domains` field in `d...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Assign the `domains` field in `declare_lint_rule!` if the rule belongs to a specific domain (e.g., testing, framework).
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
packages/@biomejs/biome/configuration_schema.json
crates/biome_json_analyze/src/lint/nursery.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : the `declare_lint_rule!` macro m...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `declare_lint_rule!` macro must be used to declare an analyzer rule type and implement the RuleMeta trait.
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_analyze/src/rule.rs
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : when implementing the `run` func...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When implementing the `run` function for a rule, prefer transforming `Result` into `Option` and using the `?` operator for concise code.
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : the `rule_category!` macro shoul...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : The `rule_category!` macro should be used in diagnostics to statically inject the category at compile time.
Applied to files:
crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_diagnostics/crates/biome_diagnostics_categories/src/categories.rs : when dec...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:35.163Z
Learning: Applies to crates/biome_diagnostics/crates/biome_diagnostics_categories/src/categories.rs : When declaring a new diagnostic category, add it to crates/biome_diagnostics_categories/src/categories.rs to ensure it is statically registered.
Applied to files:
crates/biome_diagnostics_categories/src/categories.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{use*,no*}_*{vue,react,angular,svelte}*.rs : If a rule overwhelmingly applies to a specific framework, it should be named using the `use<Framework>...` or `no<Framework>...` pattern (e.g., `noVueReservedProps`).
Applied to files:
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_excessive*_*.rs : rules that report ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_excessive*_*.rs : Rules that report code exceeding certain limits should use the `noExcessive<Concept>` naming convention (e.g., `noExcessiveNestedTestSuites`).
Applied to files:
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: create new lint rules using `just new-js-lintrule`, `just new-css-lintrule`, `just new-json-lintrule...
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Create new lint rules using `just new-js-lintrule`, `just new-css-lintrule`, `just new-json-lintrule`, or `just new-graphql-lintrule`, and the rule name must be camelCase
Applied to files:
crates/biome_diagnostics_categories/src/categories.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : rule documentation must start wi...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Rule documentation must start with a single-line summary, followed by detailed paragraphs, and include `## Examples` with `### Invalid` and `### Valid` sections.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_misleading*_*.rs : rules that report...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_misleading*_*.rs : Rules that report misleading code should use the `noMisleading<Concept>` naming convention (e.g., `noMisleadingCharacterClass`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_restricted*_*.rs : rules that report...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_restricted*_*.rs : Rules that report restricted entities should use the `noRestricted<Concept>` naming convention (e.g., `noRestrictedGlobals`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_consistent*_*.rs : rules that ensur...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/use_consistent*_*.rs : Rules that ensure consistency should use the `useConsistent<Concept>` naming convention (e.g., `useConsistentArrayType`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{no_invalid*,use_valid*}_*.rs : rules t...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/{no_invalid*,use_valid*}_*.rs : Rules that report invalid code should use the `noInvalid<Concept>` or `useValid<Concept>` naming conventions (e.g., `noInvalidConstructorSuper`, `useValidTypeof`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_empty*_*.rs : rules that report empt...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_empty*_*.rs : Rules that report empty code constructs should use the `noEmpty<Concept>` naming convention (e.g., `noEmptyBlockStatements`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unsafe*_*.rs : rules that report uns...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/no_unsafe*_*.rs : Rules that report unsafe code should use the `noUnsafe<Concept>` naming convention (e.g., `noUnsafeOptionalChaining`).
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: move rules from nursery to stable group using `just move-rule stable rulename`...
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Move rules from nursery to stable group using `just move-rule stable ruleName`
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : when a rule needs to query multi...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : When a rule needs to query multiple node types, use the `declare_node_union!` macro to define a union type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
crates/biome_json_analyze/src/lint/nursery.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : for rules that emit multiple dia...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : For rules that emit multiple diagnostics or actions, use an iterable type (e.g., `Box<[_]>`) for the `Signals` associated type.
Applied to files:
crates/biome_configuration/src/analyzer/linter/rules.rs
📚 Learning: applies to crates/biome_analyze/biome_rule_options/lib/*.rs : rule option structs must derive `deser...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_rule_options/lib/*.rs : Rule option structs must derive `Deserializable`, `Serialize`, `Deserialize`, and (optionally) `JsonSchema` for configuration and schema support.
Applied to files:
crates/biome_rule_options/src/no_duplicate_dependencies.rs
crates/biome_analyze/src/rule.rs
packages/@biomejs/backend-jsonrpc/src/workspace.ts
packages/@biomejs/biome/configuration_schema.json
📚 Learning: applies to crates/biome_diagnostics/**/*.rs : when implementing the diagnostic trait, use the #[deri...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:35.163Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : When implementing the Diagnostic trait, use the #[derive(Diagnostic)] procedural macro to simplify implementation.
Applied to files:
crates/biome_rule_options/src/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_diagnostics/**/*.rs : #[derive(diagnostic)] also works in enums, assuming ev...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_diagnostics/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:35.163Z
Learning: Applies to crates/biome_diagnostics/**/*.rs : #[derive(Diagnostic)] also works in enums, assuming every variant contains a type that is itself a diagnostic.
Applied to files:
crates/biome_rule_options/src/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_js_type_info/src/type_info.rs : avoid circular or recursive data structures ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:51:23.437Z
Learning: Applies to crates/biome_js_type_info/src/type_info.rs : Avoid circular or recursive data structures in type representations; use `TypeReference` and `TypeData::Reference` to refer to other types instead.
Applied to files:
crates/biome_rule_options/src/no_duplicate_dependencies.rs
📚 Learning: applies to crates/biome_lint_rules/**/*.rs : linter rules must have a `version` metadata field in th...
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Applies to crates/biome_lint_rules/**/*.rs : Linter rules must have a `version` metadata field in their implementation, set to "next" for new rules and updated to the new version when releasing.
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: applies to **/*.rs : update documentation for new features or changes, using inline rustdoc for rule...
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Applies to **/*.rs : Update documentation for new features or changes, using inline rustdoc for rules, assists, and their options.
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: applies to **/*.{rs,toml} : format code (rust + toml) using `just format`...
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Applies to **/*.{rs,toml} : Format code (Rust + TOML) using `just format`
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: applies to **/*.{rs,toml} : format rust and toml files using `just f` (alias for `just format`)....
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: Applies to **/*.{rs,toml} : Format Rust and TOML files using `just f` (alias for `just format`).
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: applies to crates/biome_js_formatter/**/*.rs : use the `dbg_write!` macro to output the written ir e...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:51:05.640Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Use the `dbg_write!` macro to output the written IR elements to the console for debugging formatter output.
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: format your code with `just f` and lint with `just l` before committing....
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Format your code with `just f` and lint with `just l` before committing.
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: applies to crates/biome_parser/crates/biome_*/**/*.rs : parse rule functions must be prefixed with `...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_parser/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:51:51.355Z
Learning: Applies to crates/biome_parser/crates/biome_*/**/*.rs : Parse rule functions must be prefixed with `parse_` and use the name defined in the grammar file (e.g., `parse_for_statement`).
Applied to files:
crates/biome_analyze/src/rule.rs
📚 Learning: the file `packages/@biomejs/biome/configuration_schema.json` is auto-generated and should not be man...
Learnt from: dyc3
PR: biomejs/biome#7081
File: packages/@biomejs/biome/configuration_schema.json:7765-7781
Timestamp: 2025-08-05T14:43:29.581Z
Learning: The file `packages/biomejs/biome/configuration_schema.json` is auto-generated and should not be manually edited or reviewed for schema issues; any changes should be made at the code generation source.
Applied to files:
packages/@biomejs/backend-jsonrpc/src/workspace.ts
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
packages/@biomejs/biome/configuration_schema.json
📚 Learning: document and test the effect of rule options as part of the rule's documentation and test suite....
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Document and test the effect of rule options as part of the rule's documentation and test suite.
Applied to files:
packages/@biomejs/backend-jsonrpc/src/workspace.ts
📚 Learning: applies to crates/biome_analyze/tests/specs/*/*/*.jsonc : files ending with `.jsonc` in snapshot tes...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/tests/specs/*/*/*.jsonc : Files ending with `.jsonc` in snapshot tests should contain arrays of code snippets for script environments.
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
📚 Learning: applies to crates/biome_aria_metadata/{aria-data.json,packages/aria-data/aria-data-*.json} : `aria-d...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_aria_metadata/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:25.072Z
Learning: Applies to crates/biome_aria_metadata/{aria-data.json,packages/aria-data/aria-data-*.json} : `aria-data.json` is a symlink to `packages/aria-data/aria-data-<version>.json`.
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
📚 Learning: applies to crates/biome_formatter/**/cargo.toml : update the `cargo.toml` file to include the specif...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:56.365Z
Learning: Applies to crates/biome_formatter/**/Cargo.toml : Update the `Cargo.toml` file to include the specified `[dev-dependencies]` for testing utilities.
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
📚 Learning: applies to crates/biome_analyze/tests/specs/*/*/{invalid*,valid*}* : snapshot tests for rules should...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/tests/specs/*/*/{invalid*,valid*}* : Snapshot tests for rules should be placed in `tests/specs/<group>/<rule_name>/` with files prefixed by `invalid` or `valid`.
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
📚 Learning: applies to crates/biome_formatter/tests/specs/html/**/options.json : if you require non-default form...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:56.365Z
Learning: Applies to crates/biome_formatter/tests/specs/html/**/options.json : If you require non-default formatting options for tests, create an `options.json` file in the same folder as the `.html` files. These options will apply to all files in that folder.
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json
📚 Learning: if you add a new nursery rule, send a pr to the maintenance branch `main`....
Learnt from: CR
PR: biomejs/biome#0
File: CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:49:35.574Z
Learning: If you add a new nursery rule, send a PR to the maintenance branch `main`.
Applied to files:
.changeset/seven-bats-write.md
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : avoid deep indentation by using ...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Avoid deep indentation by using combinators like `map`, `filter`, and `and_then` instead of nested `if let` or `match` statements.
Applied to files:
crates/biome_json_analyze/src/lint/nursery.rs
📚 Learning: applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : each code block in rule document...
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-05T14:50:18.454Z
Learning: Applies to crates/biome_analyze/biome_*/lib/src/lint/nursery/*.rs : Each code block in rule documentation must specify a language and use `expect_diagnostic` for invalid examples.
Applied to files:
crates/biome_json_analyze/src/lint/nursery.rs
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🔇 Additional comments (23)
crates/biome_rule_options/src/lib.rs (1)
55-55
: Module insertion is correctly alphabetised – thumbs-up.
no_duplicate_dependencies
slot sits betweenno_duplicate_custom_properties
andno_duplicate_else_if
, preserving lexicographic order of the public mods list.
No further action needed.crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json (1)
6-9
: Nice illustrative duplicate – good job.The fixture clearly covers the cross-section duplication case (
dependencies
vsdevDependencies
). Nothing to change.crates/biome_diagnostics_categories/src/categories.rs (1)
157-158
: Category entry looks perfect.Entry is lexicographically placed after
noDuplicateAtImportRules
, URL slug matches rule name, and the macro comment remains intact.crates/biome_cli/src/execute/migrate/eslint_any_rule_to_biome.rs (1)
2060-2083
: LGTM! ESLint duplicate dependency rules properly mapped to Biome.The implementation correctly maps both
package-json-dependencies/duplicate-dependencies
andpackage-json/unique-dependencies
to Biome'sno_duplicate_dependencies
rule in the nursery group. The pattern is consistent with other nursery rules and appropriately handles theinclude_nursery
option.Since this is a generated file, any future changes should be made to the code generator rather than manual edits.
crates/biome_rule_options/src/no_duplicate_dependencies.rs (1)
1-7
: LGTM!The options struct correctly derives all required traits and follows the established pattern, even though no configuration options are currently needed.
crates/biome_analyze/src/rule.rs (1)
160-372
: LGTM!The new
EslintPackageJson
andEslintPackageJsonDependencies
variants are consistently implemented across all trait methods, following the established patterns.crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (1)
10-45
: Rule metadata looks good!The rule correctly follows the
noDuplicate<Concept>
naming convention and includes appropriate ESLint source references.packages/@biomejs/biome/configuration_schema.json (1)
2857-2866
: 🔧 Verify autogenerated schema modificationsThe file
packages/@biomejs/biome/configuration_schema.json
is auto-generated. Please ensure that your additions in lines 2857–2866 come from running the schema generator, not manual edits. If they’re manual tweaks, update the code-gen source and regenerate the file instead.packages/@biomejs/backend-jsonrpc/src/workspace.ts (5)
1570-1573
: Well-documented rule addition.The JSDoc documentation clearly describes the rule's purpose. The property follows the established naming pattern for the nursery group.
2903-2905
: Consistent type configuration pattern.The type alias follows the exact same pattern as other rule configurations in the codebase, maintaining consistency.
5123-5132
: Proper rule options interface structure.The interface follows the established pattern with correct JSDoc documentation for both
level
andoptions
properties.
7863-7863
: Empty options interface ready for future extension.The empty options interface follows the pattern used by other rules without configuration options, allowing for future extensibility.
8577-8577
: Category string properly integrated.The new category string is correctly inserted in alphabetical order within the nursery lint rules union type.
crates/biome_configuration/src/analyzer/linter/rules.rs (10)
142-142
: LGTM!Correct placement in alphabetical order and follows the
noDuplicate<Concept>
naming convention.
491-491
: LGTM!String representation follows the correct camelCase convention and maintains alphabetical ordering.
844-844
: LGTM!Correctly assigns the new rule to the
Nursery
group, following the convention for new rules.
1097-1097
: Verify this rule group change is intentional.The
UseNamingConvention
rule is being moved fromNursery
toStyle
group. Ensure this change is intentional and within the scope of this PR, or if it should be part of a separate PR for rule promotion.
1198-1198
: LGTM!String parsing case correctly added in alphabetical order.
4305-4313
: LGTM!Proper addition of the rule to the
Nursery
struct with clear documentation and correct type definition. The rule is correctly added toGROUP_RULES
array.
4447-4447
: LGTM!New rule correctly added to the
ALL_RULES_AS_FILTERS
array at the appropriate index.
5129-5132
: LGTM!Rule configuration lookup correctly implemented following the established pattern.
5373-5373
: LGTM!Rule initialization correctly added to the
From<GroupPlainConfiguration>
implementation.
4373-4384
: Please verify the recommended rule indices manuallyThe index shifts look correct at a glance, but our script couldn’t locate the
GROUP_RULES
block to confirm. To be safe, double-check that eachSelf::GROUP_RULES[…]
entry matches the intended rule name:• Extract the full
GROUP_RULES
list and number each entry
• Extract theRECOMMENDED_RULES_AS_FILTERS
block and ensure the indices line up
if path.ends_with(PACKAGE_JSON) { | ||
for member in query.json_member_list().iter().flatten() { | ||
let name = member.name(); | ||
|
||
if let Ok(name) = name { | ||
let text = name.inner_string_text(); | ||
if let Ok(text) = text { | ||
if PROPERTY_KEYS.contains(&text.text()) { | ||
let value = member.value().ok(); | ||
|
||
for dependency in value | ||
.unwrap() | ||
.as_json_object_value() | ||
.unwrap() | ||
.json_member_list() | ||
.iter() | ||
.flatten() | ||
{ | ||
let dependency_name = dependency.name(); | ||
|
||
if let Ok(dependency_name) = dependency_name { | ||
let dependency_text = dependency_name.inner_string_text(); | ||
if let Ok(dependency_text) = dependency_text { | ||
if let Some(original_member) = | ||
seen.get(dependency_text.text()) | ||
{ | ||
if let Some(ranges) = | ||
duplicates.get_mut(original_member) | ||
{ | ||
ranges.push(dependency_name.range()); | ||
} else { | ||
duplicates.insert( | ||
original_member.clone(), | ||
vec![dependency_name.range()], | ||
); | ||
} | ||
} else { | ||
seen.insert( | ||
dependency_text.to_string(), | ||
dependency_name, | ||
); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Reduce nesting using combinators
The function has excessive nesting (6+ levels). Per Biome's contributing guidelines, use combinators to improve readability.
Consider extracting the dependency checking logic into a helper function and using iterator combinators:
fn check_dependencies(member: &JsonMember) -> Option<impl Iterator<Item = (String, JsonMemberName)>> {
let name = member.name().ok()?;
let text = name.inner_string_text().ok()?;
if !PROPERTY_KEYS.contains(&text.text()) {
return None;
}
let value = member.value().ok()?;
let object_value = value.as_json_object_value()?;
Some(object_value.json_member_list()
.iter()
.flatten()
.filter_map(|dep| {
let dep_name = dep.name().ok()?;
let dep_text = dep_name.inner_string_text().ok()?;
Some((dep_text.to_string(), dep_name))
}))
}
Then use it in the main loop to reduce nesting significantly.
🤖 Prompt for AI Agents
In crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs from
lines 69 to 118, the code has excessive nested if-let and unwrap calls making it
hard to read. Refactor by extracting the dependency checking logic into a helper
function that returns an iterator over dependencies using combinators and early
returns to reduce nesting. Then, in the main loop, call this helper to iterate
dependencies, simplifying the control flow and improving readability.
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json.snap
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/package.json.snap
Outdated
Show resolved
Hide resolved
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
♻️ Duplicate comments (1)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap.new (1)
26-26
: Name the conflicting group to reduce hunt time.Same suggestion as above; explicitly mention “peerDependencies”.
- i The dependency "foo" is also listed in another dependency group. + i The dependency "foo" is also listed in "peerDependencies".
🧹 Nitpick comments (13)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json (1)
4-6
: Optional: add a variant with differing version specs.Consider a sibling fixture where "foo" appears twice with different version ranges (e.g. "^1.0.0" and "~1.0.0") to confirm the rule flags duplicates regardless of version text.
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json (1)
2-2
: Rename package “name” to reflect that this is a valid-case fixture.The file lives under valid/, but the name says "invalid-...". Recommend aligning for clarity (future readers will thank you).
- "name": "invalid-optional-dependencies-dev-dependencies", + "name": "valid-optional-dependencies-dev-dependencies",crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json (1)
3-7
: Nice coverage for duplicate entries inside bundleDependencies array.Solid invalid fixture. One more for the road: consider adding
- bundledDependencies (the alias) with a duplicate, and
- a cross-group duplicate between bundledDependencies and bundleDependencies.
This helps ensure both aliases are handled and cross-aliased duplicates are caught.
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (5)
11-36
: Tighten the rule docs (mention all covered sections and arrays)The summary currently mentions dependencies/devDependencies only. The rule also covers optionalDependencies, peerDependencies, bundleDependencies/bundledDependencies (arrays), and intra-group duplicates. Small doc tweak keeps users on the same page as the implementation and tests.
Example tweak:
- Expand the first line to “Disallow specifying the same dependency more than once across package.json sections (dependencies, devDependencies, optionalDependencies, peerDependencies) and within bundleDependencies/bundledDependencies arrays.”
- Add an invalid example for bundledDependencies duplicate strings.
79-89
: Early-exit on non-package.json to avoid extra workYou parse the root before checking the path. Cheap win: gate on package.json first.
Apply this diff:
fn run(ctx: &RuleContext<Self>) -> Self::Signals { - let query = ctx.query(); - let path = ctx.file_path(); - - let value = query.value().ok()?; - let object_value = value.as_json_object_value()?; - - if !path.ends_with(PACKAGE_JSON) { - return None; - } + let query = ctx.query(); + let path = ctx.file_path(); + if !path.ends_with(PACKAGE_JSON) { + return None; + } + + let value = query.value().ok()?; + let object_value = value.as_json_object_value()?;
93-110
: Reduce nesting in the group filterThe nested Ok/if blocks hurt readability. Let-chaining or combinators keep it tidy and align with project guidelines.
Apply this diff:
- let groups = object_value - .json_member_list() - .iter() - .flatten() - .filter(|member| { - let name = member.name(); - if let Ok(name) = name { - let text = name.inner_string_text(); - if let Ok(text) = text { - if DUPLICATE_PROPERTY_KEYS.contains(&text.text()) { - return true; - } - } - } - return false; - }); + let groups = object_value + .json_member_list() + .iter() + .flatten() + .filter(|member| { + member + .name() + .ok() + .and_then(|n| n.inner_string_text().ok()) + .map_or(false, |t| DUPLICATE_PROPERTY_KEYS.contains(&t.text())) + });
119-173
: Duplicate-handling logic is repeated; extract a helperThe “insert or accumulate” block is duplicated for object and array cases. A small helper removes noise and potential mistakes.
You can add this helper outside run:
fn push_duplicate( dst: &mut FxHashMap<JsonSyntaxToken, Vec<TextRange>>, original: &JsonSyntaxToken, duplicate_range: TextRange, ) { if let Some(ranges) = dst.get_mut(original) { ranges.push(duplicate_range); } else { dst.insert(original.clone(), vec![duplicate_range]); } }Then replace both occurrences of:
if let Some(original_member) = deps.get(&dependency_text.to_string()) { if let Some(ranges) = duplicates.get_mut(original_member) { ranges.push(dependency_name.range()); } else { duplicates.insert(original_member.clone(), vec![dependency_name.range()]); } } else { /* insert */ }with a call to push_duplicate(...).
127-140
: Avoid repeated to_string allocations when keying depsMinor perf/readability: dependency_text.to_string() is called multiple times. Cache once per loop iteration.
Example:
- if let Some(original_member) = deps.get(&dependency_text.to_string()) { + let dep_key = dependency_text.text().to_owned(); + if let Some(original_member) = deps.get(&dep_key) { @@ - deps.insert( - dependency_text.to_string(), + deps.insert( + dep_key, dependency_name.value_token().ok()?, );Do the same in the array branch.
Also applies to: 155-167
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap.new (1)
21-42
: Good coverage for intra-array duplicates in bundleDependenciesNice to see arrays covered too. Consider adding a mirrored test for bundledDependencies to keep alias behaviour symmetric.
.changeset/seven-bats-write.md (3)
7-7
: End the sentence with a full stop (style guide).Tiny punctuation nit to match the changeset conventions.
-For example, the following snippets will trigger the rule: +For example, the following snippets will trigger the rule.
31-40
: Add an overrides example to mirror the enumerated sections.You list
overrides
among the checked sections; adding a representative snippet helps readers.} }+```json
+{
- "dependencies": {
- "foo": ""
- },
- "overrides": {
- "foo": ""
- }
+}
+```
2-3
: Confirm packages in the changeset.Schema/type changes touched packages beyond
@biomejs/biome
(e.g.packages/@biomejs/backend-jsonrpc
). If those need publishing, include them here; otherwise, all good.Proposed frontmatter (only if a publish is intended for backend-jsonrpc):
--- "@biomejs/biome": patch +"@biomejs/backend-jsonrpc": patch ---
Would you like me to adjust the changeset to include the extra package(s)?
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new (1)
26-26
: Make the message name the conflicting group for clarity.Calling out the specific other group improves UX, especially in large package.json files.
- i The dependency "foo" is also listed in another dependency group. + i The dependency "foo" is also listed in "devDependencies".
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these settings in your CodeRabbit configuration.
⛔ Files ignored due to path filters (7)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/peerDependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
📒 Files selected for processing (16)
.changeset/seven-bats-write.md
(1 hunks)crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap.new
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json
(1 hunks)crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/peerDependencies-devDependencies/package.json
(1 hunks)
✅ Files skipped from review due to trivial changes (2)
- crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/peerDependencies-devDependencies/package.json
- crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json
🧰 Additional context used
📓 Path-based instructions (3)
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
.changeset/*.md
📄 CodeRabbit Inference Engine (CONTRIBUTING.md)
.changeset/*.md
: Create changesets withjust new-changeset
; store them in.changeset/
with correct frontmatter (package keys and change type).
In changeset descriptions, follow content conventions: user-facing changes only; past tense for what you did; present tense for current behavior; link issues for fixes; link rules/assists; include representative code blocks; end every sentence with a period.
When adding headers in a changeset, only use #### or ##### levels.
Files:
.changeset/seven-bats-write.md
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just format
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (20)
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/**/*.jsonc : .jsonc snapshot test files must contain an array of strings (snippets) and are interpreted as script
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
📚 Learning: 2025-08-11T11:48:27.774Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:27.774Z
Learning: Applies to crates/biome_formatter/biome_html_formatter/Cargo.toml : Add the specified dev-dependencies (biome_formatter_test, biome_html_factory, biome_html_parser, biome_parser, biome_service, countme with feature enable, iai 0.1.1, quickcheck, quickcheck_macros, tests_macros) to Cargo.toml under [dev-dependencies]
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json
📚 Learning: 2025-08-05T13:25:32.395Z
Learnt from: CR
PR: biomejs/biome#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-05T13:25:32.395Z
Learning: Applies to **/tests/specs/**/*.snap : Test snapshots must be stored in `tests/specs/` directories within each crate
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Code blocks in docs must specify language; invalid examples must use expect_diagnostic; snippets must emit exactly one diagnostic
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/tests/specs/** : Place JS rule snapshot tests under tests/specs/<group>/<ruleName>/ with files prefixed by invalid* and valid*
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Set version: "next" in declare_lint_rule! for new or changing rules
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Deprecate rules by adding deprecated: reason in declare_lint_rule!
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Rule documentation: first paragraph must be a single line short description
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : New analyzer rules must be placed in the nursery group
Applied to files:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap.new
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use meaningful, cross-language-capable rule names when appropriate; use language/framework-specific names when constrained
Applied to files:
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use precise naming conventions for rules: no<Concept> to forbid, use<Concept> to mandate; and established patterns like noDuplicate<>, noUnused<>, useConsistent<>
Applied to files:
.changeset/seven-bats-write.md
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : When porting a lint rule, specify sources in declare_lint_rule! (e.g., RuleSource::Eslint(...).same() or .inspired())
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use the declare_lint_rule! macro to declare each rule
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Diagnostics must follow three pillars: state what the error is, why it triggers, and what to do (ideally via a code action or note)
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Assign domains to rules when applicable (e.g., testing, frameworks) via domains field
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Favor Result/Option combinators and the ? operator; avoid unwrap()/expect() and deep indentation
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Prefer custom visitors (Queryable + Visitor) when deep traversal within a single pass is more efficient than multiple queries
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Avoid unnecessary string allocations; compare against &str or use TokenText instead of to_string()
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use Option for Signals when reporting at most one diagnostic; use Box<[_]> or Vec for multiple signals, preferring Box<[_]>
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🔇 Additional comments (7)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json (1)
1-8
: Fixture correctly models an intra-group duplicate.This is spot-on for exercising duplicate keys within dependencies.
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json (1)
1-11
: Good negative case for cross-group duplicate (dependencies vs peerDependencies).This cleanly exercises the duplicate across groups.
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json (1)
1-11
: LGTM: invalid case across dependencies and optionalDependencies.Covers a common real-world slip. Nicely minimal.
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (2)
5-5
: Import TextRange from biome_rowan (verify current import path)TextRange is typically re-exported from biome_rowan. Importing it from biome_json_syntax may fail depending on current re-exports.
Apply this diff if needed:
-use biome_json_syntax::{JsonRoot, JsonSyntaxKind, JsonSyntaxToken, TextRange}; +use biome_json_syntax::{JsonRoot, JsonSyntaxKind, JsonSyntaxToken}; +use biome_rowan::TextRange;
63-71
: Revisit DUPLICATE_PROPERTY_KEYS membership for overridesIncluding "overrides" means you’ll detect duplicate keys inside overrides. That might be surprising, as overrides can be nested and may intentionally repeat package names in different scopes. If that’s not intended, consider dropping it or scoping the check more precisely.
If you keep it, please add invalid/valid tests for overrides to pin down desired behaviour.
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap.new (1)
24-45
: Snapshot reads well and matches the rule intentThe caret positions and messages are clear; anchor on dependencies with a detail pointing to optionalDependencies is spot on.
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap.new (1)
24-45
: Snapshot LGTMAnchoring on dependencies with a detail pointing to peerDependencies matches the documented behaviour. Crisp and helpful.
"@biomejs/biome": patch | ||
--- | ||
|
||
Added the new nursery rule [`noDuplicateDependencies`](https://next.biomejs.dev/linter/rules/no-duplicate-dependencies/), which verifies that no dependencies are duplicated between the `bundledDependencies`, `bundleDependencies`, `dependencies`, `devDependencies`, `overrides`, `optionalDependencies`, and `peerDependencies` sections. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Clarify scope: intra-group duplicates are also reported.
The rule (and tests) also flag duplicates within the same section (e.g. "dependencies" twice). The sentence currently implies only cross-section checks.
Apply this wording tweak:
-Added the new nursery rule [`noDuplicateDependencies`](https://next.biomejs.dev/linter/rules/no-duplicate-dependencies/), which verifies that no dependencies are duplicated between the `bundledDependencies`, `bundleDependencies`, `dependencies`, `devDependencies`, `overrides`, `optionalDependencies`, and `peerDependencies` sections.
+Added the new nursery rule [`noDuplicateDependencies`](https://next.biomejs.dev/linter/rules/no-duplicate-dependencies/), which reports duplicate dependencies within a section and across the following sections: `bundledDependencies`, `bundleDependencies`, `dependencies`, `devDependencies`, `overrides`, `optionalDependencies`, and `peerDependencies`.
📝 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.
Added the new nursery rule [`noDuplicateDependencies`](https://next.biomejs.dev/linter/rules/no-duplicate-dependencies/), which verifies that no dependencies are duplicated between the `bundledDependencies`, `bundleDependencies`, `dependencies`, `devDependencies`, `overrides`, `optionalDependencies`, and `peerDependencies` sections. | |
Added the new nursery rule [`noDuplicateDependencies`](https://next.biomejs.dev/linter/rules/no-duplicate-dependencies/), which reports duplicate dependencies within a section and across the following sections: `bundledDependencies`, `bundleDependencies`, `dependencies`, `devDependencies`, `overrides`, `optionalDependencies`, and `peerDependencies`. |
🤖 Prompt for AI Agents
In .changeset/seven-bats-write.md around line 5, the release note implies the
rule only checks duplicates across different dependency sections; update the
wording to clarify that the rule also reports duplicate entries within the same
section (intra-group duplicates). Edit the sentence to explicitly state it flags
duplicates both between sections and within a single section (e.g., the same
dependency listed twice in "dependencies"), keeping the rest of the description
and the link intact.
💡 Verification agent
🧩 Analysis chain
Quick sanity checks: rule version and test coverage.
Two verifications to keep us honest:
- The rule’s
declare_lint_rule!
should setversion: "next"
. - Tests should include
bundledDependencies
,bundleDependencies
, andoverrides
.
Run this from the repo root.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Checking rule version marker..."
if rg -n 'version:\s*"next"' crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs >/dev/null; then
echo "OK: version \"next\" found."
else
echo "MISSING: version \"next\" not found in declare_lint_rule!" >&2
exit 1
fi
echo
echo "Checking tests mention bundled/bundle/overrides..."
RG_PATH='crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies'
rg -n --hidden 'bundledDependencies|bundleDependencies|overrides' "$RG_PATH" -H -A 1 -B 1 || {
echo "No occurrences found in $RG_PATH. Consider adding at least one fixture/snapshot for each key." >&2
exit 2
}
echo "All checks passed."
Length of output: 1981
Add missing test fixtures for bundledDependencies and overrides
Good news: version: "next"
is correctly set in no_duplicate_dependencies.rs
. However, the existing tests only cover bundleDependencies
. Please add fixtures/snapshots under:
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundledDependencies/...
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/overrides/...
so that bundledDependencies
and overrides
are each exercised by the rule.
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
Outdated
Show resolved
Hide resolved
if duplicates.is_empty() { | ||
return None; | ||
} | ||
|
||
return duplicates.into_iter().next(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Only the first duplicate is reported; emit all duplicates
Users will expect all duplicates to be flagged, not just the first one encountered. The code currently returns duplicates.into_iter().next().
Apply this diff to return all signals:
- type Signals = Option<Self::State>;
+ type Signals = Option<Box<[Self::State]>>;
@@
- if duplicates.is_empty() {
- return None;
- }
-
- return duplicates.into_iter().next();
+ if duplicates.is_empty() {
+ return None;
+ }
+ Some(
+ duplicates
+ .into_iter()
+ .map(|(token, ranges)| (token, ranges))
+ .collect::<Vec<_>>()
+ .into_boxed_slice(),
+ )
Note: This aligns with the project guideline to use Box<[_]> for multiple diagnostics.
🤖 Prompt for AI Agents
In crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
around lines 212 to 217, the function currently returns only the first duplicate
via duplicates.into_iter().next(); instead, return all detected duplicates by
converting the duplicates Vec into a boxed slice and returning it (e.g.
Some(duplicates.into_boxed_slice())), ensuring the function's return type
matches Option<Box<[_]>> per project guidelines; remove the early single-item
return and return the boxed slice when duplicates is non-empty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not allowed;
type mismatch resolving `<Option<Box<[...]>> as IntoIterator>::Item == (SyntaxToken<...>, ...)`
expected tuple `(SyntaxToken<JsonLanguage>, Vec<TextRange>)`
found struct `Box<[(SyntaxToken<JsonLanguage>, Vec<TextRange>)]>`
...ests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json
Show resolved
Hide resolved
--- | ||
source: crates/biome_json_analyze/tests/spec_tests.rs | ||
assertion_line: 82 | ||
expression: package.json | ||
--- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Add coverage check for bundle(d)Dependencies and overrides.
We mention these in the rule/changeset; ensure we have fixtures for them too.
🏁 Script executed:
#!/bin/bash
set -euo pipefail
BASE='crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies'
echo "Looking for test input or snapshots that mention bundledDependencies, bundleDependencies, or overrides..."
rg -n 'bundledDependencies|bundleDependencies|overrides' "$BASE" -H -A 2 -B 2 || {
echo "No matches found. Consider adding fixtures covering bundledDependencies, bundleDependencies, and overrides." >&2
exit 1
}
Length of output: 2548
Add missing fixtures for bundledDependencies and overrides
We already cover bundleDependencies
, but there are no spec tests for the synonymous bundledDependencies
or for overrides
. Please add input and snapshot fixtures under:
- crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundledDependencies
- crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/overrides
This will ensure our rule catches duplicates in all supported dependency fields.
🤖 Prompt for AI Agents
In
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap.new
lines 1 to 5, the test suite lacks fixture files for the synonymous
bundledDependencies and for overrides; add two new sets of fixtures (input .json
and snapshot .snap/.snap.new) under
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundledDependencies
and .../invalid/overrides respectively, modeled after the existing
bundleDependencies fixtures: create an input package.json that contains
duplicate entries for the field (bundledDependencies array and an overrides
object with duplicate keys) that should trigger the rule, and add the expected
snapshot files capturing the rule’s error output so the tests will assert
duplicates are detected in those fields as well.
``` | ||
package.json:4:5 lint/nursery/noDuplicateDependencies ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ | ||
|
||
i The dependency "foo" is also listed in another dependency group. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Message is misleading for intra-group duplicates.
This case duplicates "foo" within the same section. The message says “another dependency group”, which is inaccurate.
Suggested wording:
- i The dependency "foo" is also listed in another dependency group.
+ i The dependency "foo" is duplicated within "dependencies".
Optional tweak for the follow-up note:
- i The dependency is also specified here.
+ i The duplicate is also specified here.
Follow-up: the rule implementation likely needs to branch message text between “within the same group” and “across groups.” Happy to draft that change.
📝 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.
i The dependency "foo" is also listed in another dependency group. | |
i The dependency "foo" is duplicated within "dependencies". |
"optionalDependencies": { | ||
"foo": "", | ||
"bar": "" | ||
}, | ||
"devDependencies": { | ||
"foo": "", | ||
"baz": "" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Please confirm rule intent: duplicates between optionalDependencies and devDependencies are allowed.
This valid-case includes "foo" in both optionalDependencies and devDependencies. If that’s intentional (i.e. the rule ignores duplicates involving devDependencies), great—let’s document it in the rule’s docs/tests description. If not, this should move to invalid/.
You can verify the intent and current coverage with:
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Show all references to the rule to locate docs and impl
rg -n --hidden --glob '!target' 'noDuplicateDependencies|NoDuplicateDependencies'
# 2) Inspect rule implementation for the set of groups considered duplicates
rg -n --hidden --glob '!target' 'optionalDependencies|devDependencies' crates
# 3) List valid fixtures that include duplicates across groups (expect this file to appear intentionally)
fd optionalDependencies-devDependencies crates/biome_json_analyze/tests/specs -t f -x echo {}
# 4) Print this fixture to double-check contents
cat crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/package.json || true
Length of output: 49373
Clarify allowed duplicates between optionalDependencies and devDependencies
The implementation only checks for duplicates in these pairs:
dependencies
↔ (devDependencies
|optionalDependencies
|peerDependencies
)optionalDependencies
↔peerDependencies
Duplicates between optionalDependencies
and devDependencies
are therefore intentionally permitted. Please update the rule’s docs and test descriptions to call this out:
• In crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
add to the ///
doc comment that optionalDependencies
↔ devDependencies
are not checked.
• In crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/
, add a note (e.g. in a README or inline comment) explaining why this case is valid.
🤖 Prompt for AI Agents
In crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
around the top doc comment, add a sentence to the /// documentation explicitly
stating that duplicate checks do not include optionalDependencies ↔
devDependencies (i.e., those pairs are intentionally not checked); and in
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/valid/optionalDependencies-devDependencies/
add a short README or an inline comment in the package.json (or an accompanying
README.md) explaining that this test is valid because optionalDependencies ↔
devDependencies duplicates are allowed by the rule and therefore not flagged.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (3)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (3)
180-210
: Avoid?
inside loops; use let-chains and Entry to simplifyUsing
?
here can cause an early None return if something unexpected slips through; we already guard withcontinue
. This rewrite is cleaner and eliminates redundant checks. Also removes manual Vec handling in favour ofentry(...).or_default()
.- // Check for duplicate dependencies between dependency groups - for (key, properties) in UNIQUE_PROPERTY_KEYS { - let key_deps = dependencies.get(key); - - if key_deps.is_none() { - continue; - } - - for property in properties { - if property.is_empty() { - continue; - } - - let deps = dependencies.get(*property); - - if deps.is_none() { - continue; - } - - for (dependency_name, original_member) in key_deps? { - if let Some(member) = deps?.get(dependency_name) { - if let Some(ranges) = duplicates.get_mut(original_member) { - ranges.push(member.text_trimmed_range()); - } else { - duplicates - .insert(original_member.clone(), vec![member.text_trimmed_range()]); - } - } - } - } - } + // Check for duplicate dependencies between dependency groups + for (key, properties) in UNIQUE_PROPERTY_KEYS { + let Some(key_deps) = dependencies.get(key) else { continue; }; + for property in properties { + let Some(deps) = dependencies.get(*property) else { continue; }; + for (dependency_name, original_member) in key_deps { + if let Some(member) = deps.get(dependency_name) { + duplicates + .entry(original_member.clone()) + .or_default() + .push(member.text_trimmed_range()); + } + } + } + }
212-217
: Return every duplicate foundCurrently only the first duplicate is reported. Convert the map into a boxed slice of states.
- if duplicates.is_empty() { - return None; - } - - return duplicates.into_iter().next(); + if duplicates.is_empty() { + return None; + } + Some( + duplicates + .into_iter() + .map(|(token, ranges)| (token, ranges)) + .collect::<Vec<_>>() + .into_boxed_slice(), + )
74-78
: Emit all duplicates, not just the firstReturn all signals to meet user expectations and Biome’s guideline (Box<[_]> for multiple diagnostics).
- type Signals = Option<Self::State>; + type Signals = Option<Box<[Self::State]>>;
🧹 Nitpick comments (7)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (7)
79-89
: Early-return before AST workCheap win: bail out for non-package.json files before touching the AST to reduce work on every JSON file.
- fn run(ctx: &RuleContext<Self>) -> Self::Signals { - let query = ctx.query(); - let path = ctx.file_path(); - - let value = query.value().ok()?; - let object_value = value.as_json_object_value()?; - - if !path.ends_with(PACKAGE_JSON) { - return None; - } + fn run(ctx: &RuleContext<Self>) -> Self::Signals { + let path = ctx.file_path(); + if !path.ends_with(PACKAGE_JSON) { + return None; + } + let query = ctx.query(); + let value = query.value().ok()?; + let object_value = value.as_json_object_value()?;
93-110
: Flatten the filter with combinators (less nesting, more signal)This follows Biome’s guideline to use combinators and early returns instead of deep nesting.
- .filter(|member| { - let name = member.name(); - if let Ok(name) = name { - let text = name.inner_string_text(); - if let Ok(text) = text { - if DUPLICATE_PROPERTY_KEYS.contains(&text.text()) { - return true; - } - } - } - return false; - }); + .filter(|member| { + member + .name() + .ok() + .and_then(|n| n.inner_string_text().ok()) + .map_or(false, |text| DUPLICATE_PROPERTY_KEYS.contains(&text.text())) + });
127-141
: De-duplicate logic using Entry API (clearer and faster)Cuts branching and avoids repeated lookups.
- // Add dependencies to deps if not exists else to duplicates - if let Some(original_member) = deps.get(&dependency_text.to_string()) { - if let Some(ranges) = duplicates.get_mut(original_member) { - ranges.push(dependency_name.range()); - } else { - duplicates - .insert(original_member.clone(), vec![dependency_name.range()]); - } - } else { - deps.insert( - dependency_text.to_string(), - dependency_name.value_token().ok()?, - ); - } + // Track first occurrence, record subsequent ones as duplicates + match deps.entry(dependency_text.text().to_string()) { + std::collections::hash_map::Entry::Occupied(entry) => { + let original_member = entry.get(); + duplicates + .entry(original_member.clone()) + .or_default() + .push(dependency_name.range()); + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(dependency_name.value_token().ok()?); + } + }If you prefer, I can factor this into a small helper to reuse here and in the array branch below.
155-167
: Mirror the Entry API refactor for arraysSame benefit as above; aligns both branches.
- if let Some(original_member) = deps.get(&dependency_text.to_string()) { - if let Some(ranges) = duplicates.get_mut(original_member) { - ranges.push(dependency_name.range()); - } else { - duplicates - .insert(original_member.clone(), vec![dependency_name.range()]); - } - } else { - deps.insert( - dependency_text.to_string(), - dependency_name.value_token().ok()?, - ); - } + match deps.entry(dependency_text.text().to_string()) { + std::collections::hash_map::Entry::Occupied(entry) => { + let original_member = entry.get(); + duplicates + .entry(original_member.clone()) + .or_default() + .push(dependency_name.range()); + } + std::collections::hash_map::Entry::Vacant(entry) => { + entry.insert(dependency_name.value_token().ok()?); + } + }
49-61
: Consider alias parity: bundleDependencies vs bundledDependenciesThese are aliases in npm. If both appear, users likely expect duplicates across them to be flagged. If that’s in scope, add cross-checks in UNIQUE_PROPERTY_KEYS for both directions.
-const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ +const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 4] = [ ( "dependencies", &[ "devDependencies", "optionalDependencies", "peerDependencies", ], ), ("optionalDependencies", &["peerDependencies"]), + ("bundleDependencies", &["bundledDependencies"]), + ("bundledDependencies", &["bundleDependencies"]), ];Would you like me to add fixture(s) to cover this alias case?
189-191
: Remove dead check
properties
no longer contains padded empty strings; this guard is redundant.- if property.is_empty() { - continue; - }
219-238
: Optional: add a hint on remediationNice diagnostic. Consider adding a short note suggesting to keep it in one group (usually dependencies) or remove the duplicate entry. This aligns with the “what to do” pillar.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these settings in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
📒 Files selected for processing (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just format
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (16)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Deprecate rules by adding deprecated: reason in declare_lint_rule!
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : When porting a lint rule, specify sources in declare_lint_rule! (e.g., RuleSource::Eslint(...).same() or .inspired())
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use precise naming conventions for rules: no<Concept> to forbid, use<Concept> to mandate; and established patterns like noDuplicate<>, noUnused<>, useConsistent<>
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use meaningful, cross-language-capable rule names when appropriate; use language/framework-specific names when constrained
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : New analyzer rules must be placed in the nursery group
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Set version: "next" in declare_lint_rule! for new or changing rules
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Set version: "next" in declare_lint_rule! for new or changing rules
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : When porting a lint rule, specify sources in declare_lint_rule! (e.g., RuleSource::Eslint(...).same() or .inspired())
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Deprecate rules by adding deprecated: reason in declare_lint_rule!
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use the declare_lint_rule! macro to declare each rule
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use meaningful, cross-language-capable rule names when appropriate; use language/framework-specific names when constrained
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : New analyzer rules must be placed in the nursery group
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use precise naming conventions for rules: no<Concept> to forbid, use<Concept> to mandate; and established patterns like noDuplicate<>, noUnused<>, useConsistent<>
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Rule documentation: first paragraph must be a single line short description
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Diagnostics must follow three pillars: state what the error is, why it triggers, and what to do (ideally via a code action or note)
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Assign domains to rules when applicable (e.g., testing, frameworks) via domains field
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Favor Result/Option combinators and the ? operator; avoid unwrap()/expect() and deep indentation
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Prefer custom visitors (Queryable + Visitor) when deep traversal within a single pass is more efficient than multiple queries
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Avoid unnecessary string allocations; compare against &str or use TokenText instead of to_string()
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use Option for Signals when reporting at most one diagnostic; use Box<[_]> or Vec for multiple signals, preferring Box<[_]>
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Code blocks in docs must specify language; invalid examples must use expect_diagnostic; snippets must emit exactly one diagnostic
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧬 Code Graph Analysis (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (1)
NoDuplicateDependenciesOptions
(7863-7863)crates/biome_analyze/src/rule.rs (9)
language
(574-577)recommended
(554-557)sources
(569-572)same
(241-246)run
(1013-1013)diagnostic
(1100-1102)new
(534-552)new
(1296-1307)new
(1421-1433)
🔇 Additional comments (2)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (2)
10-45
: Rule declaration looks sharpCorrect naming, version "next", language set, and sources wired. Doc intro is one line and examples are tidy. Nice.
63-71
: Scope check:overrides
inclusionYou include
overrides
for within-group duplicates (fine) but don’t cross-check it against other groups (also fine). Just to confirm intent: we generally shouldn’t flagoverrides
vsdependencies
, asoverrides
controls transitive resolution. If that’s the intent, we’re aligned.Would you like me to add a valid+invalid fixture pair demonstrating that
overrides
does not trigger cross-group duplicate diagnostics?
bd215e7
to
092e580
Compare
There was a problem hiding this 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
🧹 Nitpick comments (5)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (5)
11-11
: Doc comment could be more preciseThe comment mentions "i.e." but should use "e.g." since it's providing an example, not an exhaustive list.
- /// Disallow any dependency from being specified more than once (i.e. in `dependencies` and `devDependencies`) + /// Disallow any dependency from being specified more than once (e.g. in `dependencies` and `devDependencies`)
51-61
: Consider handling bundleDependencies/bundledDependencies alias parityThe arrays
bundleDependencies
andbundledDependencies
are aliases - should we also check for duplicates between them, not just within each?Consider adding an entry to prevent duplicates across the alias fields:
const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ ( "dependencies", &[ "devDependencies", "optionalDependencies", "peerDependencies", ], ), ("optionalDependencies", &["peerDependencies"]), + ("bundleDependencies", &["bundledDependencies"]), ];
Then update the constant type:
-const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ +const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 3] = [
111-141
: Consider extracting dependency collection logicThe dependency collection code for objects is quite nested. Consider extracting into a helper function for better readability.
fn collect_object_dependencies( object_value: &JsonObjectValue, deps: &mut FxHashMap<String, JsonSyntaxToken>, duplicates: &mut FxHashMap<JsonSyntaxToken, Vec<TextRange>>, ) -> Option<()> { for dependency in object_value.json_member_list().iter().flatten() { let dependency_name = dependency.name().ok()?; let dependency_text = dependency_name.inner_string_text().ok()?; if let Some(original_member) = deps.get(&dependency_text.to_string()) { if let Some(ranges) = duplicates.get_mut(original_member) { ranges.push(dependency_name.range()); } else { duplicates.insert(original_member.clone(), vec![dependency_name.range()]); } } else { deps.insert( dependency_text.to_string(), dependency_name.value_token().ok()?, ); } } Some(()) }Then use it to reduce nesting in the main function.
184-186
: Use let-else for early returnsSince you're already checking for
None
and continuing, use let-else pattern to reduce nesting.- let key_deps = dependencies.get(key); - - if key_deps.is_none() { - continue; - } + let Some(key_deps) = dependencies.get(key) else { + continue; + };
189-193
: Use let-else here tooSame pattern applies here for consistency.
- let deps = dependencies.get(*property); - - if deps.is_none() { - continue; - } + let Some(deps) = dependencies.get(*property) else { + continue; + };
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these settings in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
📒 Files selected for processing (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{rs,toml}
📄 CodeRabbit Inference Engine (CLAUDE.md)
Format code (Rust + TOML) using
just format
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**/*
📄 CodeRabbit Inference Engine (CLAUDE.md)
Core crates must be located in
/crates/biome_*/
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (19)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : When porting a lint rule, specify sources in declare_lint_rule! (e.g., RuleSource::Eslint(...).same() or .inspired())
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Deprecate rules by adding deprecated: reason in declare_lint_rule!
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use precise naming conventions for rules: no<Concept> to forbid, use<Concept> to mandate; and established patterns like noDuplicate<>, noUnused<>, useConsistent<>
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use meaningful, cross-language-capable rule names when appropriate; use language/framework-specific names when constrained
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : New analyzer rules must be placed in the nursery group
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Set version: "next" in declare_lint_rule! for new or changing rules
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : If a rule provides code actions, add fix_kind to declare_lint_rule! and pass category and applicability in action()
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Assign domains to rules when applicable (e.g., testing, frameworks) via domains field
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use the declare_lint_rule! macro to declare each rule
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Set version: "next" in declare_lint_rule! for new or changing rules
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : When porting a lint rule, specify sources in declare_lint_rule! (e.g., RuleSource::Eslint(...).same() or .inspired())
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Deprecate rules by adding deprecated: reason in declare_lint_rule!
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use the declare_lint_rule! macro to declare each rule
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use meaningful, cross-language-capable rule names when appropriate; use language/framework-specific names when constrained
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : New analyzer rules must be placed in the nursery group
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use precise naming conventions for rules: no<Concept> to forbid, use<Concept> to mandate; and established patterns like noDuplicate<>, noUnused<>, useConsistent<>
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Rule documentation: first paragraph must be a single line short description
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Diagnostics must follow three pillars: state what the error is, why it triggers, and what to do (ideally via a code action or note)
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Assign domains to rules when applicable (e.g., testing, frameworks) via domains field
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Favor Result/Option combinators and the ? operator; avoid unwrap()/expect() and deep indentation
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Prefer custom visitors (Queryable + Visitor) when deep traversal within a single pass is more efficient than multiple queries
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Avoid unnecessary string allocations; compare against &str or use TokenText instead of to_string()
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Use Option for Signals when reporting at most one diagnostic; use Box<[_]> or Vec for multiple signals, preferring Box<[_]>
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/**/src/lint/nursery/**/*.rs : Code blocks in docs must specify language; invalid examples must use expect_diagnostic; snippets must emit exactly one diagnostic
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:43:46.619Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:43:46.619Z
Learning: Applies to crates/biome_analyze/crates/biome_rule_options/lib/**/*.rs : Prefer Box<[Box<str>]> over Vec<String> for option string collections to reduce memory
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧬 Code Graph Analysis (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (2)
packages/@biomejs/backend-jsonrpc/src/workspace.ts (2)
TextRange
(8886-8886)NoDuplicateDependenciesOptions
(7863-7863)crates/biome_analyze/src/rule.rs (9)
language
(574-577)recommended
(554-557)sources
(569-572)same
(241-246)run
(1013-1013)diagnostic
(1100-1102)new
(534-552)new
(1296-1307)new
(1421-1433)
🔇 Additional comments (5)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (5)
39-43
: Rule configuration looks goodThe rule is properly set up in the nursery group with version "next" and appropriate ESLint source references, following the project guidelines from the learnings.
94-109
: Filter logic is correctGood defensive coding with proper error handling using
Ok()
patterns rather than unwraps.
143-169
: Array dependency handling looks solidProperly handles the array case for bundled dependencies with appropriate type checking.
212-212
: Only reporting first duplicate - intentional?The rule currently only reports the first duplicate found. Per past review comments, this appears to be a limitation. Consider documenting this behaviour or tracking as a TODO.
Is reporting only the first duplicate intentional? Users typically expect all duplicates to be flagged. If this is a known limitation, consider adding a TODO comment.
215-234
: Diagnostic implementation is cleanGood use of the diagnostic builder pattern with clear messages and detail attachments.
102dc77
to
785c203
Compare
d404fc8
to
3dc57a5
Compare
Woops, re-requested a review a little too early. Should now be included :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (1)
39-44
: Add missing migrate mappings for JSON duplicate-dependencies rulesOur grep didn’t find any entries for
unique-dependencies
orduplicate-dependencies
incrates/biome_cli/src/execute/migrate
, sobiome migrate
won’t carry these new rules over. Please update that file by adding mappings for both sources, for example:
"package-json/unique-dependencies"
→"json/noDuplicateDependencies"
"package-json-dependencies/duplicate-dependencies"
→"json/noDuplicateDependencies"
This will ensure
biome migrate
picks up thenoDuplicateDependencies
rule.
🧹 Nitpick comments (8)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (8)
51-61
: Consider checking alias parity: bundleDependencies ↔ bundledDependenciesCurrently cross‑group checks don’t compare the two alias fields. If both appear, it’s effectively duplication. Add them to UNIQUE_PROPERTY_KEYS.
Apply:
const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ - ( + ( "dependencies", &[ "devDependencies", "optionalDependencies", "peerDependencies", ], ), - ("peerDependencies", &["optionalDependencies"]), + ("peerDependencies", &["optionalDependencies"]), ];Suggested expansion:
-const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ +const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 4] = [ ( "dependencies", &[ "devDependencies", "optionalDependencies", "peerDependencies", ], ), ("peerDependencies", &["optionalDependencies"]), + ("bundleDependencies", &["bundledDependencies"]), + ("bundledDependencies", &["bundleDependencies"]), ];
84-94
: Early out before AST workFast‑path the filename check to avoid traversing the tree on non‑package.json files.
- fn run(ctx: &RuleContext<Self>) -> Self::Signals { - let query = ctx.query(); - let path = ctx.file_path(); - - let value = query.value().ok()?; - let object_value = value.as_json_object_value()?; - - if !path.ends_with(PACKAGE_JSON) { - return None; - } + fn run(ctx: &RuleContext<Self>) -> Self::Signals { + let path = ctx.file_path(); + if !path.ends_with(PACKAGE_JSON) { + return None; + } + let query = ctx.query(); + let value = query.value().ok()?; + let object_value = value.as_json_object_value()?;
97-111
: Flatten the filter to reduce nestingUse combinators to keep the filter concise.
- .filter(|member| { - let name = member.name(); - if let Ok(name) = name { - let text = name.inner_string_text(); - if let Ok(text) = text { - return DUPLICATE_PROPERTY_KEYS.contains(&text.text()); - } - } - return false; - }); + .filter(|member| { + member + .name() + .and_then(|n| n.inner_string_text()) + .map_or(false, |t| DUPLICATE_PROPERTY_KEYS.contains(&t.text())) + });
190-206
: Remove redundant Option checks; use let‑else for clarityYou guard with is_none() then still use
?
. Bind once and iterate.- for (key, properties) in UNIQUE_PROPERTY_KEYS { - let key_deps = dependencies.get(key); - - if key_deps.is_none() { - continue; - } - - for property in properties { - let deps = dependencies.get(*property); - - if deps.is_none() { - continue; - } - - for (dependency_name, original_member) in key_deps? { - if let Some(member) = deps?.get(dependency_name) { + for (key, properties) in UNIQUE_PROPERTY_KEYS { + let Some(key_deps) = dependencies.get(key) else { continue }; + for property in properties { + let Some(deps) = dependencies.get(*property) else { continue }; + for (dependency_name, original_member) in key_deps { + if let Some(member) = deps.get(dependency_name) {
73-76
: Narrow visibility of Dependency
Dependency
seems module‑local. Avoidpub
unless it’s part of the external API surface.-pub struct Dependency { +struct Dependency { pub group: String, pub token: JsonSyntaxToken, }
121-181
: DRY: unify duplicate‑within‑group logicThe object/array branches duplicate “insert or flag duplicate” logic. Extract a small helper/closure that takes an iterator of (name, token) to reduce code size and cognitive load. Happy to draft the refactor if you’d like.
Also applies to: 153-178
229-241
: Tiny allocation nit: avoid to_string in diagnosticsYou already hold
String
/&str
. Pass them directly tomarkup!
andEmphasis
to avoid extra allocations.- markup!("The dependency "<Emphasis>{name}</Emphasis>" is listed twice under "<Emphasis>{dupe.group.to_string()}</Emphasis>"."), + markup!("The dependency "<Emphasis>{name}</Emphasis>" is listed twice under "<Emphasis>{dupe.group.as_str()}</Emphasis>"."), @@ - markup!("The dependency "<Emphasis>{name}</Emphasis>" is also listed under "<Emphasis>{dupe.group.to_string()}</Emphasis>"."), + markup!("The dependency "<Emphasis>{name}</Emphasis>" is also listed under "<Emphasis>{dupe.group.as_str()}</Emphasis>"."),
63-71
: Add tests for alias parity and “overrides” self‑duplicationGiven the constants, please add fixtures for:
- bundleDependencies + bundledDependencies both present with overlapping entries.
- overrides containing the same key twice (to confirm intra‑group detection).
I can draft the fixtures under tests/specs/nursery/noDuplicateDependencies if helpful.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (6)
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/bundleDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-devDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-optionalDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/dependencies/package.json.snap
is excluded by!**/*.snap
crates/biome_json_analyze/tests/specs/nursery/noDuplicateDependencies/invalid/optionalDependencies-peerDependencies/package.json.snap
is excluded by!**/*.snap
📒 Files selected for processing (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (9)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule is deprecated, set the `deprecated:` field in `declare_lint_rule!` with a reason and alternative
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Avoid `unwrap`/`expect`; use `?`, `ok()?`, and combinators (`map`, `and_then`, `filter`) to handle `Result`/`Option` when navigating the CST
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Prefer `Box<[_]>` over `Vec<_>` for multiple signals and convert via `Vec::into_boxed_slice()`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧬 Code graph analysis (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (1)
crates/biome_analyze/src/rule.rs (9)
language
(574-577)recommended
(554-557)sources
(569-572)same
(241-246)run
(1013-1013)diagnostic
(1100-1102)new
(534-552)new
(1296-1307)new
(1421-1433)
No it's perfect, thank you. As long as we communicate the rule pillars, it doesn't matter how :) |
The Clippy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (8)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (8)
10-44
: Rule declaration looks solid; minor docs nitVersion, language, and sources wiring LGTM. Tiny copy edit: prefer “i.e.” over “e.g.” as this clarifies rather than gives one of many examples.
- /// Disallow any dependency from being specified more than once (e.g. in `dependencies` and `devDependencies`) + /// Disallow any dependency from being specified more than once (i.e. in `dependencies` and `devDependencies`)
73-76
: Scope creep: make Dependency non‑pubThis type appears internal to the rule; exposing it widens the crate API for no gain.
-pub struct Dependency { +struct Dependency { pub group: String, pub token: JsonSyntaxToken, }
84-94
: Early‑out before AST workMicro‑optimisation and simpler flow: bail on non‑package.json before walking the root.
- let query = ctx.query(); - let path = ctx.file_path(); - - let value = query.value().ok()?; - let object_value = value.as_json_object_value()?; - - if !path.ends_with(PACKAGE_JSON) { - return None; - } + if !ctx.file_path().ends_with(PACKAGE_JSON) { + return None; + } + let object_value = ctx.query().value().ok()?.as_json_object_value()?;
97-111
: Flatten the filter with let‑else for readabilityRemoves nesting and matches project style.
- .filter(|member| { - let name = member.name(); - if let Ok(name) = name { - let text = name.inner_string_text(); - if let Ok(text) = text { - return DUPLICATE_PROPERTY_KEYS.contains(&text.text()); - } - } - return false; - }); + .filter(|member| { + let Ok(name) = member.name() else { return false }; + let Ok(text) = name.inner_string_text() else { return false }; + DUPLICATE_PROPERTY_KEYS.contains(&text.text()) + });
129-147
: Single lookup using insert() return valueAvoids double hashing and simplifies control flow.
- // Add dependencies to deps if not exists else to duplicates - if let Some(original_member) = deps.get(&dependency_text.to_string()) { - let original = Dependency { - group: dependency_group_text.to_string(), - token: original_member.clone(), - }; - let dupe = Dependency { - group: dependency_group_text.to_string(), - token: dependency_name.value_token().ok()?, - }; - - return Some((original, dupe)); - } else { - deps.insert( - dependency_text.to_string(), - dependency_name.value_token().ok()?, - ); - } + let token = dependency_name.value_token().ok()?; + if let Some(original_tok) = + deps.insert(dependency_text.to_string(), token.clone()) + { + let original = Dependency { + group: dependency_group_text.to_string(), + token: original_tok, + }; + let dupe = Dependency { + group: dependency_group_text.to_string(), + token, + }; + return Some((original, dupe)); + }
161-177
: Same optimisation for array branchMirror the insert() approach for bundles arrays.
- if let Some(original_member) = deps.get(&dependency_text.to_string()) { - let original = Dependency { - group: dependency_group_text.to_string(), - token: original_member.clone(), - }; - let dupe = Dependency { - group: dependency_group_text.to_string(), - token: dependency_name.value_token().ok()?, - }; - - return Some((original, dupe)); - } else { - deps.insert( - dependency_text.to_string(), - dependency_name.value_token().ok()?, - ); - } + let token = dependency_name.value_token().ok()?; + if let Some(original_tok) = + deps.insert(dependency_text.to_string(), token.clone()) + { + let original = Dependency { + group: dependency_group_text.to_string(), + token: original_tok, + }; + let dupe = Dependency { + group: dependency_group_text.to_string(), + token, + }; + return Some((original, dupe)); + }
190-220
: Remove redundant Option unwraps; iterate cleanlyYou guard for None, then still use
?
. Simplify and avoid*property
noise.- for (key, properties) in UNIQUE_PROPERTY_KEYS { - let key_deps = dependencies.get(key); - - if key_deps.is_none() { - continue; - } - - for property in properties { - let deps = dependencies.get(*property); - - if deps.is_none() { - continue; - } - - for (dependency_name, original_member) in key_deps? { - if let Some(member) = deps?.get(dependency_name) { + for (key, properties) in UNIQUE_PROPERTY_KEYS { + let Some(key_deps) = dependencies.get(key) else { continue }; + for &property in properties { + let Some(deps) = dependencies.get(property) else { continue }; + for (dependency_name, original_member) in key_deps { + if let Some(member) = deps.get(dependency_name) { let original = Dependency { group: key.to_string(), token: original_member.clone(), }; - let dupe = Dependency { - group: (*property).to_string(), + let dupe = Dependency { + group: property.to_string(), token: member.clone(), }; return Some((original, dupe)); } } } }
49-61
: Consider alias parity: bundleDependencies vs bundledDependenciesIf both appear, they’re semantically the same set. Optionally check cross‑duplication between them.
const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ + // Optional: keep bundling aliases unique across each other + // ("bundleDependencies", &["bundledDependencies"]), + // ("bundledDependencies", &["bundleDependencies"]),Would you like me to add fixtures asserting duplicates across these two alias fields?
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule is deprecated, set the `deprecated:` field in `declare_lint_rule!` with a reason and alternative
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Avoid `unwrap`/`expect`; use `?`, `ok()?`, and combinators (`map`, `and_then`, `filter`) to handle `Result`/`Option` when navigating the CST
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Prefer `Box<[_]>` over `Vec<_>` for multiple signals and convert via `Vec::into_boxed_slice()`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧬 Code graph analysis (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (1)
crates/biome_analyze/src/rule.rs (9)
language
(574-577)recommended
(554-557)sources
(569-572)same
(241-246)run
(1015-1015)diagnostic
(1102-1104)new
(534-552)new
(1298-1309)new
(1423-1435)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: End-to-end tests
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Test Node.js API
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Check JS Files
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: autofix
Did you change only the ones highlighted by clippy? Line 222 and line 110 |
Yup :/ L110 results in (on the return type of filter);
on the filter L222 results in (on the return type of the run fn);
So would have to do more, to make this work, so I think the returns are fine, no? |
@Netail not sure what you were doing. I applied clippy suggestions and it worked. I pushed the changes to your fork. |
It was the semicolon 🤦♂️, thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (8)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (8)
84-95
: Do the path check before touching the CSTMinor perf: bail out on non-package.json before calling value()/as_json_object_value().
Apply this diff:
- let query = ctx.query(); - let path = ctx.file_path(); - - let value = query.value().ok()?; - let object_value = value.as_json_object_value()?; - - if !path.ends_with(PACKAGE_JSON) { - return None; - } + let path = ctx.file_path(); + if !path.ends_with(PACKAGE_JSON) { + return None; + } + let value = ctx.query().value().ok()?; + let object_value = value.as_json_object_value()?;
97-111
: Tighten the filter to reduce nestingThe nested if-let ladder is readable but a tad noisy. A small combinator cleans it up.
Apply this diff:
- .filter(|member| { - let name = member.name(); - if let Ok(name) = name { - let text = name.inner_string_text(); - if let Ok(text) = text { - return DUPLICATE_PROPERTY_KEYS.contains(&text.text()); - } - } - false - }); + .filter(|member| { + member + .name() + .ok() + .and_then(|n| n.inner_string_text().ok()) + .map_or(false, |t| DUPLICATE_PROPERTY_KEYS.contains(&t.text())) + });
121-147
: Avoid allocation on HashMap lookups
deps.get(&dependency_text.to_string())
allocates on every probe. Use a borrowed lookup and only allocate on insert.Apply this diff:
- if let Some(original_member) = deps.get(&dependency_text.to_string()) { + if let Some(original_member) = deps.get(dependency_text.text()) { @@ - deps.insert( - dependency_text.to_string(), + deps.insert( + dependency_text.text().to_string(), dependency_name.value_token().ok()?, );
149-179
: Same allocation nit for array caseMirror the zero-allocation lookup for arrays of strings.
Apply this diff:
- if let Some(original_member) = deps.get(&dependency_text.to_string()) { + if let Some(original_member) = deps.get(dependency_text.text()) { @@ - deps.insert( - dependency_text.to_string(), + deps.insert( + dependency_text.text().to_string(), dependency_name.value_token().ok()?, );
190-217
: Remove redundant?
after you’ve guarded theOption
sYou already continue on None; using
?
here is redundant and slightly obscures intent.Apply this diff:
- for (key, properties) in UNIQUE_PROPERTY_KEYS { - let key_deps = dependencies.get(key); - - if key_deps.is_none() { - continue; - } - - for property in properties { - let deps = dependencies.get(*property); - - if deps.is_none() { - continue; - } - - for (dependency_name, original_member) in key_deps? { - if let Some(member) = deps?.get(dependency_name) { + for (key, properties) in UNIQUE_PROPERTY_KEYS { + let Some(key_deps) = dependencies.get(key) else { continue; }; + for property in properties { + let Some(deps) = dependencies.get(*property) else { continue; }; + for (dependency_name, original_member) in key_deps { + if let Some(member) = deps.get(dependency_name) {
49-61
: Consider alias parity: bundleDependencies ↔ bundledDependenciesIf both alias fields are present, users likely expect duplicates across them to be flagged too. If that’s in scope, add a mapping; if not, ignore this.
Apply this diff (and adjust the loop as per next comment if you change the type):
-const UNIQUE_PROPERTY_KEYS: [(&str, &[&str]); 2] = [ +const UNIQUE_PROPERTY_KEYS: &[(&str, &[&str])] = &[ @@ - ("peerDependencies", &["optionalDependencies"]), + ("peerDependencies", &["optionalDependencies"]), + ("bundleDependencies", &["bundledDependencies"]), ];Would you like me to add tests covering this alias case?
190-200
: If you switch UNIQUE_PROPERTY_KEYS to a slice, tweak the loopOnly needed if you apply the previous change.
Apply this diff:
- for (key, properties) in UNIQUE_PROPERTY_KEYS { + for (key, properties) in UNIQUE_PROPERTY_KEYS.iter() { let key_deps = dependencies.get(key);
225-251
: Polish the diagnostic phrasingSlightly crisper closing note.
Apply this diff:
- Some(diagnostic.note(markup! { - "This can lead to package manager issues and confusion for other developers. To resolve this, remove one of the listings." - })) + Some(diagnostic.note(markup! { + "This can lead to package manager issues and confusion for other developers. Remove the duplicate entry." + }))
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{rs,toml}
📄 CodeRabbit inference engine (CONTRIBUTING.md)
Format Rust and TOML files before committing (use
just f
/just format
).
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*_{syntax,parser,formatter,analyze,factory,semantic}/**
📄 CodeRabbit inference engine (CLAUDE.md)
Maintain the per-language crate structure: biome_{lang}_{syntax,parser,formatter,analyze,factory,semantic}
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
crates/biome_*/**
📄 CodeRabbit inference engine (CLAUDE.md)
Place core crates under /crates/biome_*/
Files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧠 Learnings (11)
📓 Common learnings
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/biome_js_analyze/lib/src/lint/nursery/*.rs : For new JavaScript lint rules generated by `just new-js-lintrule`, implement the rule in the generated file under `biome_js_analyze/lib/src/lint/nursery/`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : In `declare_lint_rule!` declarations, set `version: "next"`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : When porting from other linters, declare `sources: &[RuleSource::<...>]` in `declare_lint_rule!` using `.same()` or `.inspired()` as appropriate
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : If a rule is deprecated, set the `deprecated:` field in `declare_lint_rule!` with a reason and alternative
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Place all new rules in the nursery group (implement new rule files under a `nursery` directory)
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Use `domains` in `declare_lint_rule!` when applicable; recommended rules with domains enable only when the domain is active
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Avoid `unwrap`/`expect`; use `?`, `ok()?`, and combinators (`map`, `and_then`, `filter`) to handle `Result`/`Option` when navigating the CST
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-17T08:56:30.831Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_analyze/CONTRIBUTING.md:0-0
Timestamp: 2025-08-17T08:56:30.831Z
Learning: Applies to crates/biome_analyze/crates/**/lib/src/**/nursery/**/*.rs : Prefer `Box<[_]>` over `Vec<_>` for multiple signals and convert via `Vec::into_boxed_slice()`
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:48:52.001Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_formatter/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:48:52.001Z
Learning: Applies to crates/biome_js_formatter/**/*.rs : Do not attempt to fix code: if a mandatory token/node is missing, return None instead
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
📚 Learning: 2025-08-11T11:50:12.090Z
Learnt from: CR
PR: biomejs/biome#0
File: crates/biome_js_type_info/CONTRIBUTING.md:0-0
Timestamp: 2025-08-11T11:50:12.090Z
Learning: Applies to crates/biome_js_type_info/src/**/*.rs : Represent links between types using TypeReference (not Arc) to avoid cross-module retention and recursive structures; store type data in linear vectors
Applied to files:
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs
🧬 Code graph analysis (1)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (1)
crates/biome_analyze/src/rule.rs (9)
language
(574-577)recommended
(554-557)sources
(569-572)same
(241-246)run
(1015-1015)diagnostic
(1102-1104)new
(534-552)new
(1298-1309)new
(1423-1435)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (25)
- GitHub Check: autofix
- GitHub Check: Check JS Files
- GitHub Check: Lint project (depot-windows-2022)
- GitHub Check: Test (depot-ubuntu-24.04-arm-16)
- GitHub Check: Test (depot-windows-2022-16)
- GitHub Check: Lint project (depot-ubuntu-24.04-arm-16)
- GitHub Check: Documentation
- GitHub Check: Check Dependencies
- GitHub Check: Bench (biome_module_graph)
- GitHub Check: Bench (biome_configuration)
- GitHub Check: Bench (biome_json_analyze)
- GitHub Check: Bench (biome_graphql_parser)
- GitHub Check: Bench (biome_html_parser)
- GitHub Check: Bench (biome_html_formatter)
- GitHub Check: Bench (biome_package)
- GitHub Check: Bench (biome_json_parser)
- GitHub Check: Bench (biome_js_parser)
- GitHub Check: Bench (biome_json_formatter)
- GitHub Check: Bench (biome_graphql_formatter)
- GitHub Check: Bench (biome_js_analyze)
- GitHub Check: Bench (biome_css_analyze)
- GitHub Check: Bench (biome_css_parser)
- GitHub Check: Bench (biome_js_formatter)
- GitHub Check: Bench (biome_css_formatter)
- GitHub Check: Test Node.js API
🔇 Additional comments (2)
crates/biome_json_analyze/src/lint/nursery/no_duplicate_dependencies.rs (2)
10-44
: Rule declaration looks solidGood: nursery placement, version "next", JSON language, sources mapped to ESLint counterparts, and examples included.
63-71
: Do we have tests foroverrides
duplicates?You include
overrides
in the scanned groups. Please ensure there’s at least one invalid fixture exercising a duplicate key insideoverrides
.I can add a spec case; shout if you want a PR to your branch.
@arendjr I think everything should be resolved now :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
Summary
Add
noDuplicateDependencies
rule to json linterref; #7051
Test Plan
Added unit tests for the rule.
Docs