diff --git a/Cargo.lock b/Cargo.lock index 345d50282..1971fd276 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -924,6 +924,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json-strip-comments" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a138532317bbcfd1bb99baab0fd89f4391b4975b3c0a4e1ccb074912e940ee1" + [[package]] name = "language-tags" version = "0.3.2" @@ -1500,6 +1506,7 @@ dependencies = [ "dashmap", "insta", "itertools 0.12.0", + "json-strip-comments", "language-tags", "lazy_static", "memchr", diff --git a/crates/oxc_linter/Cargo.toml b/crates/oxc_linter/Cargo.toml index 9b0a31ba9..5c2c61a2f 100644 --- a/crates/oxc_linter/Cargo.toml +++ b/crates/oxc_linter/Cargo.toml @@ -49,6 +49,7 @@ url = { workspace = true } rust-lapper = "1.1.0" once_cell = "1.19.0" memchr = "2.7.1" +json-strip-comments = "1.0.1" [dev-dependencies] miette = { workspace = true } diff --git a/crates/oxc_linter/fixtures/eslint_config.json b/crates/oxc_linter/fixtures/eslint_config.json index d0a50c010..88b77fd90 100644 --- a/crates/oxc_linter/fixtures/eslint_config.json +++ b/crates/oxc_linter/fixtures/eslint_config.json @@ -1,5 +1,6 @@ { "rules": { + // requires jsonc support "no-console": "off", "no-bitwise": [ "error", @@ -17,6 +18,6 @@ } ], "@typescript-eslint/ban-types": "error", - "jsx-a11y/alt-text": "warn" + "jsx-a11y/alt-text": "warn", } } diff --git a/crates/oxc_linter/src/config/errors.rs b/crates/oxc_linter/src/config/errors.rs index cc3100240..248bc6b93 100644 --- a/crates/oxc_linter/src/config/errors.rs +++ b/crates/oxc_linter/src/config/errors.rs @@ -39,3 +39,8 @@ pub struct FailedToParseAllowWarnDenyFromNumberError(pub String); #[error(r#"Failed to parse rule severity, expected a string or a number, but got {0:?}"#)] #[diagnostic()] pub struct FailedToParseAllowWarnDenyFromJsonValueError(pub String); + +#[derive(Debug, Error, Diagnostic)] +#[error("Failed to parse jsonc file {0:?}")] +#[diagnostic()] +pub struct FailedToParseJsonc(pub PathBuf); diff --git a/crates/oxc_linter/src/config/mod.rs b/crates/oxc_linter/src/config/mod.rs index 69cf700e3..e44ad36ea 100644 --- a/crates/oxc_linter/src/config/mod.rs +++ b/crates/oxc_linter/src/config/mod.rs @@ -8,7 +8,8 @@ use serde_json::Value; use crate::{rules::RuleEnum, settings::Nextjs, AllowWarnDeny, JsxA11y, LintSettings}; use self::errors::{ - FailedToParseConfigError, FailedToParseConfigJsonError, FailedToParseRuleValueError, + FailedToParseConfigError, FailedToParseConfigJsonError, FailedToParseJsonc, + FailedToParseRuleValueError, }; pub struct ESLintConfig { @@ -37,18 +38,15 @@ impl ESLintConfig { } fn read_json(path: &Path) -> Result { - let file = match std::fs::read_to_string(path) { - Ok(file) => file, - Err(e) => { - return Err(FailedToParseConfigError(vec![Error::new(FailedToOpenFileError( - path.to_path_buf(), - e, - ))]) - .into()); - } - }; + let mut string = std::fs::read_to_string(path).map_err(|e| { + FailedToParseConfigError(vec![Error::new(FailedToOpenFileError(path.to_path_buf(), e))]) + })?; - serde_json::from_str::(&file).map_err(|err| { + // jsonc support + json_strip_comments::strip(&mut string) + .map_err(|_| FailedToParseJsonc(path.to_path_buf()))?; + + serde_json::from_str::(&string).map_err(|err| { let guess = mime_guess::from_path(path); let err = match guess.first() { // syntax error @@ -256,15 +254,13 @@ fn resolve_rule_value(value: &serde_json::Value) -> Result<(AllowWarnDeny, Optio #[cfg(test)] mod test { - use super::parse_rules; + use super::ESLintConfig; use std::env; #[test] fn test_parse_rules() { let fixture_path = env::current_dir().unwrap().join("fixtures/eslint_config.json"); - let input = std::fs::read_to_string(fixture_path).unwrap(); - let file = serde_json::from_str::(&input).unwrap(); - let rules = parse_rules(&file).unwrap(); - insta::assert_debug_snapshot!(rules); + let config = ESLintConfig::new(&fixture_path).unwrap(); + assert!(!config.rules.is_empty()); } } diff --git a/crates/oxc_linter/src/config/snapshots/oxc_linter__config__test__parse_rules.snap b/crates/oxc_linter/src/config/snapshots/oxc_linter__config__test__parse_rules.snap deleted file mode 100644 index b8e3fd4b8..000000000 --- a/crates/oxc_linter/src/config/snapshots/oxc_linter__config__test__parse_rules.snap +++ /dev/null @@ -1,51 +0,0 @@ ---- -source: crates/oxc_linter/src/config/mod.rs -expression: rules ---- -[ - ESLintRuleConfig { - plugin_name: "eslint", - rule_name: "no-console", - severity: Allow, - config: None, - }, - ESLintRuleConfig { - plugin_name: "eslint", - rule_name: "no-bitwise", - severity: Deny, - config: Some( - Array [ - Object { - "allow": Array [ - String("~"), - ], - }, - ], - ), - }, - ESLintRuleConfig { - plugin_name: "eslint", - rule_name: "eqeqeq", - severity: Deny, - config: Some( - Array [ - String("always"), - Object { - "null": String("ignore"), - }, - ], - ), - }, - ESLintRuleConfig { - plugin_name: "typescript", - rule_name: "ban-types", - severity: Deny, - config: None, - }, - ESLintRuleConfig { - plugin_name: "jsx_a11y", - rule_name: "alt-text", - severity: Warn, - config: None, - }, -]