feat(rome_cli): ignore option of files config
MODIFY
crates/rome_cli/tests/commands/check.rs
crates/rome_cli/tests/commands/check.rs
@@ -4,8 +4,9 @@ use std::ffi::OsString;
use std::path::{Path, PathBuf};
use crate::configs::{
- CONFIG_FILE_SIZE_LIMIT, CONFIG_LINTER_DISABLED, CONFIG_LINTER_DOWNGRADE_DIAGNOSTIC,
- CONFIG_LINTER_IGNORED_FILES, CONFIG_LINTER_SUPPRESSED_GROUP, CONFIG_LINTER_SUPPRESSED_RULE,
+ CONFIG_FILE_SIZE_LIMIT, CONFIG_LINTER_AND_FILES_IGNORE, CONFIG_LINTER_DISABLED,
+ CONFIG_LINTER_DOWNGRADE_DIAGNOSTIC, CONFIG_LINTER_IGNORED_FILES,
+ CONFIG_LINTER_SUPPRESSED_GROUP, CONFIG_LINTER_SUPPRESSED_RULE,
CONFIG_LINTER_UPGRADE_DIAGNOSTIC,
};
use crate::snap_test::SnapshotPayload;
@@ -612,6 +613,58 @@ fn no_lint_when_file_is_ignored() {
));
}
+#[test]
+fn no_lint_if_files_are_listed_in_ignore_option() {
+ let mut fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Path::new("rome.json");
+ fs.insert(file_path.into(), CONFIG_LINTER_AND_FILES_IGNORE.as_bytes());
+
+ let file_path_test1 = Path::new("test1.js");
+ fs.insert(file_path_test1.into(), FIX_BEFORE.as_bytes());
+
+ let file_path_test2 = Path::new("test2.js");
+ fs.insert(file_path_test2.into(), FIX_BEFORE.as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("check"),
+ OsString::from("--apply"),
+ file_path_test1.as_os_str().into(),
+ file_path_test2.as_os_str().into(),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut buffer = String::new();
+ fs.open(file_path_test1)
+ .unwrap()
+ .read_to_string(&mut buffer)
+ .unwrap();
+
+ assert_eq!(buffer, FIX_BEFORE);
+
+ let mut buffer = String::new();
+ fs.open(file_path_test2)
+ .unwrap()
+ .read_to_string(&mut buffer)
+ .unwrap();
+
+ assert_eq!(buffer, FIX_BEFORE);
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "no_lint_if_files_are_listed_in_ignore_option",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn fs_error_symlink() {
let mut fs = MemoryFileSystem::default();

MODIFY
crates/rome_cli/tests/commands/format.rs
crates/rome_cli/tests/commands/format.rs
use crate::configs::{
CONFIG_DISABLED_FORMATTER, CONFIG_FILE_SIZE_LIMIT, CONFIG_FORMAT,
- CONFIG_FORMATTER_IGNORED_DIRECTORIES, CONFIG_FORMATTER_IGNORED_FILES, CONFIG_ISSUE_3175_1,
- CONFIG_ISSUE_3175_2,
+ CONFIG_FORMATTER_AND_FILES_IGNORE, 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::{
@@ -974,6 +974,61 @@ fn does_not_format_ignored_files() {
));
}
+#[test]
+fn does_not_format_if_files_are_listed_in_ignore_option() {
+ let mut fs = MemoryFileSystem::default();
+ let mut console = BufferConsole::default();
+
+ let file_path = Path::new("rome.json");
+ fs.insert(
+ file_path.into(),
+ CONFIG_FORMATTER_AND_FILES_IGNORE.as_bytes(),
+ );
+
+ let file_path_test1 = Path::new("test1.js");
+ fs.insert(file_path_test1.into(), UNFORMATTED.as_bytes());
+
+ let file_path_test2 = Path::new("test2.js");
+ fs.insert(file_path_test2.into(), UNFORMATTED.as_bytes());
+
+ let result = run_cli(
+ DynRef::Borrowed(&mut fs),
+ DynRef::Borrowed(&mut console),
+ Arguments::from_vec(vec![
+ OsString::from("format"),
+ file_path_test1.as_os_str().into(),
+ file_path_test2.as_os_str().into(),
+ OsString::from("--write"),
+ ]),
+ );
+
+ assert!(result.is_ok(), "run_cli returned {result:?}");
+
+ let mut buffer = String::new();
+ fs.open(file_path_test1)
+ .unwrap()
+ .read_to_string(&mut buffer)
+ .unwrap();
+
+ assert_eq!(buffer, UNFORMATTED);
+
+ let mut buffer = String::new();
+ fs.open(file_path_test2)
+ .unwrap()
+ .read_to_string(&mut buffer)
+ .unwrap();
+
+ assert_eq!(buffer, UNFORMATTED);
+
+ assert_cli_snapshot(SnapshotPayload::new(
+ module_path!(),
+ "does_not_format_if_files_are_listed_in_ignore_option",
+ fs,
+ console,
+ result,
+ ));
+}
+
#[test]
fn does_not_format_ignored_directories() {
let mut console = BufferConsole::default();

MODIFY
crates/rome_cli/tests/configs.rs
crates/rome_cli/tests/configs.rs
@@ -172,6 +172,16 @@ pub const CONFIG_FORMATTER_IGNORED_FILES: &str = r#"{
}
"#;
+pub const CONFIG_FORMATTER_AND_FILES_IGNORE: &str = r#"{
+ "files": {
+ "ignore": ["test1.js"]
+ },
+ "formatter": {
+ "enabled": true,
+ "ignore": ["test2.js"]
+ }
+}"#;
+
pub const CONFIG_FORMATTER_IGNORED_DIRECTORIES: &str = r#"{
"formatter": {
"ignore": ["scripts/*"]
@@ -187,6 +197,16 @@ pub const CONFIG_LINTER_IGNORED_FILES: &str = r#"{
}
"#;
+pub const CONFIG_LINTER_AND_FILES_IGNORE: &str = r#"{
+ "files": {
+ "ignore": ["test1.js"]
+ },
+ "linter": {
+ "enabled": true,
+ "ignore": ["test2.js"]
+ }
+}"#;
+
pub const CONFIG_FILE_SIZE_LIMIT: &str = r#"{
"files": {
"maxSize": 16

ADD
crates/rome_cli/tests/snapshots/main_commands_check/no_lint_if_files_are_listed_in_ignore_option.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `rome.json`
+
+```json
+{
+ "files": {
+ "ignore": ["test1.js"]
+ },
+ "linter": {
+ "enabled": true,
+ "ignore": ["test2.js"]
+ }
+}
+```
+
+## `test1.js`
+
+```js
+
+if(a != -0) {}
+
+```
+
+## `test2.js`
+
+```js
+
+if(a != -0) {}
+
+```
+
+# Emitted Messages
+
+

ADD
crates/rome_cli/tests/snapshots/main_commands_format/does_not_format_if_files_are_listed_in_ignore_option.snap
+---
+source: crates/rome_cli/tests/snap_test.rs
+expression: content
+---
+## `rome.json`
+
+```json
+{
+ "files": {
+ "ignore": ["test1.js"]
+ },
+ "formatter": {
+ "enabled": true,
+ "ignore": ["test2.js"]
+ }
+}
+```
+
+## `test1.js`
+
+```js
+ statement( )
+```
+
+## `test2.js`
+
+```js
+ statement( )
+```
+
+# Emitted Messages
+
+

MODIFY
crates/rome_service/src/configuration/mod.rs
crates/rome_service/src/configuration/mod.rs
@@ -80,6 +80,15 @@ pub struct FilesConfiguration {
/// The maximum allowed size for source code files in bytes. Files above
/// this limit will be ignored for performance reason. Defaults to 1 MiB
pub max_size: Option<NonZeroU64>,
+
+ /// A list of Unix shell style patterns. Rome tools will ignore files/folders that will
+ /// match these patterns.
+ #[serde(
+ skip_serializing_if = "Option::is_none",
+ deserialize_with = "crate::deserialize_set_of_strings",
+ serialize_with = "crate::serialize_set_of_strings"
+ )]
+ pub ignore: Option<IndexSet<String>>,
}
/// Series of errors that can be thrown while computing the configuration

