diff --git a/crates/biome_analyze/src/rule.rs b/crates/biome_analyze/src/rule.rs index c857205b5bdc..1b7dc60e1af0 100644 --- a/crates/biome_analyze/src/rule.rs +++ b/crates/biome_analyze/src/rule.rs @@ -85,7 +85,7 @@ impl TryFrom for Applicability { } #[derive(Debug, Clone, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, schemars::JsonSchema))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub enum RuleSource { /// Rules from [Rust Clippy](https://rust-lang.github.io/rust-clippy/master/index.html) @@ -286,7 +286,7 @@ impl RuleSource { } #[derive(Debug, Default, Clone, Copy)] -#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, schemars::JsonSchema))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub enum RuleSourceKind { /// The rule implements the same logic of the source diff --git a/crates/biome_cli/src/commands/check.rs b/crates/biome_cli/src/commands/check.rs index b8cc90369ab1..616f9013e7f6 100644 --- a/crates/biome_cli/src/commands/check.rs +++ b/crates/biome_cli/src/commands/check.rs @@ -1,36 +1,24 @@ +use super::{determine_fix_file_mode, FixFileModeOptions, LoadEditorConfig}; use crate::cli_options::CliOptions; -use crate::commands::{ - get_files_to_process, get_stdin, resolve_manifest, validate_configuration_diagnostics, -}; -use crate::execute::VcsTargeted; -use crate::{ - execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, -}; +use crate::commands::{get_files_to_process_with_cli_options, CommandRunner}; +use crate::{CliDiagnostic, Execution, TraversalMode}; use biome_configuration::analyzer::assists::PartialAssistsConfiguration; use biome_configuration::{ organize_imports::PartialOrganizeImports, PartialConfiguration, PartialFormatterConfiguration, PartialLinterConfiguration, }; -use biome_console::{markup, ConsoleExt}; +use biome_console::Console; use biome_deserialize::Merge; -use biome_diagnostics::PrintDiagnostic; -use biome_service::configuration::{load_editorconfig, PartialConfigurationExt}; -use biome_service::workspace::RegisterProjectFolderParams; -use biome_service::{ - configuration::{load_configuration, LoadedConfiguration}, - workspace::UpdateSettingsParams, -}; +use biome_fs::FileSystem; +use biome_service::{configuration::LoadedConfiguration, DynRef, Workspace, WorkspaceError}; use std::ffi::OsString; -use super::{determine_fix_file_mode, FixFileModeOptions}; - pub(crate) struct CheckCommandPayload { pub(crate) apply: bool, pub(crate) apply_unsafe: bool, pub(crate) write: bool, pub(crate) fix: bool, pub(crate) unsafe_: bool, - pub(crate) cli_options: CliOptions, pub(crate) configuration: Option, pub(crate) paths: Vec, pub(crate) stdin_file_path: Option, @@ -43,174 +31,127 @@ pub(crate) struct CheckCommandPayload { pub(crate) since: Option, } -/// Handler for the "check" command of the Biome CLI -pub(crate) fn check( - session: CliSession, - payload: CheckCommandPayload, -) -> Result<(), CliDiagnostic> { - let CheckCommandPayload { - apply, - apply_unsafe, - write, - fix, - unsafe_, - cli_options, - configuration, - paths, - stdin_file_path, - linter_enabled, - organize_imports_enabled, - formatter_enabled, - since, - assists_enabled, - staged, - changed, - } = payload; - setup_cli_subscriber(cli_options.log_level, cli_options.log_kind); - - let fix_file_mode = determine_fix_file_mode( - FixFileModeOptions { - apply, - apply_unsafe, - write, - fix, - unsafe_, - }, - session.app.console, - )?; - - let loaded_configuration = - load_configuration(&session.app.fs, cli_options.as_configuration_path_hint())?; - validate_configuration_diagnostics( - &loaded_configuration, - session.app.console, - cli_options.verbose, - )?; - - let editorconfig_search_path = loaded_configuration.directory_path.clone(); - let LoadedConfiguration { - configuration: biome_configuration, - directory_path: configuration_path, - .. - } = loaded_configuration; - - let should_use_editorconfig = configuration - .as_ref() - .and_then(|c| c.use_editorconfig()) - .unwrap_or(biome_configuration.use_editorconfig().unwrap_or_default()); - let mut fs_configuration = if should_use_editorconfig { - let (editorconfig, editorconfig_diagnostics) = { - let search_path = editorconfig_search_path.unwrap_or_else(|| { - let fs = &session.app.fs; - fs.working_directory().unwrap_or_default() - }); - load_editorconfig(&session.app.fs, search_path)? - }; - for diagnostic in editorconfig_diagnostics { - session.app.console.error(markup! { - {PrintDiagnostic::simple(&diagnostic)} - }) - } - editorconfig.unwrap_or_default() - } else { - Default::default() - }; - // this makes biome configuration take precedence over editorconfig configuration - fs_configuration.merge_with(biome_configuration); - - let formatter = fs_configuration - .formatter - .get_or_insert_with(PartialFormatterConfiguration::default); - - if formatter_enabled.is_some() { - formatter.enabled = formatter_enabled; +impl LoadEditorConfig for CheckCommandPayload { + fn should_load_editor_config(&self, fs_configuration: &PartialConfiguration) -> bool { + self.configuration + .as_ref() + .and_then(|c| c.use_editorconfig()) + .unwrap_or(fs_configuration.use_editorconfig().unwrap_or_default()) } +} - let linter = fs_configuration - .linter - .get_or_insert_with(PartialLinterConfiguration::default); +impl CommandRunner for CheckCommandPayload { + const COMMAND_NAME: &'static str = "check"; + + fn merge_configuration( + &mut self, + loaded_configuration: LoadedConfiguration, + fs: &DynRef<'_, dyn FileSystem>, + console: &mut dyn Console, + ) -> Result { + let editorconfig_search_path = loaded_configuration.directory_path.clone(); + let LoadedConfiguration { + configuration: biome_configuration, + .. + } = loaded_configuration; + let mut fs_configuration = + self.load_editor_config(editorconfig_search_path, &biome_configuration, fs, console)?; + // this makes biome configuration take precedence over editorconfig configuration + fs_configuration.merge_with(biome_configuration); + + let formatter = fs_configuration + .formatter + .get_or_insert_with(PartialFormatterConfiguration::default); + + if self.formatter_enabled.is_some() { + formatter.enabled = self.formatter_enabled; + } - if linter_enabled.is_some() { - linter.enabled = linter_enabled; - } + let linter = fs_configuration + .linter + .get_or_insert_with(PartialLinterConfiguration::default); - let organize_imports = fs_configuration - .organize_imports - .get_or_insert_with(PartialOrganizeImports::default); + if self.linter_enabled.is_some() { + linter.enabled = self.linter_enabled; + } - if organize_imports_enabled.is_some() { - organize_imports.enabled = organize_imports_enabled; - } + let organize_imports = fs_configuration + .organize_imports + .get_or_insert_with(PartialOrganizeImports::default); - let assists = fs_configuration - .assists - .get_or_insert_with(PartialAssistsConfiguration::default); + if self.organize_imports_enabled.is_some() { + organize_imports.enabled = self.organize_imports_enabled; + } - if assists_enabled.is_some() { - assists.enabled = assists_enabled; - } + let assists = fs_configuration + .assists + .get_or_insert_with(PartialAssistsConfiguration::default); - if let Some(mut configuration) = configuration { - if let Some(linter) = configuration.linter.as_mut() { - // Don't overwrite rules from the CLI configuration. - // Otherwise, rules that are disabled in the config file might - // become re-enabled due to the defaults included in the CLI - // configuration. - linter.rules = None; + if self.assists_enabled.is_some() { + assists.enabled = self.assists_enabled; } - fs_configuration.merge_with(configuration); + + if let Some(mut configuration) = self.configuration.clone() { + if let Some(linter) = configuration.linter.as_mut() { + // Don't overwrite rules from the CLI configuration. + // Otherwise, rules that are disabled in the config file might + // become re-enabled due to the defaults included in the CLI + // configuration. + linter.rules = None; + } + fs_configuration.merge_with(configuration); + } + + Ok(fs_configuration) } - // check if support of git ignore files is enabled - let vcs_base_path = configuration_path.or(session.app.fs.working_directory()); - let (vcs_base_path, gitignore_matches) = - fs_configuration.retrieve_gitignore_matches(&session.app.fs, vcs_base_path.as_deref())?; - - let stdin = get_stdin(stdin_file_path, &mut *session.app.console, "check")?; - - let vcs_targeted_paths = get_files_to_process( - since.as_deref(), - changed, - staged, - &session.app.fs, - &fs_configuration, - )?; - - session - .app - .workspace - .register_project_folder(RegisterProjectFolderParams { - path: session.app.fs.working_directory(), - set_as_current_workspace: true, - })?; - let manifest_data = resolve_manifest(&session.app.fs)?; - - if let Some(manifest_data) = manifest_data { - session - .app - .workspace - .set_manifest_for_project(manifest_data.into())?; + fn get_files_to_process( + &self, + fs: &DynRef<'_, dyn FileSystem>, + configuration: &PartialConfiguration, + ) -> Result, CliDiagnostic> { + let paths = get_files_to_process_with_cli_options( + self.since.as_deref(), + self.changed, + self.staged, + fs, + configuration, + )? + .unwrap_or(self.paths.clone()); + + Ok(paths) } - session - .app - .workspace - .update_settings(UpdateSettingsParams { - workspace_directory: session.app.fs.working_directory(), - configuration: fs_configuration, - vcs_base_path, - gitignore_matches, - })?; - - execute_mode( - Execution::new(TraversalMode::Check { + fn get_stdin_file_path(&self) -> Option<&str> { + self.stdin_file_path.as_deref() + } + + fn should_write(&self) -> bool { + self.write || self.fix + } + + fn get_execution( + &self, + cli_options: &CliOptions, + console: &mut dyn Console, + _workspace: &dyn Workspace, + ) -> Result { + let fix_file_mode = determine_fix_file_mode( + FixFileModeOptions { + apply: self.apply, + apply_unsafe: self.apply_unsafe, + write: self.write, + fix: self.fix, + unsafe_: self.unsafe_, + }, + console, + )?; + + Ok(Execution::new(TraversalMode::Check { fix_file_mode, - stdin, - vcs_targeted: VcsTargeted { staged, changed }, + stdin: self.get_stdin(console)?, + vcs_targeted: (self.staged, self.changed).into(), }) - .set_report(&cli_options), - session, - &cli_options, - vcs_targeted_paths.unwrap_or(paths), - ) + .set_report(cli_options)) + } } diff --git a/crates/biome_cli/src/commands/ci.rs b/crates/biome_cli/src/commands/ci.rs index 34ac322ed075..be4689fcf04c 100644 --- a/crates/biome_cli/src/commands/ci.rs +++ b/crates/biome_cli/src/commands/ci.rs @@ -1,18 +1,15 @@ use crate::changed::get_changed_files; use crate::cli_options::CliOptions; -use crate::commands::{resolve_manifest, validate_configuration_diagnostics}; -use crate::execute::VcsTargeted; -use crate::{execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution}; +use crate::commands::{CommandRunner, LoadEditorConfig}; +use crate::{CliDiagnostic, Execution}; use biome_configuration::analyzer::assists::PartialAssistsConfiguration; use biome_configuration::{organize_imports::PartialOrganizeImports, PartialConfiguration}; use biome_configuration::{PartialFormatterConfiguration, PartialLinterConfiguration}; -use biome_console::{markup, ConsoleExt}; +use biome_console::Console; use biome_deserialize::Merge; -use biome_diagnostics::PrintDiagnostic; -use biome_service::configuration::{ - load_configuration, load_editorconfig, LoadedConfiguration, PartialConfigurationExt, -}; -use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; +use biome_fs::FileSystem; +use biome_service::configuration::LoadedConfiguration; +use biome_service::{DynRef, Workspace, WorkspaceError}; use std::ffi::OsString; pub(crate) struct CiCommandPayload { @@ -22,163 +19,124 @@ pub(crate) struct CiCommandPayload { pub(crate) assists_enabled: Option, pub(crate) paths: Vec, pub(crate) configuration: Option, - pub(crate) cli_options: CliOptions, pub(crate) changed: bool, pub(crate) since: Option, } -/// Handler for the "ci" command of the Biome CLI -pub(crate) fn ci(session: CliSession, payload: CiCommandPayload) -> Result<(), CliDiagnostic> { - let CiCommandPayload { - cli_options, - formatter_enabled, - linter_enabled, - organize_imports_enabled, - assists_enabled, - configuration, - mut paths, - since, - changed, - } = payload; - setup_cli_subscriber(cli_options.log_level, cli_options.log_kind); - - let loaded_configuration = - load_configuration(&session.app.fs, cli_options.as_configuration_path_hint())?; - - validate_configuration_diagnostics( - &loaded_configuration, - session.app.console, - cli_options.verbose, - )?; - - let LoadedConfiguration { - configuration: biome_configuration, - directory_path: configuration_path, - .. - } = loaded_configuration; - - let should_use_editorconfig = configuration - .as_ref() - .and_then(|c| c.use_editorconfig()) - .unwrap_or(biome_configuration.use_editorconfig().unwrap_or_default()); - let mut fs_configuration = if should_use_editorconfig { - let (editorconfig, editorconfig_diagnostics) = { - let search_path = configuration_path.clone().unwrap_or_else(|| { - let fs = &session.app.fs; - fs.working_directory().unwrap_or_default() - }); - load_editorconfig(&session.app.fs, search_path)? - }; - for diagnostic in editorconfig_diagnostics { - session.app.console.error(markup! { - {PrintDiagnostic::simple(&diagnostic)} - }) - } - editorconfig.unwrap_or_default() - } else { - Default::default() - }; - // this makes biome configuration take precedence over editorconfig configuration - fs_configuration.merge_with(biome_configuration); - - let formatter = fs_configuration - .formatter - .get_or_insert_with(PartialFormatterConfiguration::default); - - if formatter_enabled.is_some() { - formatter.enabled = formatter_enabled; +impl LoadEditorConfig for CiCommandPayload { + fn should_load_editor_config(&self, fs_configuration: &PartialConfiguration) -> bool { + self.configuration + .as_ref() + .and_then(|c| c.use_editorconfig()) + .unwrap_or(fs_configuration.use_editorconfig().unwrap_or_default()) } +} - let linter = fs_configuration - .linter - .get_or_insert_with(PartialLinterConfiguration::default); +impl CommandRunner for CiCommandPayload { + const COMMAND_NAME: &'static str = "ci"; + + fn merge_configuration( + &mut self, + loaded_configuration: LoadedConfiguration, + fs: &DynRef<'_, dyn FileSystem>, + console: &mut dyn Console, + ) -> Result { + let LoadedConfiguration { + configuration: biome_configuration, + directory_path: configuration_path, + .. + } = loaded_configuration; + + let mut fs_configuration = + self.load_editor_config(configuration_path, &biome_configuration, fs, console)?; + // this makes biome configuration take precedence over editorconfig configuration + fs_configuration.merge_with(biome_configuration); + + let formatter = fs_configuration + .formatter + .get_or_insert_with(PartialFormatterConfiguration::default); + + if self.formatter_enabled.is_some() { + formatter.enabled = self.formatter_enabled; + } - if linter_enabled.is_some() { - linter.enabled = linter_enabled; - } + let linter = fs_configuration + .linter + .get_or_insert_with(PartialLinterConfiguration::default); - let organize_imports = fs_configuration - .organize_imports - .get_or_insert_with(PartialOrganizeImports::default); + if self.linter_enabled.is_some() { + linter.enabled = self.linter_enabled; + } - if organize_imports_enabled.is_some() { - organize_imports.enabled = organize_imports_enabled; - } + let organize_imports = fs_configuration + .organize_imports + .get_or_insert_with(PartialOrganizeImports::default); - let assists = fs_configuration - .assists - .get_or_insert_with(PartialAssistsConfiguration::default); + if self.organize_imports_enabled.is_some() { + organize_imports.enabled = self.organize_imports_enabled; + } - if assists_enabled.is_some() { - assists.enabled = assists_enabled; - } + let assists = fs_configuration + .assists + .get_or_insert_with(PartialAssistsConfiguration::default); - // no point in doing the traversal if all the checks have been disabled - if fs_configuration.is_formatter_disabled() - && fs_configuration.is_linter_disabled() - && fs_configuration.is_organize_imports_disabled() - { - return Err(CliDiagnostic::incompatible_end_configuration("Formatter, linter and organize imports are disabled, can't perform the command. This is probably and error.")); + if self.assists_enabled.is_some() { + assists.enabled = self.assists_enabled; + } + + if let Some(mut configuration) = self.configuration.clone() { + if let Some(linter) = configuration.linter.as_mut() { + // Don't overwrite rules from the CLI configuration. + // Otherwise, rules that are disabled in the config file might + // become re-enabled due to the defaults included in the CLI + // configuration. + linter.rules = None; + } + fs_configuration.merge_with(configuration); + } + + Ok(fs_configuration) } - if let Some(mut configuration) = configuration { - if let Some(linter) = configuration.linter.as_mut() { - // Don't overwrite rules from the CLI configuration. - // Otherwise, rules that are disabled in the config file might - // become re-enabled due to the defaults included in the CLI - // configuration. - linter.rules = None; + fn get_files_to_process( + &self, + fs: &DynRef<'_, dyn FileSystem>, + configuration: &PartialConfiguration, + ) -> Result, CliDiagnostic> { + if self.changed { + get_changed_files(fs, configuration, self.since.as_deref()) + } else { + Ok(self.paths.clone()) } - fs_configuration.merge_with(configuration); } - // check if support of git ignore files is enabled - let vcs_base_path = configuration_path.or(session.app.fs.working_directory()); - let (vcs_base_path, gitignore_matches) = - fs_configuration.retrieve_gitignore_matches(&session.app.fs, vcs_base_path.as_deref())?; + fn get_stdin_file_path(&self) -> Option<&str> { + None + } - if since.is_some() && !changed { - return Err(CliDiagnostic::incompatible_arguments("since", "changed")); + fn should_write(&self) -> bool { + false } - if changed { - paths = get_changed_files(&session.app.fs, &fs_configuration, since.as_deref())?; + fn get_execution( + &self, + cli_options: &CliOptions, + _console: &mut dyn Console, + _workspace: &dyn Workspace, + ) -> Result { + Ok(Execution::new_ci((false, self.changed).into()).set_report(cli_options)) } - session - .app - .workspace - .register_project_folder(RegisterProjectFolderParams { - path: session.app.fs.working_directory(), - set_as_current_workspace: true, - })?; - - let manifest_data = resolve_manifest(&session.app.fs)?; - - if let Some(manifest_data) = manifest_data { - session - .app - .workspace - .set_manifest_for_project(manifest_data.into())?; + fn check_incompatible_arguments(&self) -> Result<(), CliDiagnostic> { + if matches!(self.formatter_enabled, Some(false)) + && matches!(self.linter_enabled, Some(false)) + && matches!(self.organize_imports_enabled, Some(false)) + { + return Err(CliDiagnostic::incompatible_end_configuration("Formatter, linter and organize imports are disabled, can't perform the command. At least one feature needs to be enabled. This is probably and error.")); + } + if self.since.is_some() && !self.changed { + return Err(CliDiagnostic::incompatible_arguments("since", "changed")); + } + Ok(()) } - session - .app - .workspace - .update_settings(UpdateSettingsParams { - configuration: fs_configuration, - workspace_directory: session.app.fs.working_directory(), - vcs_base_path, - gitignore_matches, - })?; - - execute_mode( - Execution::new_ci(VcsTargeted { - staged: false, - changed, - }) - .set_report(&cli_options), - session, - &cli_options, - paths, - ) } diff --git a/crates/biome_cli/src/commands/format.rs b/crates/biome_cli/src/commands/format.rs index 1d7c2072761e..6b876ff5691b 100644 --- a/crates/biome_cli/src/commands/format.rs +++ b/crates/biome_cli/src/commands/format.rs @@ -1,7 +1,6 @@ use crate::cli_options::CliOptions; -use crate::commands::{get_files_to_process, CommandRunner}; +use crate::commands::{get_files_to_process_with_cli_options, CommandRunner, LoadEditorConfig}; use crate::diagnostics::DeprecatedArgument; -use crate::execute::VcsTargeted; use crate::{CliDiagnostic, Execution, TraversalMode}; use biome_configuration::vcs::PartialVcsConfiguration; use biome_configuration::{ @@ -13,8 +12,8 @@ use biome_console::{markup, Console, ConsoleExt}; use biome_deserialize::Merge; use biome_diagnostics::PrintDiagnostic; use biome_fs::FileSystem; -use biome_service::configuration::{load_editorconfig, LoadedConfiguration}; -use biome_service::{DynRef, WorkspaceError}; +use biome_service::configuration::LoadedConfiguration; +use biome_service::{DynRef, Workspace, WorkspaceError}; use std::ffi::OsString; pub(crate) struct FormatCommandPayload { @@ -34,6 +33,15 @@ pub(crate) struct FormatCommandPayload { pub(crate) since: Option, } +impl LoadEditorConfig for FormatCommandPayload { + fn should_load_editor_config(&self, fs_configuration: &PartialConfiguration) -> bool { + self.formatter_configuration + .as_ref() + .and_then(|c| c.use_editorconfig) + .unwrap_or(fs_configuration.use_editorconfig().unwrap_or_default()) + } +} + impl CommandRunner for FormatCommandPayload { const COMMAND_NAME: &'static str = "format"; @@ -49,26 +57,8 @@ impl CommandRunner for FormatCommandPayload { .. } = loaded_configuration; let editorconfig_search_path = configuration_path.clone(); - let should_use_editorconfig = self - .formatter_configuration - .as_ref() - .and_then(|c| c.use_editorconfig) - .unwrap_or(biome_configuration.use_editorconfig().unwrap_or_default()); - let mut fs_configuration = if should_use_editorconfig { - let (editorconfig, editorconfig_diagnostics) = { - let search_path = editorconfig_search_path - .unwrap_or_else(|| fs.working_directory().unwrap_or_default()); - load_editorconfig(fs, search_path)? - }; - for diagnostic in editorconfig_diagnostics { - console.error(markup! { - {PrintDiagnostic::simple(&diagnostic)} - }) - } - editorconfig.unwrap_or_default() - } else { - Default::default() - }; + let mut fs_configuration = + self.load_editor_config(editorconfig_search_path, &biome_configuration, fs, console)?; // this makes biome configuration take precedence over editorconfig configuration fs_configuration.merge_with(biome_configuration); let mut configuration = fs_configuration; @@ -180,21 +170,20 @@ impl CommandRunner for FormatCommandPayload { fs: &DynRef<'_, dyn FileSystem>, configuration: &PartialConfiguration, ) -> Result, CliDiagnostic> { - if let Some(paths) = get_files_to_process( + let paths = get_files_to_process_with_cli_options( self.since.as_deref(), self.changed, self.staged, fs, configuration, - )? { - Ok(paths) - } else { - Ok(self.paths.clone()) - } + )? + .unwrap_or(self.paths.clone()); + + Ok(paths) } - fn get_stdin_file_path(&self) -> Option<&String> { - self.stdin_file_path.as_ref() + fn get_stdin_file_path(&self) -> Option<&str> { + self.stdin_file_path.as_deref() } fn should_write(&self) -> bool { @@ -205,15 +194,13 @@ impl CommandRunner for FormatCommandPayload { &self, cli_options: &CliOptions, console: &mut dyn Console, + _workspace: &dyn Workspace, ) -> Result { Ok(Execution::new(TraversalMode::Format { ignore_errors: cli_options.skip_errors, write: self.should_write(), stdin: self.get_stdin(console)?, - vcs_targeted: VcsTargeted { - staged: self.staged, - changed: self.changed, - }, + vcs_targeted: (self.staged, self.changed).into(), }) .set_report(cli_options)) } diff --git a/crates/biome_cli/src/commands/lint.rs b/crates/biome_cli/src/commands/lint.rs index 6f4deec7861a..065674b2e4c8 100644 --- a/crates/biome_cli/src/commands/lint.rs +++ b/crates/biome_cli/src/commands/lint.rs @@ -1,11 +1,7 @@ +use super::{determine_fix_file_mode, FixFileModeOptions}; use crate::cli_options::CliOptions; -use crate::commands::{ - get_files_to_process, get_stdin, resolve_manifest, validate_configuration_diagnostics, -}; -use crate::execute::VcsTargeted; -use crate::{ - execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, -}; +use crate::commands::{get_files_to_process_with_cli_options, CommandRunner}; +use crate::{CliDiagnostic, Execution, TraversalMode}; use biome_configuration::analyzer::RuleSelector; use biome_configuration::css::PartialCssLinter; use biome_configuration::javascript::PartialJavascriptLinter; @@ -15,22 +11,19 @@ use biome_configuration::{ PartialConfiguration, PartialFilesConfiguration, PartialGraphqlLinter, PartialLinterConfiguration, }; +use biome_console::Console; use biome_deserialize::Merge; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; -use biome_service::workspace::{RegisterProjectFolderParams, UpdateSettingsParams}; +use biome_fs::FileSystem; +use biome_service::configuration::LoadedConfiguration; +use biome_service::{DynRef, Workspace, WorkspaceError}; use std::ffi::OsString; -use super::{determine_fix_file_mode, FixFileModeOptions}; - pub(crate) struct LintCommandPayload { pub(crate) apply: bool, pub(crate) apply_unsafe: bool, pub(crate) write: bool, pub(crate) fix: bool, pub(crate) unsafe_: bool, - pub(crate) cli_options: CliOptions, pub(crate) linter_configuration: Option, pub(crate) vcs_configuration: Option, pub(crate) files_configuration: Option, @@ -47,149 +40,112 @@ pub(crate) struct LintCommandPayload { pub(crate) graphql_linter: Option, } -/// Handler for the "lint" command of the Biome CLI -pub(crate) fn lint(session: CliSession, payload: LintCommandPayload) -> Result<(), CliDiagnostic> { - let LintCommandPayload { - apply, - apply_unsafe, - write, - fix, - unsafe_, - cli_options, - mut linter_configuration, - paths, - only, - skip, - stdin_file_path, - vcs_configuration, - files_configuration, - staged, - changed, - since, - javascript_linter, - css_linter, - json_linter, - graphql_linter, - } = payload; - setup_cli_subscriber(cli_options.log_level, cli_options.log_kind); +impl CommandRunner for LintCommandPayload { + const COMMAND_NAME: &'static str = "lint"; - let fix_file_mode = determine_fix_file_mode( - FixFileModeOptions { - apply, - apply_unsafe, - write, - fix, - unsafe_, - }, - session.app.console, - )?; + fn merge_configuration( + &mut self, + loaded_configuration: LoadedConfiguration, + _fs: &DynRef<'_, dyn FileSystem>, + _console: &mut dyn Console, + ) -> Result { + let LoadedConfiguration { + configuration: mut fs_configuration, + .. + } = loaded_configuration; - let loaded_configuration = - load_configuration(&session.app.fs, cli_options.as_configuration_path_hint())?; - validate_configuration_diagnostics( - &loaded_configuration, - session.app.console, - cli_options.verbose, - )?; + fs_configuration.merge_with(PartialConfiguration { + linter: if fs_configuration + .linter + .as_ref() + .is_some_and(PartialLinterConfiguration::is_disabled) + { + None + } else { + if let Some(linter) = self.linter_configuration.as_mut() { + // Don't overwrite rules from the CLI configuration. + linter.rules = None; + } + self.linter_configuration.clone() + }, + files: self.files_configuration.clone(), + vcs: self.vcs_configuration.clone(), + ..Default::default() + }); - let LoadedConfiguration { - configuration: mut fs_configuration, - directory_path: configuration_path, - .. - } = loaded_configuration; - fs_configuration.merge_with(PartialConfiguration { - linter: if fs_configuration - .linter - .as_ref() - .is_some_and(PartialLinterConfiguration::is_disabled) - { - None - } else { - if let Some(linter) = linter_configuration.as_mut() { - // Don't overwrite rules from the CLI configuration. - linter.rules = None; - } - linter_configuration - }, - files: files_configuration, - vcs: vcs_configuration, - ..Default::default() - }); + if self.css_linter.is_some() { + let css = fs_configuration.css.get_or_insert_with(Default::default); + css.linter.merge_with(self.css_linter.clone()); + } - if css_linter.is_some() { - let css = fs_configuration.css.get_or_insert_with(Default::default); - css.linter.merge_with(css_linter); - } + if self.graphql_linter.is_some() { + let graphql = fs_configuration + .graphql + .get_or_insert_with(Default::default); + graphql.linter.merge_with(self.graphql_linter.clone()); + } + if self.javascript_linter.is_some() { + let javascript = fs_configuration + .javascript + .get_or_insert_with(Default::default); + javascript.linter.merge_with(self.javascript_linter.clone()); + } + if self.json_linter.is_some() { + let json = fs_configuration.json.get_or_insert_with(Default::default); + json.linter.merge_with(self.json_linter.clone()); + } - if graphql_linter.is_some() { - let graphql = fs_configuration - .graphql - .get_or_insert_with(Default::default); - graphql.linter.merge_with(graphql_linter); + Ok(fs_configuration) } - if javascript_linter.is_some() { - let javascript = fs_configuration - .javascript - .get_or_insert_with(Default::default); - javascript.linter.merge_with(javascript_linter); - } - if json_linter.is_some() { - let json = fs_configuration.json.get_or_insert_with(Default::default); - json.linter.merge_with(json_linter); - } - - let vcs_targeted_paths = get_files_to_process( - since.as_deref(), - changed, - staged, - &session.app.fs, - &fs_configuration, - )?; - - // check if support of git ignore files is enabled - let vcs_base_path = configuration_path.or(session.app.fs.working_directory()); - let (vcs_base_path, gitignore_matches) = - fs_configuration.retrieve_gitignore_matches(&session.app.fs, vcs_base_path.as_deref())?; - let stdin = get_stdin(stdin_file_path, &mut *session.app.console, "lint")?; + fn get_files_to_process( + &self, + fs: &DynRef<'_, dyn FileSystem>, + configuration: &PartialConfiguration, + ) -> Result, CliDiagnostic> { + let paths = get_files_to_process_with_cli_options( + self.since.as_deref(), + self.changed, + self.staged, + fs, + configuration, + )? + .unwrap_or(self.paths.clone()); - session - .app - .workspace - .register_project_folder(RegisterProjectFolderParams { - path: session.app.fs.working_directory(), - set_as_current_workspace: true, - })?; - let manifest_data = resolve_manifest(&session.app.fs)?; + Ok(paths) + } - if let Some(manifest_data) = manifest_data { - session - .app - .workspace - .set_manifest_for_project(manifest_data.into())?; + fn get_stdin_file_path(&self) -> Option<&str> { + self.stdin_file_path.as_deref() } - session - .app - .workspace - .update_settings(UpdateSettingsParams { - workspace_directory: session.app.fs.working_directory(), - configuration: fs_configuration, - vcs_base_path, - gitignore_matches, - })?; + fn should_write(&self) -> bool { + self.write || self.fix + } - execute_mode( - Execution::new(TraversalMode::Lint { + fn get_execution( + &self, + cli_options: &CliOptions, + console: &mut dyn Console, + _workspace: &dyn Workspace, + ) -> Result { + let fix_file_mode = determine_fix_file_mode( + FixFileModeOptions { + apply: self.apply, + apply_unsafe: self.apply_unsafe, + write: self.write, + fix: self.fix, + unsafe_: self.unsafe_, + }, + console, + )?; + Ok(Execution::new(TraversalMode::Lint { fix_file_mode, - stdin, - only, - skip, - vcs_targeted: VcsTargeted { staged, changed }, + stdin: self.get_stdin(console)?, + only: self.only.clone(), + skip: self.skip.clone(), + vcs_targeted: (self.staged, self.changed).into(), }) - .set_report(&cli_options), - session, - &cli_options, - vcs_targeted_paths.unwrap_or(paths), - ) + .set_report(cli_options)) + } } diff --git a/crates/biome_cli/src/commands/migrate.rs b/crates/biome_cli/src/commands/migrate.rs index 7f0362f3ab90..ed29e23eb737 100644 --- a/crates/biome_cli/src/commands/migrate.rs +++ b/crates/biome_cli/src/commands/migrate.rs @@ -1,65 +1,93 @@ +use super::{ + check_fix_incompatible_arguments, CommandRunner, FixFileModeOptions, MigrateSubCommand, +}; use crate::cli_options::CliOptions; use crate::diagnostics::MigrationDiagnostic; -use crate::execute::{execute_mode, Execution, TraversalMode}; -use crate::{setup_cli_subscriber, CliDiagnostic, CliSession}; -use biome_console::{markup, ConsoleExt}; -use biome_service::configuration::{load_configuration, LoadedConfiguration}; -use biome_service::workspace::RegisterProjectFolderParams; +use crate::execute::{Execution, TraversalMode}; +use crate::CliDiagnostic; +use biome_configuration::PartialConfiguration; +use biome_console::{markup, Console, ConsoleExt}; +use biome_fs::FileSystem; +use biome_service::configuration::LoadedConfiguration; +use biome_service::{DynRef, Workspace, WorkspaceError}; +use std::ffi::OsString; +use std::path::PathBuf; -use super::{check_fix_incompatible_arguments, FixFileModeOptions, MigrateSubCommand}; +pub(crate) struct MigrateCommandPayload { + pub(crate) write: bool, + pub(crate) fix: bool, + pub(crate) sub_command: Option, + pub(crate) configuration_file_path: Option, + pub(crate) configuration_directory_path: Option, +} + +impl CommandRunner for MigrateCommandPayload { + const COMMAND_NAME: &'static str = "migrate"; -/// Handler for the "migrate" command of the Biome CLI -pub(crate) fn migrate( - session: CliSession, - cli_options: CliOptions, - write: bool, - fix: bool, - sub_command: Option, -) -> Result<(), CliDiagnostic> { - let base_path = cli_options.as_configuration_path_hint(); - let LoadedConfiguration { - configuration: _, - diagnostics: _, - directory_path, - file_path, - } = load_configuration(&session.app.fs, base_path)?; - setup_cli_subscriber(cli_options.log_level, cli_options.log_kind); + fn merge_configuration( + &mut self, + loaded_configuration: LoadedConfiguration, + _fs: &DynRef<'_, dyn FileSystem>, + _console: &mut dyn Console, + ) -> Result { + self.configuration_file_path = loaded_configuration.file_path; + self.configuration_directory_path = loaded_configuration.directory_path; + Ok(loaded_configuration.configuration) + } - check_fix_incompatible_arguments(FixFileModeOptions { - apply: false, - apply_unsafe: false, - write, - fix, - unsafe_: false, - })?; + fn get_files_to_process( + &self, + _fs: &DynRef<'_, dyn FileSystem>, + _configuration: &PartialConfiguration, + ) -> Result, CliDiagnostic> { + Ok(vec![]) + } - session - .app - .workspace - .register_project_folder(RegisterProjectFolderParams { - path: session.app.fs.working_directory(), - set_as_current_workspace: true, - })?; + fn get_stdin_file_path(&self) -> Option<&str> { + None + } - if let (Some(path), Some(directory_path)) = (file_path, directory_path) { - execute_mode( - Execution::new(TraversalMode::Migrate { - write: write || fix, + fn should_write(&self) -> bool { + self.write || self.fix + } + + fn get_execution( + &self, + _cli_options: &CliOptions, + console: &mut dyn Console, + _workspace: &dyn Workspace, + ) -> Result { + if let (Some(path), Some(directory_path)) = ( + self.configuration_file_path.clone(), + self.configuration_directory_path.clone(), + ) { + Ok(Execution::new(TraversalMode::Migrate { + write: self.should_write(), configuration_file_path: path, configuration_directory_path: directory_path, - sub_command, - }), - session, - &cli_options, - vec![], - ) - } else { - let console = session.app.console; - console.log(markup! { + sub_command: self.sub_command.clone(), + })) + } else { + console.log(markup! { "If this project has not yet been set up with Biome yet, please follow the ""Getting Started guide"" first." }); - Err(CliDiagnostic::MigrateError(MigrationDiagnostic { - reason: "Biome couldn't find the Biome configuration file.".to_string(), - })) + Err(CliDiagnostic::MigrateError(MigrationDiagnostic { + reason: "Biome couldn't find the Biome configuration file.".to_string(), + })) + } + } + + fn check_incompatible_arguments(&self) -> Result<(), CliDiagnostic> { + check_fix_incompatible_arguments(FixFileModeOptions { + apply: false, + apply_unsafe: false, + write: self.write, + fix: self.fix, + unsafe_: false, + }) + } + + fn should_validate_configuration_diagnostics(&self) -> bool { + false } } diff --git a/crates/biome_cli/src/commands/mod.rs b/crates/biome_cli/src/commands/mod.rs index 188bf7820769..0101d9545236 100644 --- a/crates/biome_cli/src/commands/mod.rs +++ b/crates/biome_cli/src/commands/mod.rs @@ -25,7 +25,7 @@ use biome_console::{markup, Console, ConsoleExt}; use biome_diagnostics::{Diagnostic, PrintDiagnostic}; use biome_fs::{BiomePath, FileSystem}; use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, + load_configuration, load_editorconfig, LoadedConfiguration, PartialConfigurationExt, }; use biome_service::documentation::Doc; use biome_service::workspace::{FixFileMode, RegisterProjectFolderParams, UpdateSettingsParams}; @@ -612,7 +612,7 @@ impl BiomeCommand { /// It accepts a [LoadedPartialConfiguration] and it prints the diagnostics emitted during parsing and deserialization. /// -/// If it contains errors, it return an error. +/// If it contains [errors](Severity::Error) or higher, it returns an error. pub(crate) fn validate_configuration_diagnostics( loaded_configuration: &LoadedConfiguration, console: &mut dyn Console, @@ -670,32 +670,7 @@ fn resolve_manifest( Ok(None) } -/// Computes [Stdin] if the CLI has the necessary information. -/// -/// ## Errors -/// - If the user didn't provide anything via `stdin` but the option `--stdin-file-path` is passed. -pub(crate) fn get_stdin( - stdin_file_path: Option, - console: &mut dyn Console, - command_name: &str, -) -> Result, CliDiagnostic> { - let stdin = if let Some(stdin_file_path) = stdin_file_path { - let input_code = console.read(); - if let Some(input_code) = input_code { - let path = PathBuf::from(stdin_file_path); - Some((path, input_code).into()) - } else { - // we provided the argument without a piped stdin, we bail - return Err(CliDiagnostic::missing_argument("stdin", command_name)); - } - } else { - None - }; - - Ok(stdin) -} - -fn get_files_to_process( +fn get_files_to_process_with_cli_options( since: Option<&str>, changed: bool, staged: bool, @@ -850,7 +825,13 @@ pub(crate) trait CommandRunner: Sized { ) -> Result<(Execution, Vec), CliDiagnostic> { let loaded_configuration = load_configuration(fs, cli_options.as_configuration_path_hint())?; - validate_configuration_diagnostics(&loaded_configuration, console, cli_options.verbose)?; + if self.should_validate_configuration_diagnostics() { + validate_configuration_diagnostics( + &loaded_configuration, + console, + cli_options.verbose, + )?; + } let configuration_path = loaded_configuration.directory_path.clone(); let configuration = self.merge_configuration(loaded_configuration, fs, console)?; let vcs_base_path = configuration_path.or(fs.working_directory()); @@ -874,7 +855,7 @@ pub(crate) trait CommandRunner: Sized { gitignore_matches, })?; - let execution = self.get_execution(cli_options, console)?; + let execution = self.get_execution(cli_options, console, workspace)?; Ok((execution, paths)) } @@ -919,7 +900,7 @@ pub(crate) trait CommandRunner: Sized { ) -> Result, CliDiagnostic>; /// It returns the file path to use in `stdin` mode. - fn get_stdin_file_path(&self) -> Option<&String>; + fn get_stdin_file_path(&self) -> Option<&str>; /// Whether the command should write the files. fn should_write(&self) -> bool; @@ -929,6 +910,7 @@ pub(crate) trait CommandRunner: Sized { &self, cli_options: &CliOptions, console: &mut dyn Console, + workspace: &dyn Workspace, ) -> Result; // Below, methods that consumers can implement @@ -939,6 +921,42 @@ pub(crate) trait CommandRunner: Sized { fn check_incompatible_arguments(&self) -> Result<(), CliDiagnostic> { Ok(()) } + + /// Checks whether the configuration has errors. + fn should_validate_configuration_diagnostics(&self) -> bool { + true + } +} + +pub trait LoadEditorConfig: CommandRunner { + /// Whether this command should load the `.editorconfig` file. + fn should_load_editor_config(&self, fs_configuration: &PartialConfiguration) -> bool; + + /// It loads the `.editorconfig` from the file system, parses it and deserialize it into a [PartialConfiguration] + fn load_editor_config( + &self, + configuration_path: Option, + fs_configuration: &PartialConfiguration, + fs: &DynRef<'_, dyn FileSystem>, + console: &mut dyn Console, + ) -> Result { + Ok(if self.should_load_editor_config(fs_configuration) { + let (editorconfig, editorconfig_diagnostics) = { + let search_path = configuration_path + .clone() + .unwrap_or_else(|| fs.working_directory().unwrap_or_default()); + load_editorconfig(fs, search_path)? + }; + for diagnostic in editorconfig_diagnostics { + console.error(markup! { + {PrintDiagnostic::simple(&diagnostic)} + }) + } + editorconfig.unwrap_or_default() + } else { + Default::default() + }) + } } #[cfg(test)] diff --git a/crates/biome_cli/src/commands/search.rs b/crates/biome_cli/src/commands/search.rs index 3e912f1dcec8..233d526b5da6 100644 --- a/crates/biome_cli/src/commands/search.rs +++ b/crates/biome_cli/src/commands/search.rs @@ -1,20 +1,18 @@ use crate::cli_options::CliOptions; -use crate::commands::{get_stdin, resolve_manifest, validate_configuration_diagnostics}; -use crate::{ - execute_mode, setup_cli_subscriber, CliDiagnostic, CliSession, Execution, TraversalMode, +use crate::commands::CommandRunner; +use crate::{CliDiagnostic, Execution, TraversalMode}; +use biome_configuration::{ + vcs::PartialVcsConfiguration, PartialConfiguration, PartialFilesConfiguration, }; -use biome_configuration::{vcs::PartialVcsConfiguration, PartialFilesConfiguration}; +use biome_console::Console; use biome_deserialize::Merge; -use biome_service::configuration::{ - load_configuration, LoadedConfiguration, PartialConfigurationExt, -}; -use biome_service::workspace::{ - ParsePatternParams, RegisterProjectFolderParams, UpdateSettingsParams, -}; +use biome_fs::FileSystem; +use biome_service::configuration::LoadedConfiguration; +use biome_service::workspace::ParsePatternParams; +use biome_service::{DynRef, Workspace, WorkspaceError}; use std::ffi::OsString; pub(crate) struct SearchCommandPayload { - pub(crate) cli_options: CliOptions, pub(crate) files_configuration: Option, pub(crate) paths: Vec, pub(crate) pattern: String, @@ -22,80 +20,57 @@ pub(crate) struct SearchCommandPayload { pub(crate) vcs_configuration: Option, } -/// Handler for the "search" command of the Biome CLI -pub(crate) fn search( - session: CliSession, - payload: SearchCommandPayload, -) -> Result<(), CliDiagnostic> { - let SearchCommandPayload { - cli_options, - files_configuration, - paths, - pattern, - stdin_file_path, - vcs_configuration, - } = payload; - setup_cli_subscriber(cli_options.log_level, cli_options.log_kind); - - let loaded_configuration = - load_configuration(&session.app.fs, cli_options.as_configuration_path_hint())?; - validate_configuration_diagnostics( - &loaded_configuration, - session.app.console, - cli_options.verbose, - )?; - - let LoadedConfiguration { - mut configuration, - directory_path: configuration_path, - .. - } = loaded_configuration; - - configuration.files.merge_with(files_configuration); - configuration.vcs.merge_with(vcs_configuration); - - // check if support for git ignore files is enabled - let vcs_base_path = configuration_path.or(session.app.fs.working_directory()); - let (vcs_base_path, gitignore_matches) = - configuration.retrieve_gitignore_matches(&session.app.fs, vcs_base_path.as_deref())?; +impl CommandRunner for SearchCommandPayload { + const COMMAND_NAME: &'static str = "search"; - session - .app - .workspace - .register_project_folder(RegisterProjectFolderParams { - path: session.app.fs.working_directory(), - set_as_current_workspace: true, - })?; - let manifest_data = resolve_manifest(&session.app.fs)?; + fn merge_configuration( + &mut self, + loaded_configuration: LoadedConfiguration, + _fs: &DynRef<'_, dyn FileSystem>, + _console: &mut dyn Console, + ) -> Result { + let LoadedConfiguration { + mut configuration, .. + } = loaded_configuration; + configuration + .files + .merge_with(self.files_configuration.clone()); + configuration.vcs.merge_with(self.vcs_configuration.clone()); - if let Some(manifest_data) = manifest_data { - session - .app - .workspace - .set_manifest_for_project(manifest_data.into())?; + Ok(configuration) } - session - .app - .workspace - .update_settings(UpdateSettingsParams { - workspace_directory: session.app.fs.working_directory(), - configuration, - vcs_base_path, - gitignore_matches, - })?; - - let console = &mut *session.app.console; - let stdin = get_stdin(stdin_file_path, console, "search")?; + fn get_files_to_process( + &self, + _fs: &DynRef<'_, dyn FileSystem>, + _configuration: &PartialConfiguration, + ) -> Result, CliDiagnostic> { + Ok(self.paths.clone()) + } - let pattern = session - .app - .workspace - .parse_pattern(ParsePatternParams { pattern })? - .pattern_id; + fn get_stdin_file_path(&self) -> Option<&str> { + self.stdin_file_path.as_deref() + } - let execution = - Execution::new(TraversalMode::Search { pattern, stdin }).set_report(&cli_options); + fn should_write(&self) -> bool { + false + } - execute_mode(execution, session, &cli_options, paths) + fn get_execution( + &self, + cli_options: &CliOptions, + _console: &mut dyn Console, + workspace: &dyn Workspace, + ) -> Result { + let pattern = workspace + .parse_pattern(ParsePatternParams { + pattern: self.pattern.clone(), + })? + .pattern_id; + Ok(Execution::new(TraversalMode::Search { + pattern, + stdin: self.get_stdin(_console)?, + }) + .set_report(cli_options)) + } } diff --git a/crates/biome_cli/src/execute/mod.rs b/crates/biome_cli/src/execute/mod.rs index 58620e90cce7..3cd4a8eb97a9 100644 --- a/crates/biome_cli/src/execute/mod.rs +++ b/crates/biome_cli/src/execute/mod.rs @@ -115,6 +115,12 @@ pub struct VcsTargeted { pub changed: bool, } +impl From<(bool, bool)> for VcsTargeted { + fn from((staged, changed): (bool, bool)) -> Self { + Self { staged, changed } + } +} + #[derive(Debug, Clone)] pub enum TraversalMode { /// This mode is enabled when running the command `biome check` diff --git a/crates/biome_cli/src/lib.rs b/crates/biome_cli/src/lib.rs index 88ebd8d09463..ca7fff6a4ab6 100644 --- a/crates/biome_cli/src/lib.rs +++ b/crates/biome_cli/src/lib.rs @@ -28,6 +28,7 @@ use crate::commands::check::CheckCommandPayload; use crate::commands::ci::CiCommandPayload; use crate::commands::format::FormatCommandPayload; use crate::commands::lint::LintCommandPayload; +use crate::commands::migrate::MigrateCommandPayload; use crate::commands::CommandRunner; pub use crate::commands::{biome_command, BiomeCommand}; pub use crate::logging::{setup_cli_subscriber, LoggingLevel}; @@ -104,15 +105,15 @@ impl<'app> CliSession<'app> { staged, changed, since, - } => commands::check::check( + } => run_command( self, + &cli_options, CheckCommandPayload { apply_unsafe, apply, write, fix, unsafe_, - cli_options, configuration, paths, stdin_file_path, @@ -146,15 +147,15 @@ impl<'app> CliSession<'app> { javascript_linter, json_linter, graphql_linter, - } => commands::lint::lint( + } => run_command( self, + &cli_options, LintCommandPayload { apply_unsafe, apply, write, fix, unsafe_, - cli_options, linter_configuration, paths, only, @@ -181,8 +182,9 @@ impl<'app> CliSession<'app> { cli_options, changed, since, - } => commands::ci::ci( + } => run_command( self, + &cli_options, CiCommandPayload { linter_enabled, formatter_enabled, @@ -190,7 +192,6 @@ impl<'app> CliSession<'app> { assists_enabled, configuration, paths, - cli_options, changed, since, }, @@ -244,7 +245,17 @@ impl<'app> CliSession<'app> { write, fix, sub_command, - } => commands::migrate::migrate(self, cli_options, write, fix, sub_command), + } => run_command( + self, + &cli_options, + MigrateCommandPayload { + write, + fix, + sub_command, + configuration_directory_path: None, + configuration_file_path: None, + }, + ), BiomeCommand::Search { cli_options, files_configuration, @@ -252,10 +263,10 @@ impl<'app> CliSession<'app> { pattern, stdin_file_path, vcs_configuration, - } => commands::search::search( + } => run_command( self, + &cli_options, SearchCommandPayload { - cli_options, files_configuration, paths, pattern, diff --git a/crates/biome_cli/tests/snapshots/main_commands_check/fs_files_ignore_symlink.snap b/crates/biome_cli/tests/snapshots/main_commands_check/fs_files_ignore_symlink.snap index 6737afed55d1..622b942847f1 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_check/fs_files_ignore_symlink.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_check/fs_files_ignore_symlink.snap @@ -5,17 +5,17 @@ expression: content # Emitted Messages ```block -internalError/fs DEPRECATED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +rome.json internalError/fs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ! The argument --apply-unsafe is deprecated, it will be removed in the next major release. Use --write --unsafe instead. + ! The configuration file rome.json is deprecated. Use biome.json instead. ``` ```block -rome.json internalError/fs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ +internalError/fs DEPRECATED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ - ! The configuration file rome.json is deprecated. Use biome.json instead. + ! The argument --apply-unsafe is deprecated, it will be removed in the next major release. Use --write --unsafe instead. ``` diff --git a/crates/biome_cli/tests/snapshots/main_commands_ci/ci_errors_for_all_disabled_checks.snap b/crates/biome_cli/tests/snapshots/main_commands_ci/ci_errors_for_all_disabled_checks.snap index 1997124eaa79..f5c8f95847b7 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_ci/ci_errors_for_all_disabled_checks.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_ci/ci_errors_for_all_disabled_checks.snap @@ -30,10 +30,8 @@ statement( ) ; let a = !b || !c; internalError/io ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ × The combination of configuration and arguments is invalid: - Formatter, linter and organize imports are disabled, can't perform the command. This is probably and error. + Formatter, linter and organize imports are disabled, can't perform the command. At least one feature needs to be enabled. This is probably and error. ``` - - diff --git a/crates/biome_cli/tests/snapshots/main_commands_migrate/should_create_biome_json_file.snap b/crates/biome_cli/tests/snapshots/main_commands_migrate/should_create_biome_json_file.snap index 3da5654f333b..b1b918cdb331 100644 --- a/crates/biome_cli/tests/snapshots/main_commands_migrate/should_create_biome_json_file.snap +++ b/crates/biome_cli/tests/snapshots/main_commands_migrate/should_create_biome_json_file.snap @@ -19,5 +19,3 @@ expression: content ```block The configuration rome.json has been successfully migrated. ``` - - diff --git a/crates/biome_css_analyze/src/utils.rs b/crates/biome_css_analyze/src/utils.rs index d87048e0a7f9..33ca5e959b08 100644 --- a/crates/biome_css_analyze/src/utils.rs +++ b/crates/biome_css_analyze/src/utils.rs @@ -219,14 +219,14 @@ pub fn get_reset_to_initial_properties(shorthand_property: &str) -> &'static [&' } fn is_custom_element(prop: &str) -> bool { - prop.contains('-') && prop.eq(prop.to_lowercase().as_str()) + prop.contains('-') && prop.eq(prop.to_lowercase_cow().as_ref()) } /// Check if the input string is a known type selector. pub fn is_known_type_selector(prop: &str) -> bool { - let input = prop.to_lowercase(); - HTML_TAGS.binary_search(&input.as_str()).is_ok() + let input = prop.to_lowercase_cow(); + HTML_TAGS.binary_search(&input.as_ref()).is_ok() || SVG_TAGS.binary_search(&prop).is_ok() - || MATH_ML_TAGS.binary_search(&input.as_str()).is_ok() + || MATH_ML_TAGS.binary_search(&input.as_ref()).is_ok() || is_custom_element(prop) }