Skip to content

Commit

Permalink
feat(cli): add --rules CLI flag (#290)
Browse files Browse the repository at this point in the history
  • Loading branch information
shannonrothe committed Apr 18, 2023
1 parent 42859b3 commit 20755a9
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 8 deletions.
6 changes: 5 additions & 1 deletion crates/oxc_cli/src/lint/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ The default category is -D correctness.")
Arg::new("path")
.value_name("PATH")
.num_args(1..)
.required(true)
.required_unless_present("rules")
.value_parser(ValueParser::path_buf())
.help("File or Directory paths to scan. Directories are scanned recursively.")
)
Expand Down Expand Up @@ -82,4 +82,8 @@ The default category is -D correctness.")
.required(false)
.help("This option allows you to specify a warning threshold, which can be used to force oxc_lint to exit with an error status if there are too many warning-level rule violations in your project.")
)
.arg(
Arg::new("rules")
.long("rules")
.required(false).action(ArgAction::SetTrue).help("This option allows you to list all the rules that are currently registered."))
}
14 changes: 13 additions & 1 deletion crates/oxc_cli/src/lint/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ use clap::ArgMatches;
pub use self::{command::lint_command, runner::LintRunner};

#[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,
Expand Down Expand Up @@ -40,9 +42,11 @@ impl From<&'static str> for AllowWarnDeny {

impl<'a> From<&'a ArgMatches> for LintOptions {
fn from(matches: &'a ArgMatches) -> Self {
let list_rules = matches.get_flag("rules");

Self {
paths: matches.get_many("path").map_or_else(
|| vec![PathBuf::from(".")],
|| if list_rules { vec![] } else { vec![PathBuf::from(".")] },
|paths| paths.into_iter().cloned().collect(),
),
rules: Self::get_rules(matches),
Expand All @@ -57,6 +61,7 @@ impl<'a> From<&'a ArgMatches> for LintOptions {
.map(|patterns| patterns.into_iter().cloned().collect())
.unwrap_or_default(),
max_warnings: matches.get_one("max-warnings").copied(),
list_rules,
}
}
}
Expand Down Expand Up @@ -179,4 +184,11 @@ mod test {
get_lint_options("lint --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("lint --rules");
assert!(options.paths.is_empty());
assert!(options.list_rules);
}
}
22 changes: 21 additions & 1 deletion crates/oxc_cli/src/lint/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use oxc_diagnostics::{
use oxc_linter::{Fixer, Linter, RuleCategory, RuleEnum, RULES};
use oxc_parser::Parser;
use oxc_semantic::SemanticBuilder;
use rustc_hash::FxHashSet;
use rustc_hash::{FxHashMap, FxHashSet};

use super::{AllowWarnDeny, LintOptions};
use crate::{CliRunResult, Walk};
Expand All @@ -43,6 +43,22 @@ impl LintRunner {
Self { options, linter: Arc::new(linter) }
}

fn print_rules() {
let rules_by_category = RULES.iter().fold(FxHashMap::default(), |mut map, rule| {
map.entry(rule.category()).or_insert_with(Vec::new).push(rule);
map
});

let mut stdout = BufWriter::new(std::io::stdout());
for (category, rules) in rules_by_category {
writeln!(stdout, "{} ({}):", category, rules.len()).unwrap();
for rule in rules {
writeln!(stdout, " • {}", rule.name()).unwrap();
}
}
writeln!(stdout, "Total: {}", RULES.len()).unwrap();
}

fn derive_rules(options: &LintOptions) -> Vec<RuleEnum> {
let mut rules: FxHashSet<RuleEnum> = FxHashSet::default();

Expand Down Expand Up @@ -96,6 +112,10 @@ impl LintRunner {
pub fn run(&self) -> CliRunResult {
let now = std::time::Instant::now();

if self.options.list_rules {
Self::print_rules();
}

let number_of_files = Arc::new(AtomicUsize::new(0));
let (tx_error, rx_error) = mpsc::channel::<(PathBuf, Vec<Error>)>();

Expand Down
14 changes: 12 additions & 2 deletions crates/oxc_linter/src/rule.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::fmt::Debug;
use std::fmt::{Debug, Display};

use oxc_semantic::Symbol;

Expand Down Expand Up @@ -28,7 +28,7 @@ pub trait RuleMeta {
}

/// Rule categories defined by rust-clippy
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum RuleCategory {
/// Code that is outright wrong or useless
Correctness,
Expand All @@ -53,3 +53,13 @@ impl RuleCategory {
}
}
}

impl Display for RuleCategory {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Correctness => write!(f, "Correctness"),
Self::Restriction => write!(f, "Restriction"),
Self::Nursery => write!(f, "Nursery"),
}
}
}
2 changes: 1 addition & 1 deletion tasks/coverage/babel
Submodule babel updated 471 files
2 changes: 1 addition & 1 deletion tasks/coverage/test262
Submodule test262 updated 173 files
2 changes: 1 addition & 1 deletion tasks/coverage/typescript
Submodule typescript updated 4157 files

0 comments on commit 20755a9

Please sign in to comment.