MODIFY
crates/rome_service/src/settings.rs
crates/rome_service/src/settings.rs
use crate::{
- configuration::FilesConfiguration, Configuration, MatchOptions, Matcher, RomeError, Rules,
+ configuration::FilesConfiguration, Configuration, ConfigurationError, MatchOptions, Matcher,
+ RomeError, Rules,
};
use indexmap::IndexSet;
use rome_diagnostics::v2::Category;
@@ -190,6 +191,9 @@ pub struct LanguageSettings<L: Language> {
pub struct FilesSettings {
/// File size limit in bytes
pub max_size: NonZeroU64,
+
+ /// List of paths/files to matcher
+ pub ignored_files: Matcher,
}
/// Limit the size of files to 1.0 MiB by default
@@ -201,6 +205,11 @@ impl Default for FilesSettings {
fn default() -> Self {
Self {
max_size: DEFAULT_FILE_SIZE_LIMIT,
+ ignored_files: Matcher::new(MatchOptions {
+ case_sensitive: true,
+ require_literal_leading_dot: false,
+ require_literal_separator: false,
+ }),
}
}
}
@@ -209,8 +218,24 @@ impl TryFrom<FilesConfiguration> for FilesSettings {
type Error = RomeError;
fn try_from(config: FilesConfiguration) -> Result<Self, Self::Error> {
+ let mut matcher = Matcher::new(MatchOptions {
+ case_sensitive: true,
+ require_literal_leading_dot: false,
+ require_literal_separator: false,
+ });
+ if let Some(ignore) = config.ignore {
+ for pattern in ignore {
+ matcher.add_pattern(&pattern).map_err(|err| {
+ RomeError::Configuration(ConfigurationError::InvalidIgnorePattern(
+ pattern.to_string(),
+ err.msg.to_string(),
+ ))
+ })?;
+ }
+ }
Ok(Self {
max_size: config.max_size.unwrap_or(DEFAULT_FILE_SIZE_LIMIT),
+ ignored_files: matcher,
})
}
}

MODIFY
crates/rome_service/src/workspace/server.rs
crates/rome_service/src/workspace/server.rs
@@ -206,17 +206,28 @@ impl WorkspaceServer {
/// If the file path matches, than `true` is returned and it should be considered ignored.
fn is_file_ignored(&self, rome_path: &RomePath, feature: &FeatureName) -> bool {
let settings = self.settings();
+ let is_ignored_by_file_config = settings
+ .as_ref()
+ .files
+ .ignored_files
+ .matches_path(rome_path.as_path());
match feature {
- FeatureName::Format => settings
+ FeatureName::Format => {
+ settings
.as_ref()
.formatter
.ignored_files
- .matches_path(rome_path.as_path()),
- FeatureName::Lint => settings
+ .matches_path(rome_path.as_path())
+ || is_ignored_by_file_config
+ }
+ FeatureName::Lint => {
+ settings
.as_ref()
.linter
.ignored_files
- .matches_path(rome_path.as_path()),
+ .matches_path(rome_path.as_path())
+ || is_ignored_by_file_config
+ }
}
}
}

MODIFY
editors/vscode/configuration_schema.json
editors/vscode/configuration_schema.json
"description": "The configuration of the filesystem",
"type": "object",
"properties": {
+ "ignore": {
+ "description": "A list of Unix shell style patterns. Rome tools will ignore files/folders that will match these patterns.",
+ "type": [
+ "array",
+ "null"
+ ],
+ "items": {
+ "type": "string"
+ },
+ "uniqueItems": true
+ },
"maxSize": {
"description": "The maximum allowed size for source code files in bytes. Files above this limit will be ignored for performance reason. Defaults to 1 MiB",
"default": null,

MODIFY
npm/backend-jsonrpc/src/workspace.ts
npm/backend-jsonrpc/src/workspace.ts
@@ -48,6 +48,10 @@ export interface Configuration {
* The configuration of the filesystem
*/
export interface FilesConfiguration {
+ /**
+ * A list of Unix shell style patterns. Rome tools will ignore files/folders that will match these patterns.
+ */
+ ignore?: string[];
/**
* The maximum allowed size for source code files in bytes. Files above this limit will be ignored for performance reason. Defaults to 1 MiB
*/

feat(rome_cli): ignore option of files config (#3564)