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