mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(linter): move OxlintConfig to Oxlintrc (#5707)
This commit is contained in:
parent
b5ac5a6bf0
commit
a438743191
8 changed files with 201 additions and 199 deletions
|
|
@ -1,70 +1,15 @@
|
||||||
mod env;
|
mod env;
|
||||||
mod globals;
|
mod globals;
|
||||||
|
mod oxlintrc;
|
||||||
mod rules;
|
mod rules;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
|
||||||
use std::path::Path;
|
|
||||||
|
|
||||||
use oxc_diagnostics::OxcDiagnostic;
|
|
||||||
use rustc_hash::FxHashSet;
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
env::OxlintEnv,
|
env::OxlintEnv,
|
||||||
globals::OxlintGlobals,
|
globals::OxlintGlobals,
|
||||||
rules::OxlintRules,
|
oxlintrc::Oxlintrc,
|
||||||
settings::{jsdoc::JSDocPluginSettings, OxlintSettings},
|
settings::{jsdoc::JSDocPluginSettings, OxlintSettings},
|
||||||
};
|
};
|
||||||
use crate::{
|
|
||||||
rules::RuleEnum,
|
|
||||||
utils::{is_jest_rule_adapted_to_vitest, read_to_string},
|
|
||||||
AllowWarnDeny, RuleWithSeverity,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Oxlint Configuration File
|
|
||||||
///
|
|
||||||
/// This configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).
|
|
||||||
///
|
|
||||||
/// Usage: `oxlint -c oxlintrc.json --import-plugin`
|
|
||||||
///
|
|
||||||
/// ::: danger NOTE
|
|
||||||
///
|
|
||||||
/// Only the `.json` format is supported. You can use comments in configuration files.
|
|
||||||
///
|
|
||||||
/// :::
|
|
||||||
///
|
|
||||||
/// Example
|
|
||||||
///
|
|
||||||
/// `.oxlintrc.json`
|
|
||||||
///
|
|
||||||
/// ```json
|
|
||||||
/// {
|
|
||||||
/// "env": {
|
|
||||||
/// "browser": true
|
|
||||||
/// },
|
|
||||||
/// "globals": {
|
|
||||||
/// "foo": "readonly"
|
|
||||||
/// },
|
|
||||||
/// "settings": {
|
|
||||||
/// },
|
|
||||||
/// "rules": {
|
|
||||||
/// "eqeqeq": "warn",
|
|
||||||
/// "import/no-cycle": "error"
|
|
||||||
/// }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize, JsonSchema)]
|
|
||||||
#[serde(default)]
|
|
||||||
pub struct OxlintConfig {
|
|
||||||
/// See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html).
|
|
||||||
pub rules: OxlintRules,
|
|
||||||
pub settings: OxlintSettings,
|
|
||||||
/// Environments enable and disable collections of global variables.
|
|
||||||
pub env: OxlintEnv,
|
|
||||||
/// Enabled or disabled specific global variables.
|
|
||||||
pub globals: OxlintGlobals,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
pub(crate) struct LintConfig {
|
pub(crate) struct LintConfig {
|
||||||
|
|
@ -75,134 +20,12 @@ pub(crate) struct LintConfig {
|
||||||
pub(crate) globals: OxlintGlobals,
|
pub(crate) globals: OxlintGlobals,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<OxlintConfig> for LintConfig {
|
impl From<Oxlintrc> for LintConfig {
|
||||||
fn from(config: OxlintConfig) -> Self {
|
fn from(config: Oxlintrc) -> Self {
|
||||||
Self { settings: config.settings, env: config.env, globals: config.globals }
|
Self { settings: config.settings, env: config.env, globals: config.globals }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OxlintConfig {
|
|
||||||
/// # Errors
|
|
||||||
///
|
|
||||||
/// * Parse Failure
|
|
||||||
pub fn from_file(path: &Path) -> Result<Self, OxcDiagnostic> {
|
|
||||||
let mut string = read_to_string(path).map_err(|e| {
|
|
||||||
OxcDiagnostic::error(format!("Failed to parse config {path:?} with error {e:?}"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
// jsonc support
|
|
||||||
json_strip_comments::strip(&mut string).map_err(|err| {
|
|
||||||
OxcDiagnostic::error(format!("Failed to parse jsonc file {path:?}: {err:?}"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let json = serde_json::from_str::<serde_json::Value>(&string).map_err(|err| {
|
|
||||||
let guess = mime_guess::from_path(path);
|
|
||||||
let err = match guess.first() {
|
|
||||||
// syntax error
|
|
||||||
Some(mime) if mime.subtype() == "json" => err.to_string(),
|
|
||||||
Some(_) => "Only json configuration is supported".to_string(),
|
|
||||||
None => {
|
|
||||||
format!(
|
|
||||||
"{err}, if the configuration is not a json file, please use json instead."
|
|
||||||
)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
OxcDiagnostic::error(format!("Failed to parse eslint config {path:?}.\n{err}"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let config = Self::deserialize(&json).map_err(|err| {
|
|
||||||
OxcDiagnostic::error(format!("Failed to parse config with error {err:?}"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(config)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(clippy::option_if_let_else)]
|
|
||||||
pub fn override_rules(
|
|
||||||
&self,
|
|
||||||
rules_for_override: &mut FxHashSet<RuleWithSeverity>,
|
|
||||||
all_rules: &[RuleEnum],
|
|
||||||
) {
|
|
||||||
use itertools::Itertools;
|
|
||||||
let mut rules_to_replace: Vec<RuleWithSeverity> = vec![];
|
|
||||||
let mut rules_to_remove: Vec<RuleWithSeverity> = vec![];
|
|
||||||
|
|
||||||
// Rules can have the same name but different plugin names
|
|
||||||
let lookup = self.rules.iter().into_group_map_by(|r| r.rule_name.as_str());
|
|
||||||
|
|
||||||
for (name, rule_configs) in &lookup {
|
|
||||||
match rule_configs.len() {
|
|
||||||
0 => unreachable!(),
|
|
||||||
1 => {
|
|
||||||
let rule_config = &rule_configs[0];
|
|
||||||
let (rule_name, plugin_name) = transform_rule_and_plugin_name(
|
|
||||||
&rule_config.rule_name,
|
|
||||||
&rule_config.plugin_name,
|
|
||||||
);
|
|
||||||
let severity = rule_config.severity;
|
|
||||||
match severity {
|
|
||||||
AllowWarnDeny::Warn | AllowWarnDeny::Deny => {
|
|
||||||
if let Some(rule) = all_rules
|
|
||||||
.iter()
|
|
||||||
.find(|r| r.name() == rule_name && r.plugin_name() == plugin_name)
|
|
||||||
{
|
|
||||||
let config = rule_config.config.clone().unwrap_or_default();
|
|
||||||
let rule = rule.read_json(config);
|
|
||||||
rules_to_replace.push(RuleWithSeverity::new(rule, severity));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
AllowWarnDeny::Allow => {
|
|
||||||
if let Some(rule) = rules_for_override
|
|
||||||
.iter()
|
|
||||||
.find(|r| r.name() == rule_name && r.plugin_name() == plugin_name)
|
|
||||||
{
|
|
||||||
let rule = rule.clone();
|
|
||||||
rules_to_remove.push(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// For overlapping rule names, use the "error" one
|
|
||||||
// "no-loss-of-precision": "off",
|
|
||||||
// "@typescript-eslint/no-loss-of-precision": "error"
|
|
||||||
if let Some(rule_config) =
|
|
||||||
rule_configs.iter().find(|r| r.severity.is_warn_deny())
|
|
||||||
{
|
|
||||||
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
|
|
||||||
let config = rule_config.config.clone().unwrap_or_default();
|
|
||||||
rules_to_replace
|
|
||||||
.push(RuleWithSeverity::new(rule.read_json(config), rule.severity));
|
|
||||||
}
|
|
||||||
} else if rule_configs.iter().all(|r| r.severity.is_allow()) {
|
|
||||||
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
|
|
||||||
rules_to_remove.push(rule.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for rule in rules_to_remove {
|
|
||||||
rules_for_override.remove(&rule);
|
|
||||||
}
|
|
||||||
for rule in rules_to_replace {
|
|
||||||
rules_for_override.replace(rule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transform_rule_and_plugin_name<'a>(
|
|
||||||
rule_name: &'a str,
|
|
||||||
plugin_name: &'a str,
|
|
||||||
) -> (&'a str, &'a str) {
|
|
||||||
if plugin_name == "vitest" && is_jest_rule_adapted_to_vitest(rule_name) {
|
|
||||||
return (rule_name, "jest");
|
|
||||||
}
|
|
||||||
|
|
||||||
(rule_name, plugin_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
@ -211,19 +34,19 @@ mod test {
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
use super::OxlintConfig;
|
use super::Oxlintrc;
|
||||||
use crate::rules::RULES;
|
use crate::rules::RULES;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_from_file() {
|
fn test_from_file() {
|
||||||
let fixture_path = env::current_dir().unwrap().join("fixtures/eslint_config.json");
|
let fixture_path = env::current_dir().unwrap().join("fixtures/eslint_config.json");
|
||||||
let config = OxlintConfig::from_file(&fixture_path).unwrap();
|
let config = Oxlintrc::from_file(&fixture_path).unwrap();
|
||||||
assert!(!config.rules.is_empty());
|
assert!(!config.rules.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_deserialize() {
|
fn test_deserialize() {
|
||||||
let config = OxlintConfig::deserialize(&serde_json::json!({
|
let config = Oxlintrc::deserialize(&serde_json::json!({
|
||||||
"rules": {
|
"rules": {
|
||||||
"no-console": "off",
|
"no-console": "off",
|
||||||
"no-debugger": 2,
|
"no-debugger": 2,
|
||||||
|
|
@ -253,7 +76,7 @@ mod test {
|
||||||
}));
|
}));
|
||||||
assert!(config.is_ok());
|
assert!(config.is_ok());
|
||||||
|
|
||||||
let OxlintConfig { rules, settings, env, globals } = config.unwrap();
|
let Oxlintrc { rules, settings, env, globals } = config.unwrap();
|
||||||
assert!(!rules.is_empty());
|
assert!(!rules.is_empty());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
settings.jsx_a11y.polymorphic_prop_name.as_ref().map(CompactStr::as_str),
|
settings.jsx_a11y.polymorphic_prop_name.as_ref().map(CompactStr::as_str),
|
||||||
|
|
@ -267,7 +90,7 @@ mod test {
|
||||||
fn test_vitest_rule_replace() {
|
fn test_vitest_rule_replace() {
|
||||||
let fixture_path: std::path::PathBuf =
|
let fixture_path: std::path::PathBuf =
|
||||||
env::current_dir().unwrap().join("fixtures/eslint_config_vitest_replace.json");
|
env::current_dir().unwrap().join("fixtures/eslint_config_vitest_replace.json");
|
||||||
let config = OxlintConfig::from_file(&fixture_path).unwrap();
|
let config = Oxlintrc::from_file(&fixture_path).unwrap();
|
||||||
let mut set = FxHashSet::default();
|
let mut set = FxHashSet::default();
|
||||||
config.override_rules(&mut set, &RULES);
|
config.override_rules(&mut set, &RULES);
|
||||||
|
|
||||||
|
|
|
||||||
180
crates/oxc_linter/src/config/oxlintrc.rs
Normal file
180
crates/oxc_linter/src/config/oxlintrc.rs
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use oxc_diagnostics::OxcDiagnostic;
|
||||||
|
use rustc_hash::FxHashSet;
|
||||||
|
use schemars::JsonSchema;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use super::{env::OxlintEnv, globals::OxlintGlobals, rules::OxlintRules, settings::OxlintSettings};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
rules::RuleEnum,
|
||||||
|
utils::{is_jest_rule_adapted_to_vitest, read_to_string},
|
||||||
|
AllowWarnDeny, RuleWithSeverity,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Oxlint Configuration File
|
||||||
|
///
|
||||||
|
/// This configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).
|
||||||
|
///
|
||||||
|
/// Usage: `oxlint -c oxlintrc.json --import-plugin`
|
||||||
|
///
|
||||||
|
/// ::: danger NOTE
|
||||||
|
///
|
||||||
|
/// Only the `.json` format is supported. You can use comments in configuration files.
|
||||||
|
///
|
||||||
|
/// :::
|
||||||
|
///
|
||||||
|
/// Example
|
||||||
|
///
|
||||||
|
/// `.oxlintrc.json`
|
||||||
|
///
|
||||||
|
/// ```json
|
||||||
|
/// {
|
||||||
|
/// "env": {
|
||||||
|
/// "browser": true
|
||||||
|
/// },
|
||||||
|
/// "globals": {
|
||||||
|
/// "foo": "readonly"
|
||||||
|
/// },
|
||||||
|
/// "settings": {
|
||||||
|
/// },
|
||||||
|
/// "rules": {
|
||||||
|
/// "eqeqeq": "warn",
|
||||||
|
/// "import/no-cycle": "error"
|
||||||
|
/// }
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
#[derive(Debug, Default, Deserialize, Serialize, JsonSchema)]
|
||||||
|
#[serde(default)]
|
||||||
|
pub struct Oxlintrc {
|
||||||
|
/// See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html).
|
||||||
|
pub rules: OxlintRules,
|
||||||
|
pub settings: OxlintSettings,
|
||||||
|
/// Environments enable and disable collections of global variables.
|
||||||
|
pub env: OxlintEnv,
|
||||||
|
/// Enabled or disabled specific global variables.
|
||||||
|
pub globals: OxlintGlobals,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Oxlintrc {
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// * Parse Failure
|
||||||
|
pub fn from_file(path: &Path) -> Result<Self, OxcDiagnostic> {
|
||||||
|
let mut string = read_to_string(path).map_err(|e| {
|
||||||
|
OxcDiagnostic::error(format!("Failed to parse config {path:?} with error {e:?}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// jsonc support
|
||||||
|
json_strip_comments::strip(&mut string).map_err(|err| {
|
||||||
|
OxcDiagnostic::error(format!("Failed to parse jsonc file {path:?}: {err:?}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let json = serde_json::from_str::<serde_json::Value>(&string).map_err(|err| {
|
||||||
|
let guess = mime_guess::from_path(path);
|
||||||
|
let err = match guess.first() {
|
||||||
|
// syntax error
|
||||||
|
Some(mime) if mime.subtype() == "json" => err.to_string(),
|
||||||
|
Some(_) => "Only json configuration is supported".to_string(),
|
||||||
|
None => {
|
||||||
|
format!(
|
||||||
|
"{err}, if the configuration is not a json file, please use json instead."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
OxcDiagnostic::error(format!("Failed to parse eslint config {path:?}.\n{err}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let config = Self::deserialize(&json).map_err(|err| {
|
||||||
|
OxcDiagnostic::error(format!("Failed to parse config with error {err:?}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::option_if_let_else)]
|
||||||
|
pub fn override_rules(
|
||||||
|
&self,
|
||||||
|
rules_for_override: &mut FxHashSet<RuleWithSeverity>,
|
||||||
|
all_rules: &[RuleEnum],
|
||||||
|
) {
|
||||||
|
use itertools::Itertools;
|
||||||
|
let mut rules_to_replace: Vec<RuleWithSeverity> = vec![];
|
||||||
|
let mut rules_to_remove: Vec<RuleWithSeverity> = vec![];
|
||||||
|
|
||||||
|
// Rules can have the same name but different plugin names
|
||||||
|
let lookup = self.rules.iter().into_group_map_by(|r| r.rule_name.as_str());
|
||||||
|
|
||||||
|
for (name, rule_configs) in &lookup {
|
||||||
|
match rule_configs.len() {
|
||||||
|
0 => unreachable!(),
|
||||||
|
1 => {
|
||||||
|
let rule_config = &rule_configs[0];
|
||||||
|
let (rule_name, plugin_name) = transform_rule_and_plugin_name(
|
||||||
|
&rule_config.rule_name,
|
||||||
|
&rule_config.plugin_name,
|
||||||
|
);
|
||||||
|
let severity = rule_config.severity;
|
||||||
|
match severity {
|
||||||
|
AllowWarnDeny::Warn | AllowWarnDeny::Deny => {
|
||||||
|
if let Some(rule) = all_rules
|
||||||
|
.iter()
|
||||||
|
.find(|r| r.name() == rule_name && r.plugin_name() == plugin_name)
|
||||||
|
{
|
||||||
|
let config = rule_config.config.clone().unwrap_or_default();
|
||||||
|
let rule = rule.read_json(config);
|
||||||
|
rules_to_replace.push(RuleWithSeverity::new(rule, severity));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AllowWarnDeny::Allow => {
|
||||||
|
if let Some(rule) = rules_for_override
|
||||||
|
.iter()
|
||||||
|
.find(|r| r.name() == rule_name && r.plugin_name() == plugin_name)
|
||||||
|
{
|
||||||
|
let rule = rule.clone();
|
||||||
|
rules_to_remove.push(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
// For overlapping rule names, use the "error" one
|
||||||
|
// "no-loss-of-precision": "off",
|
||||||
|
// "@typescript-eslint/no-loss-of-precision": "error"
|
||||||
|
if let Some(rule_config) =
|
||||||
|
rule_configs.iter().find(|r| r.severity.is_warn_deny())
|
||||||
|
{
|
||||||
|
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
|
||||||
|
let config = rule_config.config.clone().unwrap_or_default();
|
||||||
|
rules_to_replace
|
||||||
|
.push(RuleWithSeverity::new(rule.read_json(config), rule.severity));
|
||||||
|
}
|
||||||
|
} else if rule_configs.iter().all(|r| r.severity.is_allow()) {
|
||||||
|
if let Some(rule) = rules_for_override.iter().find(|r| r.name() == *name) {
|
||||||
|
rules_to_remove.push(rule.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for rule in rules_to_remove {
|
||||||
|
rules_for_override.remove(&rule);
|
||||||
|
}
|
||||||
|
for rule in rules_to_replace {
|
||||||
|
rules_for_override.replace(rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transform_rule_and_plugin_name<'a>(
|
||||||
|
rule_name: &'a str,
|
||||||
|
plugin_name: &'a str,
|
||||||
|
) -> (&'a str, &'a str) {
|
||||||
|
if plugin_name == "vitest" && is_jest_rule_adapted_to_vitest(rule_name) {
|
||||||
|
return (rule_name, "jest");
|
||||||
|
}
|
||||||
|
|
||||||
|
(rule_name, plugin_name)
|
||||||
|
}
|
||||||
|
|
@ -29,7 +29,7 @@ use oxc_diagnostics::Error;
|
||||||
use oxc_semantic::{AstNode, Semantic};
|
use oxc_semantic::{AstNode, Semantic};
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
config::OxlintConfig,
|
config::Oxlintrc,
|
||||||
context::LintContext,
|
context::LintContext,
|
||||||
fixer::FixKind,
|
fixer::FixKind,
|
||||||
frameworks::FrameworkFlags,
|
frameworks::FrameworkFlags,
|
||||||
|
|
@ -158,7 +158,7 @@ impl Linter {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use super::{Linter, OxlintConfig};
|
use super::{Linter, Oxlintrc};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn print_rules() {
|
fn print_rules() {
|
||||||
|
|
@ -173,7 +173,7 @@ mod test {
|
||||||
|
|
||||||
use project_root::get_project_root;
|
use project_root::get_project_root;
|
||||||
let path = get_project_root().unwrap().join("npm/oxlint/configuration_schema.json");
|
let path = get_project_root().unwrap().join("npm/oxlint/configuration_schema.json");
|
||||||
let schema = schemars::schema_for!(OxlintConfig);
|
let schema = schemars::schema_for!(Oxlintrc);
|
||||||
let json = serde_json::to_string_pretty(&schema).unwrap();
|
let json = serde_json::to_string_pretty(&schema).unwrap();
|
||||||
let existing_json = fs::read_to_string(&path).unwrap_or_default();
|
let existing_json = fs::read_to_string(&path).unwrap_or_default();
|
||||||
if existing_json.trim() != json.trim() {
|
if existing_json.trim() != json.trim() {
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ pub use filter::{InvalidFilterKind, LintFilter};
|
||||||
pub use plugins::{LintPluginOptions, LintPlugins};
|
pub use plugins::{LintPluginOptions, LintPlugins};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{LintConfig, OxlintConfig},
|
config::{LintConfig, Oxlintrc},
|
||||||
fixer::FixKind,
|
fixer::FixKind,
|
||||||
rules::RULES,
|
rules::RULES,
|
||||||
utils::is_jest_rule_adapted_to_vitest,
|
utils::is_jest_rule_adapted_to_vitest,
|
||||||
|
|
@ -188,8 +188,7 @@ impl OxlintOptions {
|
||||||
pub(crate) fn derive_rules_and_config(
|
pub(crate) fn derive_rules_and_config(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<(Vec<RuleWithSeverity>, LintConfig), Error> {
|
) -> Result<(Vec<RuleWithSeverity>, LintConfig), Error> {
|
||||||
let config =
|
let config = self.config_path.as_ref().map(|path| Oxlintrc::from_file(path)).transpose()?;
|
||||||
self.config_path.as_ref().map(|path| OxlintConfig::from_file(path)).transpose()?;
|
|
||||||
|
|
||||||
let mut rules: FxHashSet<RuleWithSeverity> = FxHashSet::default();
|
let mut rules: FxHashSet<RuleWithSeverity> = FxHashSet::default();
|
||||||
let all_rules = self.get_filtered_rules();
|
let all_rules = self.get_filtered_rules();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ expression: json
|
||||||
---
|
---
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"title": "OxlintConfig",
|
"title": "Oxlintrc",
|
||||||
"description": "Oxlint Configuration File\n\nThis configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).\n\nUsage: `oxlint -c oxlintrc.json --import-plugin`\n\n::: danger NOTE\n\nOnly the `.json` format is supported. You can use comments in configuration files.\n\n:::\n\nExample\n\n`.oxlintrc.json`\n\n```json { \"env\": { \"browser\": true }, \"globals\": { \"foo\": \"readonly\" }, \"settings\": { }, \"rules\": { \"eqeqeq\": \"warn\", \"import/no-cycle\": \"error\" } } ```",
|
"description": "Oxlint Configuration File\n\nThis configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).\n\nUsage: `oxlint -c oxlintrc.json --import-plugin`\n\n::: danger NOTE\n\nOnly the `.json` format is supported. You can use comments in configuration files.\n\n:::\n\nExample\n\n`.oxlintrc.json`\n\n```json { \"env\": { \"browser\": true }, \"globals\": { \"foo\": \"readonly\" }, \"settings\": { }, \"rules\": { \"eqeqeq\": \"warn\", \"import/no-cycle\": \"error\" } } ```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ use serde_json::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
fixer::FixKind, options::LintPluginOptions, rules::RULES, AllowWarnDeny, Fixer, LintService,
|
fixer::FixKind, options::LintPluginOptions, rules::RULES, AllowWarnDeny, Fixer, LintService,
|
||||||
LintServiceOptions, Linter, OxlintConfig, OxlintOptions, RuleEnum, RuleWithSeverity,
|
LintServiceOptions, Linter, OxlintOptions, Oxlintrc, RuleEnum, RuleWithSeverity,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Eq, PartialEq)]
|
#[derive(Eq, PartialEq)]
|
||||||
|
|
@ -362,7 +362,7 @@ impl Tester {
|
||||||
.with_node_plugin(self.plugins.node);
|
.with_node_plugin(self.plugins.node);
|
||||||
let eslint_config = eslint_config
|
let eslint_config = eslint_config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or_else(OxlintConfig::default, |v| OxlintConfig::deserialize(v).unwrap());
|
.map_or_else(Oxlintrc::default, |v| Oxlintrc::deserialize(v).unwrap());
|
||||||
let linter = Linter::from_options(options)
|
let linter = Linter::from_options(options)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.with_rules(vec![RuleWithSeverity::new(rule, AllowWarnDeny::Warn)])
|
.with_rules(vec![RuleWithSeverity::new(rule, AllowWarnDeny::Warn)])
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||||
"title": "OxlintConfig",
|
"title": "Oxlintrc",
|
||||||
"description": "Oxlint Configuration File\n\nThis configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).\n\nUsage: `oxlint -c oxlintrc.json --import-plugin`\n\n::: danger NOTE\n\nOnly the `.json` format is supported. You can use comments in configuration files.\n\n:::\n\nExample\n\n`.oxlintrc.json`\n\n```json { \"env\": { \"browser\": true }, \"globals\": { \"foo\": \"readonly\" }, \"settings\": { }, \"rules\": { \"eqeqeq\": \"warn\", \"import/no-cycle\": \"error\" } } ```",
|
"description": "Oxlint Configuration File\n\nThis configuration is aligned with ESLint v8's configuration schema (`eslintrc.json`).\n\nUsage: `oxlint -c oxlintrc.json --import-plugin`\n\n::: danger NOTE\n\nOnly the `.json` format is supported. You can use comments in configuration files.\n\n:::\n\nExample\n\n`.oxlintrc.json`\n\n```json { \"env\": { \"browser\": true }, \"globals\": { \"foo\": \"readonly\" }, \"settings\": { }, \"rules\": { \"eqeqeq\": \"warn\", \"import/no-cycle\": \"error\" } } ```",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use handlebars::Handlebars;
|
use handlebars::Handlebars;
|
||||||
use oxc_linter::OxlintConfig;
|
use oxc_linter::Oxlintrc;
|
||||||
use schemars::{
|
use schemars::{
|
||||||
schema::{RootSchema, Schema, SchemaObject, SingleOrVec, SubschemaValidation},
|
schema::{RootSchema, Schema, SchemaObject, SingleOrVec, SubschemaValidation},
|
||||||
schema_for,
|
schema_for,
|
||||||
|
|
@ -11,7 +11,7 @@ pub fn print_schema_json() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_schema_json() -> String {
|
fn generate_schema_json() -> String {
|
||||||
let schema = schema_for!(OxlintConfig);
|
let schema = schema_for!(Oxlintrc);
|
||||||
serde_json::to_string_pretty(&schema).unwrap()
|
serde_json::to_string_pretty(&schema).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ pub fn print_schema_markdown() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_schema_markdown() -> String {
|
fn generate_schema_markdown() -> String {
|
||||||
let root_schema = schema_for!(OxlintConfig);
|
let root_schema = schema_for!(Oxlintrc);
|
||||||
Renderer::new(root_schema).render()
|
Renderer::new(root_schema).render()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue