diff options
-rw-r--r-- | cli/args/flags.rs | 44 | ||||
-rw-r--r-- | cli/tests/integration/lint_tests.rs | 7 | ||||
-rw-r--r-- | cli/tests/testdata/lint/expected_compact.out | 5 | ||||
-rw-r--r-- | cli/tools/lint.rs | 49 |
4 files changed, 105 insertions, 0 deletions
diff --git a/cli/args/flags.rs b/cli/args/flags.rs index 46fa8c552..a4eca942f 100644 --- a/cli/args/flags.rs +++ b/cli/args/flags.rs @@ -154,6 +154,7 @@ pub struct LintFlags { pub maybe_rules_include: Option<Vec<String>>, pub maybe_rules_exclude: Option<Vec<String>>, pub json: bool, + pub compact: bool, } #[derive(Clone, Debug, Eq, PartialEq, Deserialize, Serialize)] @@ -1402,6 +1403,13 @@ Ignore linting a file by adding an ignore comment at the top of the file: .takes_value(false), ) .arg( + Arg::new("compact") + .long("compact") + .help("Output lint result in compact format") + .takes_value(false) + .conflicts_with("json"), + ) + .arg( Arg::new("files") .takes_value(true) .multiple_values(true) @@ -2584,6 +2592,7 @@ fn lint_parse(flags: &mut Flags, matches: &clap::ArgMatches) { .map(|f| f.map(String::from).collect()); let json = matches.is_present("json"); + let compact = matches.is_present("compact"); flags.subcommand = DenoSubcommand::Lint(LintFlags { files, rules, @@ -2592,6 +2601,7 @@ fn lint_parse(flags: &mut Flags, matches: &clap::ArgMatches) { maybe_rules_exclude, ignore, json, + compact, }); } @@ -3686,6 +3696,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: false, + compact: false, ignore: vec![], }), ..Flags::default() @@ -3712,6 +3723,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: false, + compact: false, ignore: vec![], }), watch: Some(vec![]), @@ -3740,6 +3752,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: false, + compact: false, ignore: vec![], }), watch: Some(vec![]), @@ -3760,6 +3773,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: false, + compact: false, ignore: vec![ PathBuf::from("script_1.ts"), PathBuf::from("script_2.ts") @@ -3780,6 +3794,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: false, + compact: false, ignore: vec![], }), ..Flags::default() @@ -3803,6 +3818,7 @@ mod tests { maybe_rules_include: Some(svec!["ban-untagged-todo", "no-undef"]), maybe_rules_exclude: Some(svec!["no-const-assign"]), json: false, + compact: false, ignore: vec![], }), ..Flags::default() @@ -3820,6 +3836,7 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: true, + compact: false, ignore: vec![], }), ..Flags::default() @@ -3844,6 +3861,33 @@ mod tests { maybe_rules_include: None, maybe_rules_exclude: None, json: true, + compact: false, + ignore: vec![], + }), + config_flag: ConfigFlag::Path("Deno.jsonc".to_string()), + ..Flags::default() + } + ); + + let r = flags_from_vec(svec![ + "deno", + "lint", + "--config", + "Deno.jsonc", + "--compact", + "script_1.ts" + ]); + assert_eq!( + r.unwrap(), + Flags { + subcommand: DenoSubcommand::Lint(LintFlags { + files: vec![PathBuf::from("script_1.ts")], + rules: false, + maybe_rules_tags: None, + maybe_rules_include: None, + maybe_rules_exclude: None, + json: false, + compact: true, ignore: vec![], }), config_flag: ConfigFlag::Path("Deno.jsonc".to_string()), diff --git a/cli/tests/integration/lint_tests.rs b/cli/tests/integration/lint_tests.rs index 5ed12f59e..6b78e0609 100644 --- a/cli/tests/integration/lint_tests.rs +++ b/cli/tests/integration/lint_tests.rs @@ -42,6 +42,13 @@ itest!(json { exit_code: 1, }); +itest!(compact { + args: + "lint --compact lint/without_config/file1.js lint/without_config/file2.ts lint/without_config/ignored_file.tss", + output: "lint/expected_compact.out", + exit_code: 1, +}); + itest!(ignore { args: "lint --ignore=lint/without_config/file1.js,lint/without_config/malformed.js,lint/without_config/lint_with_config/ lint/without_config/", diff --git a/cli/tests/testdata/lint/expected_compact.out b/cli/tests/testdata/lint/expected_compact.out new file mode 100644 index 000000000..03b77faa1 --- /dev/null +++ b/cli/tests/testdata/lint/expected_compact.out @@ -0,0 +1,5 @@ +[WILDCARD]file1.js: line 1, col 1 - Ignore directive requires lint rule name(s) (ban-untagged-ignore) +[WILDCARD]file1.js: line 2, col 15 - Empty block statement (no-empty) +[WILDCARD]file2.ts: line 3, col 14 - Empty block statement (no-empty) +Found 3 problems +Checked 2 files diff --git a/cli/tools/lint.rs b/cli/tools/lint.rs index da5df3a81..9afc9cd46 100644 --- a/cli/tools/lint.rs +++ b/cli/tools/lint.rs @@ -49,12 +49,14 @@ static STDIN_FILE_NAME: &str = "_stdin.ts"; pub enum LintReporterKind { Pretty, Json, + Compact, } fn create_reporter(kind: LintReporterKind) -> Box<dyn LintReporter + Send> { match kind { LintReporterKind::Pretty => Box::new(PrettyLintReporter::new()), LintReporterKind::Json => Box::new(JsonLintReporter::new()), + LintReporterKind::Compact => Box::new(CompactLintReporter::new()), } } @@ -66,6 +68,7 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { files: args, ignore, json, + compact, .. } = lint_flags; // First, prepare final configuration. @@ -104,6 +107,8 @@ pub async fn lint(flags: Flags, lint_flags: LintFlags) -> Result<(), AnyError> { let reporter_kind = if json { LintReporterKind::Json + } else if compact { + LintReporterKind::Compact } else { LintReporterKind::Pretty }; @@ -413,6 +418,50 @@ impl LintReporter for PrettyLintReporter { } } +struct CompactLintReporter { + lint_count: u32, +} + +impl CompactLintReporter { + fn new() -> CompactLintReporter { + CompactLintReporter { lint_count: 0 } + } +} + +impl LintReporter for CompactLintReporter { + fn visit_diagnostic(&mut self, d: &LintDiagnostic, _source_lines: Vec<&str>) { + self.lint_count += 1; + + eprintln!( + "{}: line {}, col {} - {} ({})", + d.filename, + d.range.start.line_index + 1, + d.range.start.column_index + 1, + d.message, + d.code + ) + } + + fn visit_error(&mut self, file_path: &str, err: &AnyError) { + eprintln!("Error linting: {}", file_path); + eprintln!(" {}", err); + } + + fn close(&mut self, check_count: usize) { + match self.lint_count { + 1 => info!("Found 1 problem"), + n if n > 1 => info!("Found {} problems", self.lint_count), + _ => (), + } + + match check_count { + n if n <= 1 => info!("Checked {} file", n), + n if n > 1 => info!("Checked {} files", n), + _ => unreachable!(), + } + } +} + pub fn format_diagnostic( diagnostic_code: &str, message_line: &str, |