Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): add --rules CLI flag #290

Merged
merged 8 commits into from
Apr 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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