Skip to content

Commit c4e2d96

Browse files
committed
feat(linter): Add support for ignores property within config file
1 parent 79bf74a commit c4e2d96

File tree

10 files changed

+83
-24
lines changed

10 files changed

+83
-24
lines changed

apps/oxlint/fixtures/print_config/ban_rules/expect.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -40,5 +40,6 @@
4040
"env": {
4141
"builtin": true
4242
},
43-
"globals": {}
43+
"globals": {},
44+
"ignores": []
4445
}

apps/oxlint/fixtures/print_config/normal/expect.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@
3333
"env": {
3434
"builtin": true
3535
},
36-
"globals": {}
36+
"globals": {},
37+
"ignores": []
3738
}

apps/oxlint/src/lint.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,6 @@ impl Runner for LintRunner {
9292
.copied()
9393
.collect::<Vec<&'static str>>();
9494

95-
let paths =
96-
Walk::new(&paths, &ignore_options).with_extensions(Extensions(extensions)).paths();
97-
98-
let number_of_files = paths.len();
99-
100-
let cwd = std::env::current_dir().unwrap();
101-
10295
let mut oxlintrc = if let Some(config_path) = basic_options.config.as_ref() {
10396
match Oxlintrc::from_file(config_path) {
10497
Ok(config) => config,
@@ -115,6 +108,18 @@ impl Runner for LintRunner {
115108
Oxlintrc::default()
116109
};
117110

111+
let cwd = std::env::current_dir().unwrap();
112+
113+
let paths = Walk::new(
114+
&paths,
115+
&ignore_options,
116+
&oxlintrc.ignores.iter().map(|value| cwd.join(value)).collect::<Vec<_>>(),
117+
)
118+
.with_extensions(Extensions(extensions))
119+
.paths();
120+
121+
let number_of_files = paths.len();
122+
118123
enable_plugins.apply_overrides(&mut oxlintrc.plugins);
119124

120125
let oxlintrc_for_print =

apps/oxlint/src/walk.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,11 @@ impl ignore::ParallelVisitor for WalkCollector {
7070
impl Walk {
7171
/// Will not canonicalize paths.
7272
/// # Panics
73-
pub fn new(paths: &[PathBuf], options: &IgnoreOptions) -> Self {
73+
pub fn new(
74+
paths: &[PathBuf],
75+
options: &IgnoreOptions,
76+
config_ignore_pattern: &[PathBuf],
77+
) -> Self {
7478
assert!(!paths.is_empty(), "At least one path must be provided to Walk::new");
7579

7680
let mut inner = ignore::WalkBuilder::new(
@@ -100,6 +104,15 @@ impl Walk {
100104
let overrides = override_builder.build().unwrap();
101105
inner.overrides(overrides);
102106
}
107+
108+
if !config_ignore_pattern.is_empty() {
109+
let mut override_builder = OverrideBuilder::new(Path::new("/"));
110+
for pattern in config_ignore_pattern {
111+
override_builder.add(pattern.to_str().unwrap()).unwrap();
112+
}
113+
let overrides = override_builder.build().unwrap();
114+
inner.overrides(overrides);
115+
}
103116
}
104117
// Turning off `follow_links` because:
105118
// * following symlinks is a really slow syscall
@@ -155,7 +168,7 @@ mod test {
155168
symlinks: false,
156169
};
157170

158-
let mut paths = Walk::new(&fixtures, &ignore_options)
171+
let mut paths = Walk::new(&fixtures, &ignore_options, &[])
159172
.with_extensions(Extensions(["js", "vue"].to_vec()))
160173
.paths()
161174
.into_iter()

crates/oxc_language_server/src/main.rs

+16-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
mod linter;
22

3-
use std::{fmt::Debug, path::PathBuf, str::FromStr};
3+
use std::{env, fmt::Debug, path::PathBuf, str::FromStr};
44

55
use dashmap::DashMap;
66
use futures::future::join_all;
77
use globset::Glob;
8-
use ignore::gitignore::Gitignore;
8+
use ignore::gitignore::{Gitignore, GitignoreBuilder};
99
use log::{debug, error, info};
1010
use oxc_linter::{FixKind, LinterBuilder, Oxlintrc};
1111
use serde::{Deserialize, Serialize};
@@ -353,16 +353,21 @@ impl Backend {
353353
}
354354
if let Some(config_path) = config_path {
355355
let mut linter = self.server_linter.write().await;
356+
let oxlintrc = Oxlintrc::from_file(&config_path)
357+
.expect("should have initialized linter with new options");
358+
let mut gitignore_builder = GitignoreBuilder::new(config_path.parent().unwrap());
359+
for path in &oxlintrc.ignores {
360+
gitignore_builder
361+
.add_line(None, path)
362+
.expect("Invalid glob in config \"ignores\" property");
363+
}
364+
self.gitignore_glob.lock().await.push(gitignore_builder.build().unwrap());
356365
*linter = ServerLinter::new_with_linter(
357-
LinterBuilder::from_oxlintrc(
358-
true,
359-
Oxlintrc::from_file(&config_path)
360-
.expect("should have initialized linter with new options"),
361-
)
362-
// FIXME: Handle this error more gracefully and report it properly
363-
.expect("failed to build linter from oxlint config")
364-
.with_fix(FixKind::SafeFix)
365-
.build(),
366+
LinterBuilder::from_oxlintrc(true, oxlintrc)
367+
// FIXME: Handle this error more gracefully and report it properly
368+
.expect("failed to build linter from oxlint config")
369+
.with_fix(FixKind::SafeFix)
370+
.build(),
366371
);
367372
}
368373
}

crates/oxc_linter/src/builder.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,15 @@ impl LinterBuilder {
8585
oxlintrc: Oxlintrc,
8686
) -> Result<Self, LinterBuilderError> {
8787
// TODO: monorepo config merging, plugin-based extends, etc.
88-
let Oxlintrc { plugins, settings, env, globals, categories, rules: mut oxlintrc_rules } =
89-
oxlintrc;
88+
let Oxlintrc {
89+
plugins,
90+
settings,
91+
env,
92+
globals,
93+
categories,
94+
rules: mut oxlintrc_rules,
95+
ignores: _,
96+
} = oxlintrc;
9097

9198
let config = LintConfig { plugins, settings, env, globals };
9299
let options = LintOptions::default();

crates/oxc_linter/src/config/oxlintrc.rs

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ pub struct Oxlintrc {
7474
pub env: OxlintEnv,
7575
/// Enabled or disabled specific global variables.
7676
pub globals: OxlintGlobals,
77+
/// Globs to ignore during linting.
78+
pub ignores: Vec<String>,
7779
}
7880

7981
impl Oxlintrc {

crates/oxc_linter/src/snapshots/schema_json.snap

+8
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ expression: json
3636
}
3737
]
3838
},
39+
"ignores": {
40+
"description": "Globs to ignore during linting.",
41+
"default": [],
42+
"type": "array",
43+
"items": {
44+
"type": "string"
45+
}
46+
},
3947
"plugins": {
4048
"default": [
4149
"react",

npm/oxlint/configuration_schema.json

+8
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@
3232
}
3333
]
3434
},
35+
"ignores": {
36+
"description": "Globs to ignore during linting.",
37+
"default": [],
38+
"type": "array",
39+
"items": {
40+
"type": "string"
41+
}
42+
},
3543
"plugins": {
3644
"default": [
3745
"react",

tasks/website/src/linter/snapshots/schema_markdown.snap

+9
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,15 @@ Globals can be disabled by setting their value to `"off"`. For example, in an en
148148
You may also use `"readable"` or `false` to represent `"readonly"`, and `"writeable"` or `true` to represent `"writable"`.
149149

150150

151+
## ignores
152+
153+
type: `string[]`
154+
155+
default: `[]`
156+
157+
Globs to ignore during linting.
158+
159+
151160
## plugins
152161

153162
type: `string[]`

0 commit comments

Comments
 (0)