Skip to content
This repository has been archived by the owner on Aug 31, 2023. It is now read-only.

feat(rome_cli): Add a new option --config-path to set the path to rome.json #4158

Merged
merged 10 commits into from
Feb 13, 2023
3 changes: 3 additions & 0 deletions crates/rome_cli/src/commands/help.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const CHECK: Markup = markup! {
"<Dim>"--apply"</Dim>" Apply safe fixes
"<Dim>"--apply-unsafe"</Dim>" Apply safe and unsafe fixes
"<Dim>"--max-diagnostics"</Dim>" Cap the amount of diagnostics displayed (default: 20)
"<Dim>"--config-path"</Dim>" Set the filesystem path to the directory of the rome.json configuration file
"<Dim>"--verbose"</Dim>" Print additional verbose advices on diagnostics
"
};
Expand Down Expand Up @@ -65,6 +66,7 @@ const CI: Markup = markup! {
"<Dim>"--formatter-enabled"</Dim>" Allow to enable or disable the formatter check. (default: true)
"<Dim>"--linter-enabled"</Dim>" Allow to enable or disable the linter check. (default: true)
"<Dim>"--max-diagnostics"</Dim>" Cap the amount of diagnostics displayed (default: 50)
"<Dim>"--config-path"</Dim>" Set the filesystem path to the directory of the rome.json configuration file
"<Dim>"--verbose"</Dim>" Print additional verbose advices on diagnostics"
{FORMAT_OPTIONS}
};
Expand All @@ -81,6 +83,7 @@ const FORMAT: Markup = markup! {
"<Dim>"--write"</Dim>" Edit the files in place (beware!) instead of printing the diff to the console
"<Dim>"--skip-errors"</Dim>" Skip over files containing syntax errors instead of emitting an error diagnostic.
"<Dim>"--max-diagnostics"</Dim>" Cap the amount of diagnostics displayed (default: 50)
"<Dim>"--config-path"</Dim>" Set the filesystem path to the directory of the rome.json configuration file
"<Dim>"--verbose"</Dim>" Print additional verbose advices on diagnostics"
{FORMAT_OPTIONS}
""<Dim>"--stdin-file-path <string>"</Dim>" 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
Expand Down
2 changes: 1 addition & 1 deletion crates/rome_cli/src/commands/rage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, None, false) {
Ok(None) => KeyValuePair("Status", markup!(<Dim>"unset"</Dim>)).fmt(fmt)?,
Ok(Some(deserialized)) => {
let (configuration, diagnostics) = deserialized.consume();
Expand Down
11 changes: 10 additions & 1 deletion crates/rome_cli/src/configuration.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::path::PathBuf;

use crate::{CliDiagnostic, CliSession};
use rome_deserialize::Deserialized;
use rome_service::{load_config, Configuration};
Expand All @@ -7,5 +9,12 @@ use rome_service::{load_config, Configuration};
pub(crate) fn load_configuration(
session: &mut CliSession,
) -> Result<Deserialized<Configuration>, CliDiagnostic> {
Ok(load_config(&session.app.fs, None)?.unwrap_or_default())
let config_path: Option<PathBuf> = session
.args
.opt_value_from_str("--config-path")
.map_err(|source| CliDiagnostic::parse_error("--config-path", source))?;

let is_config_path = config_path.is_some();

Ok(load_config(&session.app.fs, config_path, is_config_path)?.unwrap_or_default())
realtimetodie marked this conversation as resolved.
Show resolved Hide resolved
}
90 changes: 90 additions & 0 deletions crates/rome_cli/tests/commands/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
}"#;
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <TIME>
```


Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
source: crates/rome_cli/tests/snap_test.rs
assertion_line: 335
expression: content
---
## `file.js`

```js
content
```

# Termination Message

```block
/test/rome.json internalError/fs ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Rome couldn't read the following file, maybe for permissions reasons or it doesn't exists: /test/rome.json



```


3 changes: 2 additions & 1 deletion crates/rome_lsp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,12 +366,13 @@ impl Session {
pub(crate) async fn load_workspace_settings(&self) {
let base_path = self.base_path();

let status = match load_config(&self.fs, base_path) {
let status = match load_config(&self.fs, base_path, false) {
Ok(Some(deserialized)) => {
let (configuration, diagnostics) = deserialized.consume();
if diagnostics.is_empty() {
warn!("The deserialization of the configuration resulted in errors. Rome will its defaults where possible.");
}

info!("Loaded workspace settings: {configuration:#?}");

let result = self
Expand Down
34 changes: 19 additions & 15 deletions crates/rome_service/src/configuration/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,45 +120,49 @@ type LoadConfig = Result<Option<Deserialized<Configuration>>, WorkspaceError>;
/// This function is responsible to load the rome configuration.
///
/// The `file_system` will read the configuration file. A base path can be passed
pub fn load_config(file_system: &DynRef<dyn FileSystem>, base_path: Option<PathBuf>) -> LoadConfig {
pub fn load_config(
file_system: &DynRef<dyn FileSystem>,
base_path: Option<PathBuf>,
show_error: bool,
) -> LoadConfig {
let config_name = file_system.config_name();
let configuration_path = if let Some(base_path) = base_path {
let config_path = if let Some(ref base_path) = base_path {
realtimetodie marked this conversation as resolved.
Show resolved Hide resolved
base_path.join(config_name)
} else {
PathBuf::from(config_name)
};
info!(
"Attempting to load the configuration file at path {:?}",
configuration_path
"Attempting to read the configuration file from {:?}",
config_path
);
let options = OpenOptions::default().read(true);
let file = file_system.open_with_options(&configuration_path, options);
let file = file_system.open_with_options(&config_path, options);
match file {
Ok(mut file) => {
let mut buffer = String::new();
file.read_to_string(&mut buffer).map_err(|_| {
WorkspaceError::cant_read_file(format!("{}", configuration_path.display()))
WorkspaceError::cant_read_file(format!("{}", config_path.display()))
})?;

let deserialized = deserialize_from_json::<Configuration>(&buffer)
.with_file_path(&configuration_path.display().to_string());
.with_file_path(&config_path.display().to_string());
Ok(Some(deserialized))
}
Err(err) => {
// We throw an error only when the error is found.
// In case we don't fine the file, we swallow the error and we continue; not having
// a file should not be a cause of error (for now)
if err.kind() != ErrorKind::NotFound {
// We skip the error when the configuration file is not found
// and the base path is not explicitly set; not having a configuration
// file is not a cause of error
if show_error || err.kind() != ErrorKind::NotFound {
return Err(WorkspaceError::cant_read_file(format!(
"{}",
configuration_path.display()
config_path.display()
)));
}
error!(
"Could not find the file configuration at {:?}",
configuration_path.display()
"Could not read the configuration file from {:?}, reason:\n {}",
config_path.display(),
err
);
error!("Reason: {:?}", err);
Ok(None)
}
}
Expand Down
6 changes: 6 additions & 0 deletions website/src/pages/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ Set the formatting mode for markup: `off` prints everything as plain text,
`force` forces the formatting of markup using ANSI even if the console output
is determined to be incompatible

### `--config-path`

Set the filesystem path to the directory of the rome.json configuration file.
This is optional. Rome will try to read a rome.json configuration file from the
current working directory by default.

realtimetodie marked this conversation as resolved.
Show resolved Hide resolved
### `--use-server`

Connect to a running instance of the Rome daemon server
Expand Down