Skip to content
Closed
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
14 changes: 7 additions & 7 deletions apps/oxlint/src/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,6 @@ impl Runner for LintRunner {
let format_str = self.options.output_options.format;
let output_formatter = OutputFormatter::new(format_str);

if self.options.list_rules {
if let Some(output) = output_formatter.all_rules() {
print_and_flush_stdout(stdout, &output);
}
return CliRunResult::None;
}

let LintCommand {
paths,
filter,
Expand Down Expand Up @@ -254,6 +247,13 @@ impl Runner for LintRunner {

let lint_config = config_builder.build();

if self.options.list_rules {
if let Some(output) = output_formatter.all_rules(Some(&lint_config)) {
print_and_flush_stdout(stdout, &output);
}
return CliRunResult::None;
}

let report_unused_directives = match inline_config_options.report_unused_directives {
ReportUnusedDirectives::WithoutSeverity(true) => Some(AllowWarnDeny::Warn),
ReportUnusedDirectives::WithSeverity(Some(severity)) => Some(severity),
Expand Down
10 changes: 6 additions & 4 deletions apps/oxlint/src/output_formatter/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@ use oxc_diagnostics::{
Error, GraphicalReportHandler,
reporter::{DiagnosticReporter, DiagnosticResult},
};
use oxc_linter::table::RuleTable;
use oxc_linter::{Config, table::RuleTable};

#[derive(Debug)]
pub struct DefaultOutputFormatter;

impl InternalFormatter for DefaultOutputFormatter {
fn all_rules(&self) -> Option<String> {
fn all_rules(&self, config: Option<&Config>) -> Option<String> {
let mut output = String::new();
let table = RuleTable::default();
let table = RuleTable::new(None, config);
for section in table.sections {
output.push_str(section.render_markdown_table(None).as_str());
output.push('\n');
}

output.push_str(format!("Enabled: {}\n", table.enabled_count).as_str());
output.push_str(format!("Default: {}\n", table.turned_on_by_default_count).as_str());
output.push_str(format!("Total: {}\n", table.total).as_str());
Some(output)
Expand Down Expand Up @@ -164,7 +166,7 @@ mod test {
#[test]
fn all_rules() {
let formatter = DefaultOutputFormatter;
let result = formatter.all_rules();
let result = formatter.all_rules(None);

assert!(result.is_some());
}
Expand Down
4 changes: 2 additions & 2 deletions apps/oxlint/src/output_formatter/json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use oxc_diagnostics::{
Error,
reporter::{DiagnosticReporter, DiagnosticResult},
};
use oxc_linter::{RuleCategory, rules::RULES};
use oxc_linter::{Config, RuleCategory, rules::RULES};

use miette::JSONReportHandler;

Expand All @@ -17,7 +17,7 @@ pub struct JsonOutputFormatter {
}

impl InternalFormatter for JsonOutputFormatter {
fn all_rules(&self) -> Option<String> {
fn all_rules(&self, _config: Option<&Config>) -> Option<String> {
#[derive(Debug, serde::Serialize)]
struct RuleInfoJson<'a> {
scope: &'a str,
Expand Down
7 changes: 4 additions & 3 deletions apps/oxlint/src/output_formatter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use stylish::StylishOutputFormatter;
use unix::UnixOutputFormatter;

use oxc_diagnostics::reporter::DiagnosticReporter;
use oxc_linter::Config;

use crate::output_formatter::{default::DefaultOutputFormatter, json::JsonOutputFormatter};

Expand Down Expand Up @@ -72,7 +73,7 @@ pub struct LintCommandInfo {
/// The Formatter is then managed by [`OutputFormatter`].
trait InternalFormatter {
/// Print all available rules by oxlint
fn all_rules(&self) -> Option<String> {
fn all_rules(&self, _config: Option<&Config>) -> Option<String> {
None
}

Expand Down Expand Up @@ -110,8 +111,8 @@ impl OutputFormatter {

/// Print all available rules by oxlint
/// See [`InternalFormatter::all_rules`] for more details.
pub fn all_rules(&self) -> Option<String> {
self.internal.all_rules()
pub fn all_rules(&self, config: Option<&Config>) -> Option<String> {
self.internal.all_rules(config)
}

/// At the end of the Lint command we may output extra information.
Expand Down
35 changes: 28 additions & 7 deletions crates/oxc_linter/src/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ use std::{borrow::Cow, fmt::Write};

use rustc_hash::{FxHashMap, FxHashSet};

use crate::{RuleCategory, RuleFixMeta, rules::RULES};
use crate::{Config, RuleCategory, RuleFixMeta, rules::RULES};

pub struct RuleTable {
pub sections: Vec<RuleTableSection>,
pub total: usize,
pub turned_on_by_default_count: usize,
pub enabled_count: usize,
}

pub struct RuleTableSection {
Expand All @@ -27,25 +28,32 @@ pub struct RuleTableRow {
pub schema: Option<schemars::schema::Schema>,

pub turned_on_by_default: bool,
pub enabled: bool,
pub autofix: RuleFixMeta,
}

impl Default for RuleTable {
fn default() -> Self {
Self::new(None)
Self::new(None, None)
}
}

impl RuleTable {
#[expect(clippy::allow_attributes)]
#[allow(unused, unused_mut)]
pub fn new(mut generator: Option<&mut schemars::SchemaGenerator>) -> Self {
pub fn new(
mut generator: Option<&mut schemars::SchemaGenerator>,
config: Option<&Config>,
) -> Self {
let default_rules = RULES
.iter()
.filter(|rule| rule.category() == RuleCategory::Correctness)
.map(super::rules::RuleEnum::name)
.collect::<FxHashSet<&str>>();

let enabled_rules =
config.map(|c| c.rules().iter().map(|rule| rule.0.name()).collect::<FxHashSet<&str>>());

let mut rows = RULES
.iter()
.map(|rule| {
Expand All @@ -58,6 +66,7 @@ impl RuleTable {
schema: generator.as_mut().and_then(|g| rule.schema(g)),
plugin: rule.plugin_name().to_string(),
category: rule.category(),
enabled: enabled_rules.as_ref().is_some_and(|e| e.contains(name)),
turned_on_by_default: default_rules.contains(name),
autofix: rule.fix(),
}
Expand Down Expand Up @@ -94,7 +103,12 @@ impl RuleTable {
})
.collect::<Vec<_>>();

RuleTable { total, sections, turned_on_by_default_count: 123 }
RuleTable {
total,
sections,
turned_on_by_default_count: 123,
enabled_count: enabled_rules.map_or(0, |rules| rules.len()),
}
}
}

Expand All @@ -106,9 +120,11 @@ impl RuleTableSection {
pub fn render_markdown_table(&self, link_prefix: Option<&str>) -> String {
const FIX_EMOJI_COL_WIDTH: usize = 10;
const DEFAULT_EMOJI_COL_WIDTH: usize = 9;
const ENABLED_COL_WIDTH: usize = 10;
/// text width, leave 2 spaces for padding
const FIX: usize = FIX_EMOJI_COL_WIDTH - 2;
const DEFAULT: usize = DEFAULT_EMOJI_COL_WIDTH - 2;
const ENABLED: usize = ENABLED_COL_WIDTH - 2;

let mut s = String::new();
let category = &self.category;
Expand All @@ -122,17 +138,22 @@ impl RuleTableSection {
let x = "";
writeln!(
s,
"| {:<rule_width$} | {:<plugin_width$} | Default | Fixable? |",
"| {:<rule_width$} | {:<plugin_width$} | Enabled? | Default | Fixable? |",
"Rule name", "Source"
)
.unwrap();
writeln!(s, "| {x:-<rule_width$} | {x:-<plugin_width$} | {x:-<7} | {x:-<8} |").unwrap();
writeln!(s, "| {x:-<rule_width$} | {x:-<plugin_width$} | {x:-<8} | {x:-<7} | {x:-<8} |")
.unwrap();

for row in rows {
let rule_name = row.name;
let plugin_name = &row.plugin;
let (default, default_width) =
if row.turned_on_by_default { ("✅", DEFAULT - 1) } else { ("", DEFAULT) };

let (enabled, enabled_width) =
if row.enabled { ("✅", ENABLED - 1) } else { ("", ENABLED) };

let rendered_name = if let Some(prefix) = link_prefix {
Cow::Owned(format!("[{rule_name}]({prefix}/{plugin_name}/{rule_name}.html)"))
} else {
Expand All @@ -142,7 +163,7 @@ impl RuleTableSection {
let len = emoji.len();
if len > FIX { (emoji, 0) } else { (emoji, FIX - len) }
});
writeln!(s, "| {rendered_name:<rule_width$} | {plugin_name:<plugin_width$} | {default:<default_width$} | {fix_emoji:<fix_emoji_width$} |").unwrap();
writeln!(s, "| {rendered_name:<rule_width$} | {plugin_name:<plugin_width$} | {enabled:<enabled_width$} | {default:<default_width$} | {fix_emoji:<fix_emoji_width$} |").unwrap();
}

s
Expand Down
1 change: 1 addition & 0 deletions tasks/website/src/linter/rules/doc_page.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ impl Context {
turned_on_by_default,
autofix,
category,
enabled: _,
} = rule;
let resolved =
schema.as_ref().map(|schema| self.schemas.dereference(schema).unwrap_or(schema));
Expand Down
2 changes: 1 addition & 1 deletion tasks/website/src/linter/rules/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pub fn print_rules(mut args: Arguments) {
});

let mut generator = SchemaGenerator::new(SchemaSettings::default());
let table = RuleTable::new(Some(&mut generator));
let table = RuleTable::new(Some(&mut generator), None);

if let Some(table_path) = table_path {
let table_path = pwd.join(table_path).canonicalize().unwrap();
Expand Down