fix(rome_cli): correctly compute file to handle in `rome ci`
MODIFY
crates/rome_cli/src/traversal.rs
crates/rome_cli/src/traversal.rs
@@ -547,10 +547,9 @@ impl<'ctx, 'app> TraversalContext for TraversalOptions<'ctx, 'app> {
TraversalMode::Check { .. } => self.can_lint(rome_path),
TraversalMode::CI { .. } => self
.can_lint(rome_path)
- .or_else(|_| self.can_format(rome_path)),
+ .and_then(|_| self.can_format(rome_path)),
TraversalMode::Format { .. } => self.can_format(rome_path),
};
-
match result {
Ok(result) => result.reason.is_none(),
Err(err) => {

MODIFY
crates/rome_cli/tests/commands/format.rs
crates/rome_cli/tests/commands/format.rs
use crate::configs::{
- CONFIG_DISABLED_FORMATTER, CONFIG_FORMAT, CONFIG_FORMATTER_IGNORED_FILES, CONFIG_ISSUE_3175_1,
- CONFIG_ISSUE_3175_2,
+ CONFIG_DISABLED_FORMATTER, CONFIG_FORMAT, CONFIG_FORMATTER_IGNORED_DIRECTORIES,
+ CONFIG_FORMATTER_IGNORED_FILES, CONFIG_ISSUE_3175_1, CONFIG_ISSUE_3175_2,
};
use crate::snap_test::{markup_to_string, SnapshotPayload};
use crate::{
@@ -134,6 +134,61 @@ fn write() {
));
}
+#[test]
+fn write_only_files_in_correct_base() {
+ let mut fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_to_format = Path::new("src/format.js");
+ fs.insert(
+ file_to_format.into(),
+ <&str>::clone(&UNFORMATTED).as_bytes(),
+ );
+
+ let file_to_not_format = Path::new("scripts/format.js");
+ fs.insert(file_to_not_format.into(), UNFORMATTED.as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("format"),
+ OsString::from("--write"),
+ OsString::from("./src"),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut file = fs
+ .open(file_to_format)
+ .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, FORMATTED, "we test the file is formatted");
+ drop(file);
+ let mut file = fs
+ .open(file_to_not_format)
+ .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, UNFORMATTED, "we test the file is not formatted");
+ drop(file);
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "write_only_files_in_correct_base",
+ fs,
+ console,
+ result,
+ ));
+}
+
// Ensures lint warnings are not printed in format mode
#[test]
fn lint_warning() {
@@ -918,6 +973,64 @@ fn does_not_format_ignored_files() {
));
}
+#[test]
+fn does_not_format_ignored_directories() {
+ let mut console = BufferConsole::default();
+ let mut fs = MemoryFileSystem::default();
+ let file_path = Path::new("rome.json");
+ fs.insert(
+ file_path.into(),
+ CONFIG_FORMATTER_IGNORED_DIRECTORIES.as_bytes(),
+ );
+
+ let ignored_file = Path::new("scripts/test.js");
+ fs.insert(ignored_file.into(), <&str>::clone(&UNFORMATTED).as_bytes());
+
+ let file_to_format = Path::new("src/test.js");
+ fs.insert(file_to_format.into(), UNFORMATTED.as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("format"),
+ OsString::from("./"),
+ OsString::from("--write"),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut file = fs
+ .open(ignored_file)
+ .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, UNFORMATTED, "we test the file is not formatted");
+ drop(file);
+ let mut file = fs
+ .open(file_to_format)
+ .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, FORMATTED, "we test the file is formatted");
+ drop(file);
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "does_not_format_ignored_directories",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn file_too_large() {
let mut fs = MemoryFileSystem::default();

MODIFY
crates/rome_cli/tests/configs.rs
crates/rome_cli/tests/configs.rs
@@ -172,6 +172,13 @@ pub const CONFIG_FORMATTER_IGNORED_FILES: &str = r#"{
}
"#;
+pub const CONFIG_FORMATTER_IGNORED_DIRECTORIES: &str = r#"{
+ "formatter": {
+ "ignore": ["scripts/*"]
+ }
+}
+"#;
+
pub const CONFIG_LINTER_IGNORED_FILES: &str = r#"{
"linter": {
"enabled": true,

MODIFY
crates/rome_cli/tests/snap_test.rs
crates/rome_cli/tests/snap_test.rs
@@ -3,7 +3,7 @@ use rome_console::fmt::{Formatter, Termcolor};
use rome_console::{markup, BufferConsole, Markup};
use rome_diagnostics::termcolor::NoColor;
use rome_fs::{FileSystemExt, MemoryFileSystem};
-use std::collections::HashMap;
+use std::collections::BTreeMap;
use std::env::current_exe;
use std::fmt::Write as _;
use std::path::PathBuf;
@@ -19,7 +19,7 @@ pub(crate) struct CliSnapshot {
/// the configuration, if set
pub configuration: Option<String>,
/// file name -> content
- pub files: HashMap<String, String>,
+ pub files: BTreeMap<String, String>,
/// messages written in console
pub messages: Vec<String>,
/// possible termination error of the CLI
@@ -31,7 +31,7 @@ impl CliSnapshot {
Self {
in_messages: InMessages::default(),
configuration: None,
- files: HashMap::default(),
+ files: BTreeMap::default(),
messages: Vec::new(),
termination: result.err(),
}
@@ -138,13 +138,18 @@ impl From<SnapshotPayload<'_>> for CliSnapshot {
}
}
- for (file, entry) in fs.files() {
+ let files: Vec<_> = fs
+ .files()
+ .into_iter()
+ .map(|(file, entry)| {
let content = entry.lock();
let content = std::str::from_utf8(content.as_slice()).unwrap();
+ (file.to_str().unwrap().to_string(), String::from(content))
+ })
+ .collect();
- cli_snapshot
- .files
- .insert(file.to_str().unwrap().to_string(), String::from(content));
+ for (file, content) in files {
+ cli_snapshot.files.insert(file, content);
}
let in_buffer = &console.in_buffer;

ADD
crates/rome_cli/tests/snapshots/main_commands_format/does_not_format_ignored_directories.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `rome.json`
+
+```json
+{
+ "formatter": {
+ "ignore": ["scripts/*"]
+ }
+}
+
+```
+
+## `scripts/test.js`
+
+```js
+ statement( )
+```
+
+## `src/test.js`
+
+```js
+statement();
+
+```
+
+# Emitted Messages
+
+

ADD
crates/rome_cli/tests/snapshots/main_commands_format/write_only_files_in_correct_base.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `scripts/format.js`
+
+```js
+ statement( )
+```
+
+## `src/format.js`
+
+```js
+statement();
+
+```
+
+# Emitted Messages
+
+

MODIFY
crates/rome_fs/src/fs/memory.rs
crates/rome_fs/src/fs/memory.rs
@@ -12,7 +12,7 @@ use parking_lot::{lock_api::ArcMutexGuard, Mutex, RawMutex, RwLock};
use rome_diagnostics::v2::Error;
use crate::fs::{FileSystemExt, OpenOptions};
-use crate::{FileSystem, TraversalContext, TraversalScope};
+use crate::{FileSystem, RomePath, TraversalContext, TraversalScope};
use super::{BoxedTraversal, File, UnhandledDiagnostic, UnhandledKind};
@@ -161,8 +161,21 @@ impl<'scope> TraversalScope<'scope> for MemoryTraversalScope<'scope> {
{
let files = &self.fs.files.0.read();
for path in files.keys() {
- if path.strip_prefix(&base).is_ok() {
+ let should_process_file = if base.starts_with(".") || base.starts_with("./") {
+ // we simulate absolute paths, so we can correctly strips out the base path from the path
+ let absolute_base = PathBuf::from("/").join(&base);
+ let absolute_path = Path::new("/").join(&path);
+ absolute_path.strip_prefix(&absolute_base).is_ok()
+ } else {
+ path.strip_prefix(&base).is_ok()
+ };
+
+ if should_process_file {
let file_id = ctx.interner().intern_path(path.into());
+ let rome_path = RomePath::new(&path, file_id);
+ if !ctx.can_handle(&rome_path) {
+ continue;
+ }
ctx.handle_file(path, file_id);
}
}

fix(rome_cli): correctly compute file to handle in `rome ci` (#3453)