-
-
Notifications
You must be signed in to change notification settings - Fork 794
refactor(cli): make commands more generic #8485
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: e34489c 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 |
WalkthroughThis PR radically restructures the biome_cli command execution pipeline: it removes the old CommandRunner/TraversalMode/execute modules and per-file process_file/traverse/std_in implementations, and replaces them with a new runner framework (Execution, TraversalCommand, Crawler, Collector, Handler, Finalizer) plus concrete implementations for process-file variants (lint/format/check). Reporters now accept trait-object Execution references. Several command payloads were adapted to the TraversalCommand flow. Also adds runner impls, collectors, crawlers, finalizers, and a changeset; a previously included example was removed and CliOptions now derives Default. (≈85 words) Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)crates/**/*.rs📄 CodeRabbit inference engine (CONTRIBUTING.md)
Files:
🧠 Learnings (10)📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-27T23:04:02.022ZApplied to files:
📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-27T23:04:02.022ZApplied to files:
📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-24T18:04:57.309ZApplied to files:
📚 Learning: 2025-11-27T23:04:02.022ZApplied to files:
📚 Learning: 2025-12-12T10:11:05.549ZApplied to files:
🧬 Code graph analysis (1)crates/biome_cli/src/diagnostics.rs (4)
⏰ 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). (8)
🔇 Additional comments (1)
Comment |
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
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
crates/biome_cli/src/reporter/github.rs (1)
46-54: Verbose logic appears inverted.The condition at lines 48-52 seems backwards:
- When
verbose=trueanddiagnostic.tags().is_verbose(): logs the diagnostic- When
verbose=false: logs all diagnostics regardless of tagsThis means setting
--verbosewould show fewer diagnostics (only verbose-tagged ones), not more. Typically, verbose mode should show additional output, not restrict it.for diagnostic in &diagnostics_payload.diagnostics { if diagnostic.severity() >= diagnostics_payload.diagnostic_level { - if diagnostic.tags().is_verbose() && verbose { - self.0.log(markup! {{PrintGitHubDiagnostic(diagnostic)}}); - } else if !verbose { + if diagnostic.tags().is_verbose() { + if verbose { + self.0.log(markup! {{PrintGitHubDiagnostic(diagnostic)}}); + } + } else { self.0.log(markup! {{PrintGitHubDiagnostic(diagnostic)}}); } } }
🧹 Nitpick comments (26)
.changeset/tiny-dodos-ask.md (1)
5-5: Clarify what Biome now does, rather than what wasn't happening.The changeset describes a fix, but the phrasing is a bit passive. Following the changeset guidelines, consider rephrasing to be more explicit about the corrected behaviour — e.g., "Fixed an issue where Biome didn't track some info diagnostics in the final summary." This makes it clearer what users benefit from.
Suggested revision:
-Fixed an issue where some info diagnostics weren't tracked by the final summary. +Fixed an issue where Biome wasn't tracking some info diagnostics in the final summary.Based on coding guidelines for
.changeset/*.md, use past tense for actions taken and present tense for Biome's behaviour to maintain consistency across changesets.crates/biome_cli/src/runner/impls/process_file/check.rs (1)
53-55: Consider inverting the condition to avoid an empty branch.The empty
ifblock with a comment is a bit awkward. Negating the condition improves readability.- if execution.should_skip_parse_errors() && skipped_parse_error { - // Parse errors are already skipped during the analyze phase, so no need to do it here. - } else { + // Parse errors are already skipped during the analyze phase, so no need to do it here. + if !(execution.should_skip_parse_errors() && skipped_parse_error) { let format_result = FormatProcessFile::process_file(ctx, workspace_file, features_supported); // ... rest of the block - } + }crates/biome_cli/src/runner/impls/commands/custom_execution.rs (3)
14-17: Consider adding rustdoc to explain the wrapper's purpose.Whilst the struct is crate-private, a doc comment explaining that this wrapper adapts commands that don't require crawling into the CommandRunner framework would aid maintainability.
38-78: Consider adding rustdoc to clarify the trait's role.The trait encapsulates the contract for non-crawling commands, but lacks explanation of when and why to use it versus implementing CommandRunner directly. A brief doc comment would help future contributors.
147-154: Minor: Inconsistent parameter naming.Parameters are prefixed with
_but then used in the method body. Other delegating methods (lines 91-92, 99-100, etc.) don't use this prefix. Consider removing the underscore prefix for consistency.crates/biome_cli/src/runner/run.rs (1)
10-13: Redundant rebinding.The
let command = &mut command;on line 12 is unnecessary —commandis already declaredmut, so you can callcommand.run(...)directly.pub(crate) fn run_command( session: CliSession, log_options: &LogOptions, cli_options: &CliOptions, mut command: impl CommandRunner, ) -> Result<(), CliDiagnostic> { - let command = &mut command; command.run(session, log_options, cli_options) }crates/biome_cli/src/commands/migrate.rs (1)
125-148: Consider usingexpect()with an informative message instead ofunwrap().The
// SAFETYcomment on line 142 is helpful, butexpect()would provide a clearer panic message if the invariant is ever violated during future refactoring.- // SAFETY: checked during get_execution - configuration_file_path: self.configuration_file_path.clone().unwrap(), + configuration_file_path: self + .configuration_file_path + .clone() + .expect("configuration_file_path must be Some; checked during get_execution"),crates/biome_cli/src/runner/impls/finalizers/default.rs (1)
258-274: Minor inconsistency:GitLab {}vs other unit variants.Line 269 uses
Self::GitLab {}with empty braces whilst other unit-like variants (e.g.,Self::GitHub,Self::Junit) don't. This is valid Rust but inconsistent with the rest of the match arm.- CliReporter::GitLab => Self::GitLab {}, + CliReporter::GitLab => Self::GitLab,crates/biome_cli/src/reporter/gitlab.rs (1)
71-98: Minor naming inconsistency in unused parameters.Line 74 uses
_whilst line 83 uses_executionfor the same unused parameter type. Consider aligning them for consistency, though this is purely cosmetic.crates/biome_cli/src/runner/impls/process_file/format.rs (2)
36-42: Technical debt marker detected.The
NOTE: probably to revisitcomment suggests this boolean value needs review. Consider creating a tracking issue or adding more context about what specifically needs revisiting.Would you like me to open an issue to track this?
81-104: Consider consolidating the repeated empty-output check.The pattern of checking
if output.is_empty() { return Ok(FileStatus::Unchanged); }is duplicated for astro, vue, and svelte. A helper or early match could reduce repetition.+ let maybe_output = |ext: &str, input: &str, output: &str| -> Option<String> { + if output.is_empty() { + return None; + } + match ext { + "astro" => Some(AstroFileHandler::output(input, output)), + "vue" => Some(VueFileHandler::output(input, output)), + "svelte" => Some(SvelteFileHandler::output(input, output)), + _ => Some(output.to_string()), + } + }; + if !features_supported.supports_full_html_support() { - match workspace_file.as_extension() { - Some("astro") => { - if output.is_empty() { - return Ok(FileStatus::Unchanged); - } - output = AstroFileHandler::output(input.as_str(), output.as_str()); - } - // ... similar for vue and svelte + if let Some(ext) = workspace_file.as_extension() { + if let Some(processed) = maybe_output(ext, input.as_str(), output.as_str()) { + output = processed; + } else { + return Ok(FileStatus::Unchanged); + } + } }crates/biome_cli/src/runner/handler.rs (1)
103-105: Doc comment style: use backticks for code references.The rustdoc convention is to use backticks for inline code, e.g.,
`process_file`and`catch_unwind`, rather than square brackets (which are for linking to items in scope).- /// This function wraps the [process_file] function implementing the traversal - /// in a [catch_unwind] block and emit diagnostics in case of error (either the + /// This function wraps the `process_file` function implementing the traversal + /// in a `catch_unwind` block and emit diagnostics in case of error (either thecrates/biome_cli/src/runner/finalizer.rs (1)
14-15: Minor typo: "finalise" should be "finalize".For consistency with the trait and method naming, the comment should use "finalize".
/// Optional hook to run before finalization. Useful for commands that need - /// to work with the Workspace before finally finalise the command. + /// to work with the Workspace before finally finalizing the command.crates/biome_cli/src/reporter/json.rs (1)
33-39: Public visibility on struct fields.The
JsonReporterstruct haspubfields (notpub(crate)), making them accessible outside the crate. If this is intentional for external API usage, that's fine. Otherwise, considerpub(crate)for consistency withGithubReporter.crates/biome_cli/src/commands/check.rs (1)
250-265: Potential silent fallback when VCS options yield no files.When
get_files_to_process_with_cli_optionsreturnsOk(None), the code falls back toself.paths.clone(). Ifself.pathsis empty and no VCS files are found, this silently proceeds with an empty list rather than warning the user.Consider logging or warning when both VCS targeting and explicit paths result in no files to process, to help users debug unexpected "0 files checked" scenarios.
crates/biome_cli/src/commands/ci.rs (1)
42-51: Unused_environmentfield.The
_environmentfield is populated but never read. If this is intended for future use, consider adding a TODO comment. Otherwise, it could be removed to avoid dead code.struct CiExecution { - /// Whether the CI is running in a specific environment, e.g. GitHub, GitLab, etc. - _environment: Option<ExecutionEnvironment>, /// A flag to know vcs integrated options such as `--staged` or `--changed` are enabled vcs_targeted: VcsTargeted,If planned for future use, add a comment explaining the intent.
crates/biome_cli/src/commands/search.rs (1)
116-129: Language compatibility check could be extended.The
is_file_compatible_with_patternmethod currently handles JS and CSS. If Grit adds support for more languages (JSON, HTML, GraphQL), this will need updating.Consider adding a
// TODO: extend when GritTargetLanguage adds new variantscomment, or use a more exhaustive match to catch new variants at compile time:- match pattern_language { + #[deny(clippy::wildcard_enum_match_arm)] + match pattern_language {crates/biome_cli/src/reporter/summary.rs (1)
194-199: Consider adding a trailing slash check for "plugin" prefix.The
"plugin"prefix check at line 198 doesn't include a trailing delimiter, which could match unintended categories like"pluginmanager/". The other prefixes use"/"as a delimiter.fn should_report_lint_diagnostic(category: &Category) -> bool { category.name().starts_with("lint/") || category.name().starts_with("suppressions/") || category.name().starts_with("assist/") - || category.name().starts_with("plugin") + || category.name().starts_with("plugin/") }crates/biome_cli/src/runner/execution.rs (2)
43-47: Minor rustdoc typo.Line 46 has "It should returns" — should be "It should return".
- /// It should returns the value of `--stdin-file-path` + /// It should return the value of `--stdin-file-path` fn get_stdin_file_path(&self) -> Option<&str>;
166-189: Consider adding rustdoc forStdinmethods.As per coding guidelines, inline rustdoc documentation should be updated when adding new features in Rust crates.
impl Stdin { + /// Returns the virtual path associated with this stdin input. pub(crate) fn as_path(&self) -> &Utf8Path { self.0.as_path() } + /// Returns the content read from stdin. pub(crate) fn as_content(&self) -> &str { self.1.as_str() } }crates/biome_cli/src/runner/impls/commands/traversal.rs (1)
120-120: Minor typo in doc comment.Line 120 references
CommanderRunnerbut should beCommandRunner.- /// Alias of [CommanderRunner::get_files_to_process] + /// Alias of [CommandRunner::get_files_to_process] fn get_files_to_process(crates/biome_cli/src/reporter/terminal.rs (2)
165-186: Comments indicate deferred generalisation — consider tracking.Lines 174-176 note that the assumption about fixes "can be refined later". This is fine for the current refactor scope, but worth tracking to avoid stale assumptions as new execution types are added.
234-242: Assumption about search detection via match count.The comment on lines 235-237 indicates the code infers a search command by checking
summary.matches > 0. This works but couples the display logic to an implicit heuristic rather than queryingexecution.is_search()directly, which is already available.Consider using
execution.is_search()for consistency with the rest of the file:- // For now, we'll assume this is a search command if there are matches - // This can be refined later when we have more specific execution types - if summary.matches > 0 { + if execution.is_search() && summary.matches > 0 {crates/biome_cli/src/runner/process_file.rs (3)
64-69: Remove commented-out code or track with an issue.The
DiagnosticsWithActionsvariant is commented out. Either remove it entirely or open a tracking issue if this is planned functionality.
120-127: Trait methods lack rustdoc.As per coding guidelines, consider adding inline rustdoc for the
ProcessFiletrait methods to document their purpose and expected behaviour.
163-177: Remove large commented-out TODO block.This block contains old
TraversalModematching logic that's been superseded by the new design. Dead code in comments tends to rot; either remove it or extract to a tracking issue.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Summary
This PR refactors the CLI infrastructure to be as flexible as possible. The refactor breaks down the command execution in five entities:
enum, now it's a trait and each command implements itEverything has been placed inside the
runnerfolder.Also, I created some default types, and that's where the existing functionality resides.
The only part that isn't very "generic" is the use of
is_ci,is_format,is_check,is_searchandis_lint. I decided to keep them and tackle them later.I also fixed a bug where some info diagnostics weren't tracked.
Note
I mostly used AI to write the documentation inside
runner/mod.rsand track the missing features during the developments. Towards the end, I asked it to do some trivial renaming and reactors. The bulk of the logic was written by me.Test Plan
Updated the relevant snapshots.
Docs
N/A