|
1 | | -use std::{env, io::BufWriter, path::PathBuf, time::Instant}; |
| 1 | +use std::{ |
| 2 | + env, |
| 3 | + io::BufWriter, |
| 4 | + path::{Path, PathBuf}, |
| 5 | + time::Instant, |
| 6 | +}; |
2 | 7 |
|
3 | 8 | use ignore::gitignore::Gitignore; |
4 | 9 | use oxc_diagnostics::{DiagnosticService, GraphicalReportHandler}; |
@@ -102,21 +107,13 @@ impl Runner for LintRunner { |
102 | 107 |
|
103 | 108 | let number_of_files = paths.len(); |
104 | 109 |
|
105 | | - let mut oxlintrc = if let Some(config_path) = basic_options.config.as_ref() { |
106 | | - match Oxlintrc::from_file(config_path) { |
107 | | - Ok(config) => config, |
108 | | - Err(diagnostic) => { |
109 | | - let handler = GraphicalReportHandler::new(); |
110 | | - let mut err = String::new(); |
111 | | - handler.render_report(&mut err, &diagnostic).unwrap(); |
112 | | - return CliRunResult::InvalidOptions { |
113 | | - message: format!("Failed to parse configuration file.\n{err}"), |
114 | | - }; |
115 | | - } |
116 | | - } |
117 | | - } else { |
118 | | - Oxlintrc::default() |
119 | | - }; |
| 110 | + let config_search_result = Self::find_oxlint_config(&self.cwd, &basic_options.config); |
| 111 | + |
| 112 | + if let Err(err) = config_search_result { |
| 113 | + return err; |
| 114 | + } |
| 115 | + |
| 116 | + let mut oxlintrc = config_search_result.unwrap(); |
120 | 117 |
|
121 | 118 | enable_plugins.apply_overrides(&mut oxlintrc.plugins); |
122 | 119 |
|
@@ -179,6 +176,8 @@ impl Runner for LintRunner { |
179 | 176 | } |
180 | 177 |
|
181 | 178 | impl LintRunner { |
| 179 | + const DEFAULT_OXLINTRC: &'static str = ".oxlintrc.json"; |
| 180 | + |
182 | 181 | #[must_use] |
183 | 182 | pub fn with_cwd(mut self, cwd: PathBuf) -> Self { |
184 | 183 | self.cwd = cwd; |
@@ -241,6 +240,34 @@ impl LintRunner { |
241 | 240 |
|
242 | 241 | Ok(filters) |
243 | 242 | } |
| 243 | + |
| 244 | + // finds the oxlint config |
| 245 | + // when config is provided, but not found, an CliRunResult is returned, else the oxlintrc config file is returned |
| 246 | + // when no config is provided, it will search for the default file names in the current working directory |
| 247 | + // when no file is found, the default configuration is returned |
| 248 | + fn find_oxlint_config(cwd: &Path, config: &Option<PathBuf>) -> Result<Oxlintrc, CliRunResult> { |
| 249 | + if let Some(config_path) = config { |
| 250 | + return match Oxlintrc::from_file(config_path) { |
| 251 | + Ok(config) => Ok(config), |
| 252 | + Err(diagnostic) => { |
| 253 | + let handler = GraphicalReportHandler::new(); |
| 254 | + let mut err = String::new(); |
| 255 | + handler.render_report(&mut err, &diagnostic).unwrap(); |
| 256 | + return Err(CliRunResult::InvalidOptions { |
| 257 | + message: format!("Failed to parse configuration file.\n{err}"), |
| 258 | + }); |
| 259 | + } |
| 260 | + }; |
| 261 | + } |
| 262 | + |
| 263 | + // no config argument is provided, |
| 264 | + // auto detect default config file from current work directory |
| 265 | + // or return the default configuration, when no valid file is found |
| 266 | + let mut config_path = cwd.to_path_buf(); |
| 267 | + config_path.push(Self::DEFAULT_OXLINTRC); |
| 268 | + |
| 269 | + Oxlintrc::from_file(&config_path).or_else(|_| Ok(Oxlintrc::default())) |
| 270 | + } |
244 | 271 | } |
245 | 272 |
|
246 | 273 | #[cfg(all(test, not(target_os = "windows")))] |
@@ -432,6 +459,15 @@ mod test { |
432 | 459 | assert_eq!(result.number_of_errors, 0); |
433 | 460 | } |
434 | 461 |
|
| 462 | + #[test] |
| 463 | + fn oxlint_config_auto_detection() { |
| 464 | + let args = &["debugger.js"]; |
| 465 | + let result = test_with_cwd("fixtures/auto_config_detection", args); |
| 466 | + assert_eq!(result.number_of_files, 1); |
| 467 | + assert_eq!(result.number_of_warnings, 0); |
| 468 | + assert_eq!(result.number_of_errors, 1); |
| 469 | + } |
| 470 | + |
435 | 471 | #[test] |
436 | 472 | fn eslintrc_no_undef() { |
437 | 473 | let args = &[ |
|
0 commit comments