mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
refactor(cli): add WalkOptions for walk logic (#757)
This commit is contained in:
parent
a9c4fddb6d
commit
772f71f191
5 changed files with 98 additions and 82 deletions
|
|
@ -1,5 +1,5 @@
|
|||
use bpaf::{any, Bpaf, Parser};
|
||||
use std::path::PathBuf;
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
|
||||
#[derive(Debug, Clone, Bpaf)]
|
||||
#[bpaf(options)]
|
||||
|
|
@ -63,18 +63,22 @@ pub struct CliOptions {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Bpaf)]
|
||||
pub struct IgnoreOptions {
|
||||
pub struct WalkOptions {
|
||||
/// Disables excluding of files from .eslintignore files
|
||||
#[bpaf(switch)]
|
||||
pub no_ignore: bool,
|
||||
|
||||
/// Specify the file to use as your .eslintignore
|
||||
#[bpaf(argument("PATH"), optional)]
|
||||
pub ignore_path: Option<PathBuf>,
|
||||
#[bpaf(argument("PATH"), fallback(".eslintignore".into()))]
|
||||
pub ignore_path: OsString,
|
||||
|
||||
/// Specify patterns of files to ignore (in addition to those in .eslintignore)
|
||||
#[bpaf(argument("PATTERN"), many)]
|
||||
pub ignore_pattern: Vec<String>,
|
||||
|
||||
/// Single file, single path or list of paths
|
||||
#[bpaf(positional("PATH"), many)]
|
||||
pub paths: Vec<PathBuf>,
|
||||
}
|
||||
|
||||
static FILTER_HELP: &str = r#"
|
||||
|
|
@ -100,9 +104,6 @@ pub struct LintOptions {
|
|||
#[bpaf(switch)]
|
||||
pub fix: bool,
|
||||
|
||||
#[bpaf(external(ignore_options), hide_usage)]
|
||||
pub ignore: IgnoreOptions,
|
||||
|
||||
/// Display the execution time of each lint rule
|
||||
#[bpaf(switch, env("TIMING"), hide_usage)]
|
||||
pub timing: bool,
|
||||
|
|
@ -114,9 +115,8 @@ pub struct LintOptions {
|
|||
#[bpaf(external(cli_options), hide_usage)]
|
||||
pub cli: CliOptions,
|
||||
|
||||
/// Single file, single path or list of paths
|
||||
#[bpaf(positional("PATH"), many)]
|
||||
pub paths: Vec<PathBuf>,
|
||||
#[bpaf(external(walk_options), hide_usage)]
|
||||
pub walk: WalkOptions,
|
||||
|
||||
#[bpaf(external(filter_value), many, group_help(FILTER_HELP))]
|
||||
pub filter: Vec<FilterValue>,
|
||||
|
|
@ -168,3 +168,56 @@ pub struct CheckOptions {
|
|||
#[bpaf(positional("PATH"))]
|
||||
pub path: PathBuf,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod walk_options {
|
||||
use super::{lint_command, WalkOptions};
|
||||
use std::{ffi::OsString, path::PathBuf};
|
||||
|
||||
fn get_walk_options(arg: &str) -> WalkOptions {
|
||||
let args = arg.split(' ').map(std::string::ToString::to_string).collect::<Vec<String>>();
|
||||
lint_command().run_inner(args.as_slice()).unwrap().lint_options.walk
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let options = get_walk_options(".");
|
||||
assert_eq!(options.paths, vec![PathBuf::from(".")]);
|
||||
assert_eq!(options.ignore_path, OsString::from(".eslintignore"));
|
||||
assert!(!options.no_ignore);
|
||||
assert!(options.ignore_pattern.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_paths() {
|
||||
let options = get_walk_options("foo bar baz");
|
||||
assert_eq!(
|
||||
options.paths,
|
||||
[PathBuf::from("foo"), PathBuf::from("bar"), PathBuf::from("baz")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_path() {
|
||||
let options = get_walk_options("--ignore-path .xxx foo.js");
|
||||
assert_eq!(options.ignore_path, PathBuf::from(".xxx"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore() {
|
||||
let options = get_walk_options("--no-ignore foo.js");
|
||||
assert!(options.no_ignore);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_ignore_pattern() {
|
||||
let options = get_walk_options("--ignore-pattern ./test foo.js");
|
||||
assert_eq!(options.ignore_pattern, vec![String::from("./test")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_ignore_pattern() {
|
||||
let options = get_walk_options("--ignore-pattern ./test --ignore-pattern bar.js foo.js");
|
||||
assert_eq!(options.ignore_pattern, vec![String::from("./test"), String::from("bar.js")]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,9 +21,11 @@ use oxc_parser::Parser;
|
|||
use oxc_semantic::SemanticBuilder;
|
||||
use oxc_span::SourceType;
|
||||
|
||||
use crate::{CliRunResult, Walk};
|
||||
use crate::{CliRunResult, Walk, WalkOptions};
|
||||
|
||||
pub struct IsolatedLintHandler {
|
||||
walk_options: Arc<WalkOptions>,
|
||||
|
||||
options: Arc<LintOptions>,
|
||||
|
||||
linter: Arc<Linter>,
|
||||
|
|
@ -35,8 +37,12 @@ pub struct IsolatedLintHandler {
|
|||
pub struct MinifiedFileError(pub PathBuf);
|
||||
|
||||
impl IsolatedLintHandler {
|
||||
pub(super) fn new(options: Arc<LintOptions>, linter: Arc<Linter>) -> Self {
|
||||
Self { options, linter }
|
||||
pub(super) fn new(
|
||||
walk_options: Arc<WalkOptions>,
|
||||
options: Arc<LintOptions>,
|
||||
linter: Arc<Linter>,
|
||||
) -> Self {
|
||||
Self { walk_options, options, linter }
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
|
|
@ -71,7 +77,7 @@ impl IsolatedLintHandler {
|
|||
) {
|
||||
let (tx_path, rx_path) = mpsc::channel::<Box<Path>>();
|
||||
|
||||
let walk = Walk::new(&self.options);
|
||||
let walk = Walk::new(&self.walk_options);
|
||||
let number_of_files = Arc::clone(number_of_files);
|
||||
rayon::spawn(move || {
|
||||
let mut count = 0;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
mod error;
|
||||
mod isolated_handler;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use std::{io::BufWriter, sync::Arc, time::Duration};
|
||||
|
||||
pub use self::{error::Error, isolated_handler::IsolatedLintHandler};
|
||||
|
|
@ -11,9 +10,13 @@ use oxc_linter::{AllowWarnDeny, LintOptions, Linter, RuleCategory, RuleEnum, RUL
|
|||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::FilterType;
|
||||
use crate::{command::LintOptions as CliLintOptions, CliRunResult, Runner};
|
||||
use crate::{
|
||||
command::{LintOptions as CliLintOptions, WalkOptions},
|
||||
CliRunResult, Runner,
|
||||
};
|
||||
|
||||
pub struct LintRunner {
|
||||
walk_options: Arc<WalkOptions>,
|
||||
options: Arc<LintOptions>,
|
||||
linter: Arc<Linter>,
|
||||
}
|
||||
|
|
@ -23,11 +26,15 @@ impl Runner for LintRunner {
|
|||
type Options = CliLintOptions;
|
||||
|
||||
fn new(options: Self::Options) -> Self {
|
||||
let options = parse_cli_options(options);
|
||||
let linter = Linter::from_rules(Self::derive_rules(&options))
|
||||
.with_fix(options.fix)
|
||||
.with_print_execution_times(options.print_execution_times);
|
||||
Self { options: Arc::new(options), linter: Arc::new(linter) }
|
||||
let lint_options = parse_cli_options(&options);
|
||||
let linter = Linter::from_rules(Self::derive_rules(&lint_options))
|
||||
.with_fix(lint_options.fix)
|
||||
.with_print_execution_times(lint_options.print_execution_times);
|
||||
Self {
|
||||
walk_options: Arc::new(options.walk),
|
||||
options: Arc::new(lint_options),
|
||||
linter: Arc::new(linter),
|
||||
}
|
||||
}
|
||||
|
||||
fn run(&self) -> CliRunResult {
|
||||
|
|
@ -36,8 +43,12 @@ impl Runner for LintRunner {
|
|||
return CliRunResult::None;
|
||||
}
|
||||
|
||||
let result =
|
||||
IsolatedLintHandler::new(Arc::clone(&self.options), Arc::clone(&self.linter)).run();
|
||||
let result = IsolatedLintHandler::new(
|
||||
Arc::clone(&self.walk_options),
|
||||
Arc::clone(&self.options),
|
||||
Arc::clone(&self.linter),
|
||||
)
|
||||
.run();
|
||||
|
||||
if self.options.print_execution_times {
|
||||
self.print_execution_times();
|
||||
|
|
@ -121,16 +132,12 @@ impl LintRunner {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_cli_options(options: CliLintOptions) -> LintOptions {
|
||||
let rules = get_rules(&options);
|
||||
fn parse_cli_options(options: &CliLintOptions) -> LintOptions {
|
||||
let rules = get_rules(options);
|
||||
LintOptions {
|
||||
paths: options.paths,
|
||||
rules,
|
||||
fix: options.fix,
|
||||
quiet: options.cli.quiet,
|
||||
ignore_path: options.ignore.ignore_path.unwrap_or_else(|| PathBuf::from(".eslintignore")),
|
||||
no_ignore: options.ignore.no_ignore,
|
||||
ignore_pattern: options.ignore.ignore_pattern,
|
||||
max_warnings: options.cli.max_warnings,
|
||||
list_rules: options.rules,
|
||||
print_execution_times: options.timing,
|
||||
|
|
@ -157,38 +164,23 @@ fn get_rules(options: &CliLintOptions) -> Vec<(AllowWarnDeny, String)> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::path::PathBuf;
|
||||
|
||||
use super::{parse_cli_options, AllowWarnDeny, LintOptions};
|
||||
use crate::lint_command;
|
||||
|
||||
fn get_lint_options(arg: &str) -> LintOptions {
|
||||
let args = arg.split(' ').map(std::string::ToString::to_string).collect::<Vec<String>>();
|
||||
let options = lint_command().run_inner(args.as_slice()).unwrap();
|
||||
parse_cli_options(options.lint_options)
|
||||
parse_cli_options(&options.lint_options)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let options = get_lint_options(".");
|
||||
assert_eq!(options.paths, vec![PathBuf::from(".")]);
|
||||
assert!(!options.fix);
|
||||
assert!(!options.quiet);
|
||||
assert_eq!(options.ignore_path, PathBuf::from(".eslintignore"));
|
||||
assert!(!options.no_ignore);
|
||||
assert!(options.ignore_pattern.is_empty());
|
||||
assert_eq!(options.max_warnings, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_paths() {
|
||||
let options = get_lint_options("foo bar baz");
|
||||
assert_eq!(
|
||||
options.paths,
|
||||
[PathBuf::from("foo"), PathBuf::from("bar"), PathBuf::from("baz")]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rules_with_deny_and_allow() {
|
||||
let options =
|
||||
|
|
@ -222,34 +214,9 @@ mod test {
|
|||
assert_eq!(options.max_warnings, Some(10));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ignore_path() {
|
||||
let options = get_lint_options("--ignore-path .xxx foo.js");
|
||||
assert_eq!(options.ignore_path, PathBuf::from(".xxx"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn no_ignore() {
|
||||
let options = get_lint_options("--no-ignore foo.js");
|
||||
assert!(options.no_ignore);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn single_ignore_pattern() {
|
||||
let options = get_lint_options("--ignore-pattern ./test foo.js");
|
||||
assert_eq!(options.ignore_pattern, vec![String::from("./test")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn multiple_ignore_pattern() {
|
||||
let options = get_lint_options("--ignore-pattern ./test --ignore-pattern bar.js foo.js");
|
||||
assert_eq!(options.ignore_pattern, vec![String::from("./test"), String::from("bar.js")]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn list_rules_true() {
|
||||
let options = get_lint_options("--rules");
|
||||
assert!(options.paths.is_empty());
|
||||
assert!(options.list_rules);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use std::path::Path;
|
|||
use ignore::{overrides::OverrideBuilder, DirEntry, WalkBuilder};
|
||||
use oxc_span::VALID_EXTENSIONS;
|
||||
|
||||
use oxc_linter::LintOptions;
|
||||
use crate::WalkOptions;
|
||||
|
||||
pub struct Walk {
|
||||
inner: ignore::Walk,
|
||||
|
|
@ -11,7 +11,7 @@ pub struct Walk {
|
|||
|
||||
impl Walk {
|
||||
/// # Panics
|
||||
pub fn new(options: &LintOptions) -> Self {
|
||||
pub fn new(options: &WalkOptions) -> Self {
|
||||
let mut inner = WalkBuilder::new(&options.paths[0]);
|
||||
|
||||
if let Some(paths) = options.paths.get(1..) {
|
||||
|
|
|
|||
|
|
@ -1,18 +1,12 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug)]
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct LintOptions {
|
||||
pub paths: Vec<PathBuf>,
|
||||
/// Allow / Deny rules in order. [("allow" / "deny", rule name)]
|
||||
/// Defaults to [("deny", "correctness")]
|
||||
pub rules: Vec<(AllowWarnDeny, String)>,
|
||||
pub list_rules: bool,
|
||||
pub fix: bool,
|
||||
pub quiet: bool,
|
||||
pub ignore_path: PathBuf,
|
||||
pub no_ignore: bool,
|
||||
pub ignore_pattern: Vec<String>,
|
||||
pub max_warnings: Option<usize>,
|
||||
pub print_execution_times: bool,
|
||||
}
|
||||
|
|
@ -20,14 +14,10 @@ pub struct LintOptions {
|
|||
impl Default for LintOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
paths: vec![],
|
||||
rules: vec![(AllowWarnDeny::Deny, String::from("correctness"))],
|
||||
list_rules: false,
|
||||
fix: false,
|
||||
quiet: false,
|
||||
ignore_path: PathBuf::default(),
|
||||
no_ignore: false,
|
||||
ignore_pattern: vec![],
|
||||
max_warnings: None,
|
||||
print_execution_times: false,
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue