diff --git a/crates/rome_cli/src/commands/help.rs b/crates/rome_cli/src/commands/help.rs index 3ae3b3f1be8..b4d30d650c0 100644 --- a/crates/rome_cli/src/commands/help.rs +++ b/crates/rome_cli/src/commands/help.rs @@ -37,6 +37,7 @@ const CHECK: Markup = markup! { ""--apply"" Apply safe fixes ""--apply-unsafe"" Apply safe and unsafe fixes ""--max-diagnostics"" Cap the amount of diagnostics displayed (default: 20) + ""--config-path"" Set the filesystem path to the directory of the rome.json configuration file ""--verbose"" Print additional verbose advices on diagnostics " }; @@ -65,6 +66,7 @@ const CI: Markup = markup! { ""--formatter-enabled"" Allow to enable or disable the formatter check. (default: true) ""--linter-enabled"" Allow to enable or disable the linter check. (default: true) ""--max-diagnostics"" Cap the amount of diagnostics displayed (default: 50) + ""--config-path"" Set the filesystem path to the directory of the rome.json configuration file ""--verbose"" Print additional verbose advices on diagnostics" {FORMAT_OPTIONS} }; @@ -81,6 +83,7 @@ const FORMAT: Markup = markup! { ""--write"" Edit the files in place (beware!) instead of printing the diff to the console ""--skip-errors"" Skip over files containing syntax errors instead of emitting an error diagnostic. ""--max-diagnostics"" Cap the amount of diagnostics displayed (default: 50) + ""--config-path"" Set the filesystem path to the directory of the rome.json configuration file ""--verbose"" Print additional verbose advices on diagnostics" {FORMAT_OPTIONS} """--stdin-file-path "" A file name with its extension to pass when reading from standard in, e.g. echo 'let a;' | rome format --stdin-file-path file.js diff --git a/crates/rome_cli/src/commands/rage.rs b/crates/rome_cli/src/commands/rage.rs index 1c2ede42274..f26c299c5c9 100644 --- a/crates/rome_cli/src/commands/rage.rs +++ b/crates/rome_cli/src/commands/rage.rs @@ -4,7 +4,7 @@ use rome_diagnostics::termcolor::{ColorChoice, WriteColor}; use rome_diagnostics::{termcolor, PrintDescription}; use rome_fs::FileSystem; use rome_service::workspace::{client, RageEntry, RageParams}; -use rome_service::{load_config, DynRef, Workspace}; +use rome_service::{load_config, BasePath, DynRef, Workspace}; use std::{env, io, ops::Deref}; use tokio::runtime::Runtime; @@ -163,7 +163,7 @@ impl Display for RageConfiguration<'_, '_> { fn fmt(&self, fmt: &mut Formatter) -> io::Result<()> { Section("Rome Configuration").fmt(fmt)?; - match load_config(self.0, None) { + match load_config(self.0, BasePath::default()) { Ok(None) => KeyValuePair("Status", markup!("unset")).fmt(fmt)?, Ok(Some(deserialized)) => { let (configuration, diagnostics) = deserialized.consume(); diff --git a/crates/rome_cli/src/configuration.rs b/crates/rome_cli/src/configuration.rs index 7dac5280f45..a1162040138 100644 --- a/crates/rome_cli/src/configuration.rs +++ b/crates/rome_cli/src/configuration.rs @@ -1,11 +1,25 @@ +use std::path::PathBuf; + use crate::{CliDiagnostic, CliSession}; use rome_deserialize::Deserialized; -use rome_service::{load_config, Configuration}; +use rome_service::{load_config, BasePath, Configuration}; /// Load the configuration for this session of the CLI, merging the content of /// the `rome.json` file if it exists on disk with common command line options pub(crate) fn load_configuration( session: &mut CliSession, ) -> Result, CliDiagnostic> { - Ok(load_config(&session.app.fs, None)?.unwrap_or_default()) + let config_path: Option = session + .args + .opt_value_from_str("--config-path") + .map_err(|source| CliDiagnostic::parse_error("--config-path", source))?; + + let base_path = match config_path { + None => BasePath::default(), + Some(path) => BasePath::FromUser(path), + }; + + let config = load_config(&session.app.fs, base_path)?; + + Ok(config.unwrap_or_default()) } diff --git a/crates/rome_cli/tests/commands/format.rs b/crates/rome_cli/tests/commands/format.rs index 9f861142e22..bed33cb90d8 100644 --- a/crates/rome_cli/tests/commands/format.rs +++ b/crates/rome_cli/tests/commands/format.rs @@ -44,6 +44,15 @@ const APPLY_TRAILING_COMMA_AFTER: &str = r#"const a = [ ]; "#; +const DEFAULT_CONFIGURATION_BEFORE: &str = r#"function f() { + return { a, b } + }"#; + +const DEFAULT_CONFIGURATION_AFTER: &str = "function f() { + return { a, b }; +} +"; + const CUSTOM_CONFIGURATION_BEFORE: &str = r#"function f() { return { a, b } }"#; @@ -236,6 +245,87 @@ fn lint_warning() { )); } +#[test] +fn custom_config_file_path() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let config_path = Path::new("/test/rome.json"); + fs.insert(config_path.into(), CONFIG_FORMAT.as_bytes()); + + let file_path = Path::new("file.js"); + fs.insert(file_path.into(), DEFAULT_CONFIGURATION_BEFORE.as_bytes()); + + let mut config_path = PathBuf::from(config_path); + config_path.pop(); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Arguments::from_vec(vec![ + OsString::from("format"), + OsString::from("--config-path"), + OsString::from(config_path), + OsString::from("--write"), + file_path.as_os_str().into(), + ]), + ); + + assert!(result.is_ok(), "run_cli returned {result:?}"); + + let mut file = fs + .open(file_path) + .expect("formatting target file was removed by the CLI"); + + let mut content = String::new(); + file.read_to_string(&mut content) + .expect("failed to read file from memory FS"); + + assert_eq!(content, DEFAULT_CONFIGURATION_AFTER); + + drop(file); + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "custom_config_file_path", + fs, + console, + result, + )); +} + +// Should throw an error when an invalid configuration path is specified +#[test] +fn invalid_config_file_path() { + let mut fs = MemoryFileSystem::default(); + let mut console = BufferConsole::default(); + + let config_path = Path::new("/test"); + let file_path = Path::new("file.js"); + fs.insert(file_path.into(), *b"content"); + + let result = run_cli( + DynRef::Borrowed(&mut fs), + &mut console, + Arguments::from_vec(vec![ + OsString::from("format"), + OsString::from("--config-path"), + OsString::from(config_path), + OsString::from("--write"), + file_path.as_os_str().into(), + ]), + ); + + assert!(result.is_err(), "run_cli returned {result:?}"); + + assert_cli_snapshot(SnapshotPayload::new( + module_path!(), + "invalid_config_file_path", + fs, + console, + result, + )); +} + #[test] fn applies_custom_configuration() { let mut fs = MemoryFileSystem::default(); diff --git a/crates/rome_cli/tests/snapshots/main_commands_format/custom_config_file_path.snap b/crates/rome_cli/tests/snapshots/main_commands_format/custom_config_file_path.snap new file mode 100644 index 00000000000..86e33f688cb --- /dev/null +++ b/crates/rome_cli/tests/snapshots/main_commands_format/custom_config_file_path.snap @@ -0,0 +1,35 @@ +--- +source: crates/rome_cli/tests/snap_test.rs +assertion_line: 335 +expression: content +--- +## `/test/rome.json` + +```json +{ + "formatter": { + "enabled": true, + "lineWidth": 160, + "indentStyle": "space", + "indentSize": 6 + } +} + +``` + +## `file.js` + +```js +function f() { + return { a, b }; +} + +``` + +# Emitted Messages + +```block +Formatted 1 file(s) in