From 058eff3085beeb22d4feb816c02467f95e851ead Mon Sep 17 00:00:00 2001 From: thatrichman Date: Sun, 8 Dec 2024 19:04:19 -0500 Subject: [PATCH] fix: only test for shellcheck once Tests if shellcheck exists and assigns the result to a OnceLock. If shellcheck is not found, adds a diagnostic and returns. --- .../{command_shellcheck.rs => shellcheck.rs} | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) rename wdl-lint/src/rules/{command_shellcheck.rs => shellcheck.rs} (92%) diff --git a/wdl-lint/src/rules/command_shellcheck.rs b/wdl-lint/src/rules/shellcheck.rs similarity index 92% rename from wdl-lint/src/rules/command_shellcheck.rs rename to wdl-lint/src/rules/shellcheck.rs index a4922e6c..d82af7bc 100644 --- a/wdl-lint/src/rules/command_shellcheck.rs +++ b/wdl-lint/src/rules/shellcheck.rs @@ -4,6 +4,7 @@ use std::collections::HashSet; use std::io::Write; use std::process; use std::process::Stdio; +use std::sync::OnceLock; use anyhow::Context; use anyhow::Result; @@ -52,6 +53,9 @@ const SHELLCHECK_SUPPRESS: &[&str] = &[ /// ShellCheck: var is referenced by not assigned. const SHELLCHECK_REFERENCED_UNASSIGNED: usize = 2154; +/// Whether or not shellcheck exists on the system +static SHELLCHECK_EXISTS: OnceLock = OnceLock::new(); + /// The identifier for the command section ShellCheck rule. const ID: &str = "CommandSectionShellCheck"; @@ -228,7 +232,25 @@ impl Visitor for ShellCheckRule { return; } - if !program_exists(SHELLCHECK_BIN) { + if !SHELLCHECK_EXISTS.get_or_init(|| { + if !program_exists(SHELLCHECK_BIN) { + let command_keyword = support::token(section.syntax(), SyntaxKind::CommandKeyword) + .expect("should have a command keyword token"); + state.exceptable_add( + Diagnostic::error("running `shellcheck` on command section") + .with_label( + "could not find `shellcheck` executable.", + command_keyword.text_range().to_span(), + ) + .with_rule(ID) + .with_fix("install shellcheck or disable this lint."), + SyntaxElement::from(section.syntax().clone()), + &self.exceptable_nodes(), + ); + return false; + } + true + }) { return; }