diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots.toml index e053434926..098ecfbbd3 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots.toml @@ -4,4 +4,5 @@ vp = "local" steps = [ { argv = ["vp", "check", "--fix"], continue-on-failure = true }, { argv = ["vp", "check"], continue-on-failure = true }, + { argv = ["vp", "check", "--fix", "--quiet"], comment = "quiet composes with the fix pipeline", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots/check_fix_lint_warn.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots/check_fix_lint_warn.md index b31eff7555..6a50cf7c2e 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots/check_fix_lint_warn.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fix_lint_warn/snapshots/check_fix_lint_warn.md @@ -33,3 +33,13 @@ warn: Lint warnings found Found 0 errors and 1 warning in 2 files (, threads) ``` + +## `vp check --fix --quiet` + +quiet composes with the fix pipeline + +``` + +Found 0 errors and 1 warning in 2 files (, threads) +pass: Formatting completed for checked files () +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots.toml index a82d0d2060..821eb19b85 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots.toml @@ -3,6 +3,7 @@ name = "check_fmt_fail" vp = "local" steps = [ { argv = ["vp", "check"], continue-on-failure = true }, + { argv = ["vp", "check", "--quiet"], comment = "quiet does not suppress formatting failures", continue-on-failure = true }, { argv = ["vp", "check", "--fix"], continue-on-failure = true }, { argv = ["vp", "check"], comment = "should pass after fix", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots/check_fmt_fail.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots/check_fmt_fail.md index a9b3215b87..4e32f8e6d8 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots/check_fmt_fail.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_fmt_fail/snapshots/check_fmt_fail.md @@ -11,6 +11,19 @@ src/index.js () Found formatting issues in 1 file (, threads). Run `vp check --fix` to fix them. ``` +## `vp check --quiet` + +quiet does not suppress formatting failures + +**Exit code:** 1 + +``` +error: Formatting issues found +src/index.js () + +Found formatting issues in 1 file (, threads). Run `vp check --fix` to fix them. +``` + ## `vp check --fix` ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots.toml index 9834d031ae..03ee472126 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots.toml @@ -3,4 +3,5 @@ name = "check_lint_fail" vp = "local" steps = [ { argv = ["vp", "check"], continue-on-failure = true }, + { argv = ["vp", "check", "--quiet"], comment = "warnings are suppressed while errors are still reported", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots/check_lint_fail.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots/check_lint_fail.md index 39b8d60272..16a3ce5f00 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots/check_lint_fail.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/snapshots/check_lint_fail.md @@ -12,9 +12,39 @@ error: Lint issues found 1 │ function hello() { 2 │ eval("code"); · ──── - 3 │ return "hello"; + 3 │ console.log("warning"); ╰──── help: Avoid eval(). For JSON parsing use JSON.parse(); for dynamic property access use bracket notation (obj[key]); for other cases refactor to avoid evaluating strings as code. -Found 1 error and 0 warnings in 2 files (, threads) + ⚠ eslint(no-console): Unexpected console statement. + ╭─[src/index.js:3:3] + 2 │ eval("code"); + 3 │ console.log("warning"); + · ─────────── + 4 │ return "hello"; + ╰──── + help: Delete this console statement. + +Found 1 error and 1 warning in 2 files (, threads) +``` + +## `vp check --quiet` + +warnings are suppressed while errors are still reported + +**Exit code:** 1 + +``` +pass: All 3 files are correctly formatted (, threads) +error: Lint issues found +× eslint(no-eval): eval can be harmful. + ╭─[src/index.js:2:3] + 1 │ function hello() { + 2 │ eval("code"); + · ──── + 3 │ console.log("warning"); + ╰──── + help: Avoid eval(). For JSON parsing use JSON.parse(); for dynamic property access use bracket notation (obj[key]); for other cases refactor to avoid evaluating strings as code. + +Found 1 error and 1 warning in 2 files (, threads) ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/src/index.js b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/src/index.js index e916f931f1..11c76887e2 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/src/index.js +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/src/index.js @@ -1,5 +1,6 @@ function hello() { eval("code"); + console.log("warning"); return "hello"; } diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/vite.config.ts b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/vite.config.ts index 96170b5f50..f328efe2f1 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/vite.config.ts +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_fail/vite.config.ts @@ -2,6 +2,7 @@ export default { lint: { rules: { "no-eval": "error", + "no-console": "warn", }, }, }; diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots.toml index 48604895d6..811ee5d44a 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots.toml @@ -3,4 +3,6 @@ name = "check_lint_warn" vp = "local" steps = [ { argv = ["vp", "check"], continue-on-failure = true }, + { argv = ["vp", "check", "--quiet"], comment = "warning diagnostics are suppressed", continue-on-failure = true }, + { argv = ["vp", "lint", "--quiet"], comment = "standalone lint has the same warning suppression semantics", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots/check_lint_warn.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots/check_lint_warn.md index 50b8744625..80014e8d9b 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots/check_lint_warn.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn/snapshots/check_lint_warn.md @@ -16,3 +16,23 @@ warn: Lint warnings found Found 0 errors and 1 warning in 2 files (, threads) ``` + +## `vp check --quiet` + +warning diagnostics are suppressed + +``` +pass: All 3 files are correctly formatted (, threads) + +Found 0 errors and 1 warning in 2 files (, threads) +``` + +## `vp lint --quiet` + +standalone lint has the same warning suppression semantics + +``` + +Found 1 warning and 0 errors. +Finished in on 2 files with rules using threads. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots.toml index f039af242a..b516ce4927 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots.toml @@ -3,4 +3,6 @@ name = "check_lint_warn_deny_warnings" vp = "local" steps = [ { argv = ["vp", "check"], continue-on-failure = true }, + { argv = ["vp", "check", "--quiet"], comment = "warnings stay hidden but denyWarnings still fails", continue-on-failure = true }, + { argv = ["vp", "lint", "--quiet"], comment = "standalone lint also hides diagnostics and preserves the denyWarnings failure", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots/check_lint_warn_deny_warnings.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots/check_lint_warn_deny_warnings.md index 3888c8faa0..cf63375da6 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots/check_lint_warn_deny_warnings.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_lint_warn_deny_warnings/snapshots/check_lint_warn_deny_warnings.md @@ -18,3 +18,28 @@ warn: Lint warnings found Found 0 errors and 1 warning in 2 files (, threads) ``` + +## `vp check --quiet` + +warnings stay hidden but denyWarnings still fails + +**Exit code:** 1 + +``` +pass: All 3 files are correctly formatted (, threads) +warn: Lint warnings found + +Found 0 errors and 1 warning in 2 files (, threads) +``` + +## `vp lint --quiet` + +standalone lint also hides diagnostics and preserves the denyWarnings failure + +**Exit code:** 1 + +``` + +Found 1 warning and 0 errors. +Finished in on 2 files with rules using threads. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots.toml index 4feff36c0c..7f604c29e8 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots.toml @@ -3,4 +3,5 @@ name = "check_no_lint_typecheck_fail" vp = "local" steps = [ { argv = ["vp", "check", "--no-lint"], continue-on-failure = true }, + { argv = ["vp", "check", "--no-lint", "--quiet"], comment = "type errors are still reported when lint rules are skipped", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots/check_no_lint_typecheck_fail.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots/check_no_lint_typecheck_fail.md index ce692ad540..e15b93c756 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots/check_no_lint_typecheck_fail.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/check_no_lint_typecheck_fail/snapshots/check_no_lint_typecheck_fail.md @@ -16,3 +16,22 @@ error: Type errors found Found 1 error and 0 warnings in 2 files (, threads) ``` + +## `vp check --no-lint --quiet` + +type errors are still reported when lint rules are skipped + +**Exit code:** 1 + +``` +pass: All 3 files are correctly formatted (, threads) +error: Type errors found +× typescript(TS2322): Type 'string' is not assignable to type 'number'. + ╭─[src/index.ts:1:7] + 1 │ const value: number = "not a number"; + · ───── + 2 │ export { value }; + ╰──── + +Found 1 error and 0 warnings in 2 files (, threads) +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_check_help/snapshots/command_check_help.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_check_help/snapshots/command_check_help.md index e38f2f7ec0..76081e3122 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_check_help/snapshots/command_check_help.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_check_help/snapshots/command_check_help.md @@ -14,6 +14,7 @@ Arguments: Options: --fix Auto-fix format and lint issues + --quiet Disable reporting on warnings, only errors are reported --no-fmt Skip format check --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched @@ -41,6 +42,7 @@ Arguments: Options: --fix Auto-fix format and lint issues + --quiet Disable reporting on warnings, only errors are reported --no-fmt Skip format check --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched @@ -68,6 +70,7 @@ Arguments: Options: --fix Auto-fix format and lint issues + --quiet Disable reporting on warnings, only errors are reported --no-fmt Skip format check --no-lint Skip lint rules; type-check still runs when `lint.options.typeCheck` is true --no-error-on-unmatched-pattern Do not exit with error when pattern is unmatched diff --git a/docs/guide/check.md b/docs/guide/check.md index 0d04c3e58e..5e5e20039a 100644 --- a/docs/guide/check.md +++ b/docs/guide/check.md @@ -15,6 +15,7 @@ We recommend turning `typeCheck` on so `vp check` becomes the single command for ```bash vp check vp check --fix # Format and run autofixers. +vp check --quiet # Hide lint warnings; still report and fail on errors. vp check --no-fmt # Skip format; run lint (and type-check if enabled). vp check --no-lint # Skip lint rules; keep type-check when enabled. vp check --no-fmt --no-lint # Type-check only (requires `typeCheck` enabled). diff --git a/packages/cli/binding/src/check/analysis.rs b/packages/cli/binding/src/check/analysis.rs index ae94393b48..8a9ea32694 100644 --- a/packages/cli/binding/src/check/analysis.rs +++ b/packages/cli/binding/src/check/analysis.rs @@ -52,9 +52,11 @@ impl LintMessageKind { } } - pub(super) fn success_label(self) -> &'static str { + pub(super) fn success_label(self, quiet: bool) -> &'static str { match self { + Self::LintOnly if quiet => "Found no lint errors", Self::LintOnly => "Found no warnings or lint errors", + Self::LintAndTypeCheck if quiet => "Found no lint or type errors", Self::LintAndTypeCheck => "Found no warnings, lint errors, or type errors", Self::TypeCheckOnly => "Found no type errors", } @@ -262,7 +264,10 @@ mod tests { fn lint_message_kind_defaults_to_lint_only_without_typecheck() { assert!(!lint_config_type_check_enabled(None)); assert!(!lint_config_type_check_enabled(Some(&json!({ "options": {} })))); - assert_eq!(LintMessageKind::from_flags(true, false), LintMessageKind::LintOnly); + let kind = LintMessageKind::from_flags(true, false); + assert_eq!(kind, LintMessageKind::LintOnly); + assert_eq!(kind.success_label(false), "Found no warnings or lint errors"); + assert_eq!(kind.success_label(true), "Found no lint errors"); } #[test] @@ -278,7 +283,8 @@ mod tests { let kind = LintMessageKind::from_flags(true, true); assert_eq!(kind, LintMessageKind::LintAndTypeCheck); - assert_eq!(kind.success_label(), "Found no warnings, lint errors, or type errors"); + assert_eq!(kind.success_label(false), "Found no warnings, lint errors, or type errors"); + assert_eq!(kind.success_label(true), "Found no lint or type errors"); assert_eq!(kind.warning_heading(), "Lint or type warnings found"); assert_eq!(kind.issue_heading(), "Lint or type issues found"); } @@ -287,7 +293,8 @@ mod tests { fn lint_message_kind_type_check_only_labels() { let kind = LintMessageKind::from_flags(false, true); assert_eq!(kind, LintMessageKind::TypeCheckOnly); - assert_eq!(kind.success_label(), "Found no type errors"); + assert_eq!(kind.success_label(false), "Found no type errors"); + assert_eq!(kind.success_label(true), "Found no type errors"); assert_eq!(kind.warning_heading(), "Type warnings found"); assert_eq!(kind.issue_heading(), "Type errors found"); } diff --git a/packages/cli/binding/src/check/mod.rs b/packages/cli/binding/src/check/mod.rs index 42a4543db2..39249516e5 100644 --- a/packages/cli/binding/src/check/mod.rs +++ b/packages/cli/binding/src/check/mod.rs @@ -21,6 +21,7 @@ use crate::cli::{ pub(crate) async fn execute_check( resolver: &SubcommandResolver, fix: bool, + quiet: bool, no_fmt_flag: bool, no_lint_flag: bool, no_error_on_unmatched_pattern: bool, @@ -153,6 +154,9 @@ pub(crate) async fn execute_check( if fix && lint_enabled { args.push("--fix".to_string()); } + if quiet { + args.push("--quiet".to_string()); + } // `vp check` parses oxlint's human-readable summary output to print // unified pass/fail lines. When `GITHUB_ACTIONS=true`, oxlint auto-switches // to the GitHub reporter, which omits that summary on success and makes the @@ -184,7 +188,7 @@ pub(crate) async fn execute_check( Some(Ok(success)) => { let message = format!( "{} in {}", - lint_message_kind.success_label(), + lint_message_kind.success_label(quiet), format_count(success.summary.files, "file", "files"), ); let detail = @@ -197,10 +201,17 @@ pub(crate) async fn execute_check( } } Some(Err(failure)) => { - if failure.errors == 0 && failure.warnings > 0 { - output::warn(lint_message_kind.warning_heading()); - } else { - output::error(lint_message_kind.issue_heading()); + // `--quiet` suppresses warning diagnostics, but oxlint still + // reports warning counts in its summary. Preserve those counts + // so `vp check --quiet` matches `vp lint --quiet` semantics. + let quiet_warning_only = + quiet && failure.errors == 0 && status == ExitStatus::SUCCESS; + if !quiet_warning_only { + if failure.errors == 0 && failure.warnings > 0 { + output::warn(lint_message_kind.warning_heading()); + } else { + output::error(lint_message_kind.issue_heading()); + } } print_stdout_block(&failure.diagnostics); print_summary_line(&format!( diff --git a/packages/cli/binding/src/cli/mod.rs b/packages/cli/binding/src/cli/mod.rs index e370d1eaea..67940d2be6 100644 --- a/packages/cli/binding/src/cli/mod.rs +++ b/packages/cli/binding/src/cli/mod.rs @@ -94,6 +94,7 @@ async fn execute_direct_subcommand( let status = match subcommand { SynthesizableSubcommand::Check { fix, + quiet, no_fmt, no_lint, no_error_on_unmatched_pattern, @@ -102,6 +103,7 @@ async fn execute_direct_subcommand( return crate::check::execute_check( &resolver, fix, + quiet, no_fmt, no_lint, no_error_on_unmatched_pattern, diff --git a/packages/cli/binding/src/cli/types.rs b/packages/cli/binding/src/cli/types.rs index c2fda6c821..7c9f3832ef 100644 --- a/packages/cli/binding/src/cli/types.rs +++ b/packages/cli/binding/src/cli/types.rs @@ -80,6 +80,9 @@ pub enum SynthesizableSubcommand { /// Auto-fix format and lint issues #[arg(long)] fix: bool, + /// Disable reporting on warnings, only errors are reported + #[arg(long)] + quiet: bool, /// Skip format check #[arg(long = "no-fmt")] no_fmt: bool, diff --git a/packages/cli/src/help.ts b/packages/cli/src/help.ts index 1782352953..96398535e6 100644 --- a/packages/cli/src/help.ts +++ b/packages/cli/src/help.ts @@ -803,6 +803,10 @@ const commandHelpDocs = { title: 'Options', rows: [ { label: '--fix', description: 'Auto-fix format and lint issues' }, + { + label: '--quiet', + description: 'Disable reporting on warnings, only errors are reported', + }, { label: '--no-fmt', description: 'Skip format check' }, { label: '--no-lint',