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

Change default behavior for missing output #1478

Merged
merged 5 commits into from
Feb 5, 2025
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
77 changes: 39 additions & 38 deletions qlty-check/src/executor/invocation_result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use anyhow::{Context, Result};
use chrono::prelude::*;
use qlty_analysis::utils::fs::path_to_string;
use qlty_config::{
config::{OutputDestination, TargetType},
config::{OutputDestination, OutputMissing, TargetType},
version::QLTY_VERSION,
};
use qlty_types::analysis::v1::{
Expand Down Expand Up @@ -273,20 +273,7 @@ impl InvocationResult {
let tmpfile_path = self.invocation.tmpfile_path.as_ref().unwrap();
let read_result = std::fs::read_to_string(tmpfile_path)
.with_context(|| format!("Failed to read tmpfile contents from {}", tmpfile_path));

match read_result {
Ok(contents) => {
self.invocation.tmpfile_contents = Some(contents);
}
Err(e) => {
if self.plan.driver.missing_output_as_error {
self.invocation.tmpfile_contents = Some("".to_string());
} else {
self.invocation.parser_error = Some(e.to_string());
}
}
}

self.invocation.tmpfile_contents = read_result.ok();
Ok(())
}

Expand Down Expand Up @@ -320,37 +307,51 @@ impl InvocationResult {
}

fn handle_output_parsing(&mut self) -> Result<()> {
// If we have something to attempt to parse (which we don't if the tmpfile doesn't exist)
if !self.plan.uses_tmpfile() || self.invocation.tmpfile_contents.is_some() {
let output = if self.plan.uses_tmpfile() {
self.invocation.tmpfile_contents.as_ref().unwrap()
} else if self.plan.driver.output == OutputDestination::Stderr {
&self.invocation.stderr
} else {
&self.invocation.stdout
};

if output.is_empty() && self.plan.driver.missing_output_as_error {
self.invocation.exit_result =
qlty_types::analysis::v1::ExitResult::UnknownError.into();
self.log_error_output();
} else {
let file_results = self.plan.driver.parse(output, &self.plan);
let output = if self.plan.uses_tmpfile() {
self.invocation
.tmpfile_contents
.as_ref()
.unwrap_or(&String::new())
.to_owned()
} else if self.plan.driver.output == OutputDestination::Stderr {
self.invocation.stderr.to_owned()
} else {
self.invocation.stdout.to_owned()
};

match file_results {
Ok(file_results) => {
self.file_results = Some(file_results);
}
Err(e) => {
self.invocation.parser_error = Some(e.to_string());
}
if output.is_empty() {
match self.plan.driver.output_missing {
OutputMissing::Error => {
self.invocation.exit_result =
qlty_types::analysis::v1::ExitResult::UnknownError.into();
self.log_error_output();
}
OutputMissing::NoIssues => {
self.invocation.exit_result =
qlty_types::analysis::v1::ExitResult::NoIssues.into();
}
OutputMissing::Parse => self.parse_output(output),
}
} else {
self.parse_output(output);
}

Ok(())
}

fn parse_output(&mut self, output: String) {
let file_results = self.plan.driver.parse(&output, &self.plan);

match file_results {
Ok(file_results) => {
self.file_results = Some(file_results);
}
Err(e) => {
self.invocation.parser_error = Some(e.to_string());
}
}
}

fn create_file_result_for_autofmts(&self) -> Result<Vec<FileResult>> {
let mut file_results: Vec<FileResult> = Vec::new();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ prepare_script = "mkdir ${linter} && echo dir %2 > ${linter}/ls.cmd || echo dir
script = "echo \"The plugin crashed for some reason\""
success_codes = [0]
output = "tmpfile"
missing_output_as_error = true

[[plugin]]
name = "exists"
Expand Down
4 changes: 2 additions & 2 deletions qlty-config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ pub use language::Language;
pub use plugin::{
CheckTrigger, DriverBatchBy, DriverDef, DriverType, EnabledPlugin, ExtraPackage,
InvocationDirectoryDef, InvocationDirectoryType, IssueMode, OutputDestination, OutputFormat,
PackageFileCandidate, Platform, PluginDef, PluginEnvironment, PluginFetch, Runtime,
SuggestionMode, TargetDef, TargetType,
OutputMissing, PackageFileCandidate, Platform, PluginDef, PluginEnvironment, PluginFetch,
Runtime, SuggestionMode, TargetDef, TargetType,
};
pub use release::ReleaseDef;
pub use source::SourceDef;
Expand Down
23 changes: 20 additions & 3 deletions qlty-config/src/config/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ pub struct DriverDef {

#[serde(default)]
pub output_format: OutputFormat,

#[serde(default)]
pub output_missing: OutputMissing,

pub output_regex: Option<String>,

#[serde(default)]
Expand Down Expand Up @@ -111,9 +115,6 @@ pub struct DriverDef {

#[serde(default)]
pub autoload_script: Option<String>,

#[serde(default)]
pub missing_output_as_error: bool,
}

fn default_driver_timeout() -> u64 {
Expand All @@ -124,6 +125,22 @@ fn default_max_batch() -> usize {
64
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Default, JsonSchema)]
pub enum OutputMissing {
/// Raise an error if the output is missing
#[default]
#[serde(rename = "error")]
Error,

/// Interpret no output as no issues
#[serde(rename = "no_issues")]
NoIssues,

/// Hand the empty output to the parser for processing
#[serde(rename = "parse")]
Parse,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Hash, Default, JsonSchema)]
pub enum DriverBatchBy {
#[default]
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/actionlint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ output_format = "actionlint"
cache_results = true
batch = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/bandit/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ output_format = "bandit"
cache_results = true
batch = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/biome/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ output_format = "biome"
batch = true
cache_results = true
suggested = "config"
output_missing = "parse"

[plugins.definitions.biome.drivers.format]
script = "biome format --write ${target}"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/brakeman/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ success_codes = [0, 1, 3]
output = "stdout"
output_format = "sarif"
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/checkov/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,4 @@ output_level = "medium"
batch = false
cache_results = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/clippy/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ success_codes = [0, 101, 383]
output = "stdout"
output_format = "clippy"
suggested = "targets"
output_missing = "parse"

[[plugins.definitions.clippy.environment]]
name = "PATH"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/coffeelint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,4 @@ output_format = "coffeelint"
batch = true
cache_results = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/dotenv-linter/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ known_good_version = "3.3.0"
version_command = "dotenv-linter --version"
description = "Dotenv file linter"
suggested = "targets"
output_missing = "parse"

[plugins.definitions.dotenv-linter.drivers.format]
script = "dotenv-linter fix --quiet ${target}"
Expand Down
1 change: 0 additions & 1 deletion qlty-plugins/plugins/linters/eslint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,3 @@ batch = true
cache_results = true
max_batch = 40
known_good_version = "4.19.1"
missing_output_as_error = true
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/flake8/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ output_regex = "((?P<path>.*):(?P<line>-?\\d+):(?P<col>-?\\d+): (?P<code>\\S+) (
cache_results = true
batch = true
suggested = "config"
output_missing = "parse"

# TODO: run_linter_from: parent_directory
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/gitleaks/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ output_level = "high"
cache_results = true
batch = false
suggested = "config"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/golangci-lint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ success_codes = [0, 2, 7]
output = "stdout"
output_format = "golangci_lint"
suggested = "targets"
output_missing = "parse"

[[plugins.definitions.golangci-lint.environment]]
name = "PATH"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/hadolint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ output_format = "hadolint"
cache_results = true
batch = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/knip/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ success_codes = [0, 1]
output = "stdout"
output_format = "knip"
skip_upstream = true
output_missing = "parse"
3 changes: 1 addition & 2 deletions qlty-plugins/plugins/linters/kube-linter/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,4 @@ output = "stdout"
output_format = "sarif"
output_category = "vulnerability"
output_level = "medium"
missing_output_as_error = true
target = { type = "literal", path = "." }
target = { type = "literal", path = "." }
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`linter=markdownlint fixture=no_issues version=0.41.0 1`] = `
{
"issues": [],
}
`;
Empty file.
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/markdownlint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ driver_type = "linter"
output = "stderr"
output_format = "markdownlint"
suggested = "targets"
output_missing = "parse"

[plugins.definitions.markdownlint.drivers.format]
script = "markdownlint --fix ${target}"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/mypy/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ output_format = "mypy"
cache_results = true
batch = true
suggested = "config"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/osv-scanner/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,4 @@ cache_results = true
batch = false
skip_upstream = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/oxc/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ output_regex = "::(?P<severity>[^ ]+) file=(?P<path>[^,]+),line=(?P<line>\\d+),e
batch = true
cache_results = true
max_batch = 40
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/php-codesniffer/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ output_format = "php_codesniffer"
cache_results = true
batch = true
suggested = "targets"
output_missing = "parse"

[[plugins.definitions.php-codesniffer.environment]]
name = "PHP_INI_SCAN_DIR"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/phpstan/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ output_format = "phpstan"
cache_results = true
batch = true
suggested = "targets"
output_missing = "parse"
2 changes: 2 additions & 0 deletions qlty-plugins/plugins/linters/pmd/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ output = "stdout"
output_format = "sarif"
file_types = ["java"]
batch = true
output_missing = "parse"

[plugins.definitions.pmd.drivers.lint-apex]
script = "pmd check --rulesets rulesets/apex/quickstart.xml --format sarif --dir ${target}"
Expand All @@ -25,3 +26,4 @@ output = "stdout"
output_format = "sarif"
file_types = ["apex"]
batch = true
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/radarlint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ script = "java -jar ${linter}/radarlint.jar ${target}"
success_codes = [0]
output = "stdout"
output_format = "radarlint"
output_missing = "parse"
batch = true
cache_results = true
suggested = "targets"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/redocly/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ output_format = "regex"
output_regex = "::(?P<severity>[^ ]+) title=(?P<code>[^,]+),file=(?P<path>[^,]+),line=(?P<line>\\d+),col=(?P<col>\\d+),endLine=(?P<end_line>\\d+),endColumn=(?P<end_col>\\d+)::(?P<message>.+)"
cache_results = true
suggested = "targets"
output_missing = "parse"
3 changes: 2 additions & 1 deletion qlty-plugins/plugins/linters/reek/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ output = "stdout"
output_format = "reek"
batch = true
cache_results = true
suggested = "targets"
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/ripgrep/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,3 +48,4 @@ output_format = "ripgrep"
batch = true
cache_results = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/rubocop/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ output_format = "rubocop"
batch = true
cache_results = true
suggested = "targets"
output_missing = "parse"

[plugins.definitions.rubocop.drivers.format]
script = "rubocop --fix-layout ${target}"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/ruff/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ output = "tmpfile"
output_format = "ruff"
batch = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/semgrep/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ output_format = "sarif"
cache_results = true
batch = true
suggested = "config"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/shellcheck/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ output = "stdout"
output_format = "shellcheck"
cache_results = true
suggested = "targets"
output_missing = "parse"
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/sqlfluff/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ success_codes = [0]
output = "stdout"
output_format = "sqlfluff"
batch = true
output_missing = "parse"

[plugins.definitions.sqlfluff.drivers.fix]
script = "sqlfluff fix --disable-progress-bar --quiet --dialect ansi ${target}"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/standardrb/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ output_format = "rubocop"
batch = true
cache_results = true
suggested = "config"
output_missing = "parse"

[plugins.definitions.standardrb.drivers.format]
script = "standardrb ${target} --fix"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/stylelint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ cache_results = true
batch = true
max_batch = 100
suggested = "config"
output_missing = "parse"

[plugins.definitions.stylelint.drivers.format]
script = "stylelint --fix ${target}"
Expand Down
1 change: 1 addition & 0 deletions qlty-plugins/plugins/linters/swiftlint/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ batch = true
cache_results = true
output_category = "style"
suggested = "never"
output_missing = "parse"
Loading
Loading