Skip to content

Instantly share code, notes, and snippets.

@jabberabbe
Created January 14, 2019 13:37
Show Gist options
  • Save jabberabbe/123fead56df37761cfcd38571d0e3aae to your computer and use it in GitHub Desktop.
Save jabberabbe/123fead56df37761cfcd38571d0e3aae to your computer and use it in GitHub Desktop.
From a4b9cec9f00ba31e8b48c379296d2bb1d4bb3638 Mon Sep 17 00:00:00 2001
From: Tito Sacchi <[email protected]>
Date: Mon, 14 Jan 2019 14:16:12 +0100
Subject: [PATCH 1/2] Fix #1369 (Use file extension to detect shell)
The precedence order that is used to determine the shell
is the following:
1. ShellCheck directive
2. Shebang
3. File extension
A new field `asFallbackShell` has been
added to the record type `AnalysisSpec`.
---
src/ShellCheck/AnalyzerLib.hs | 10 ++++++----
src/ShellCheck/Checker.hs | 10 ++++++++++
src/ShellCheck/Interface.hs | 4 +++-
3 files changed, 19 insertions(+), 5 deletions(-)
diff --git a/src/ShellCheck/AnalyzerLib.hs b/src/ShellCheck/AnalyzerLib.hs
index 37a96ad..5248d94 100644
--- a/src/ShellCheck/AnalyzerLib.hs
+++ b/src/ShellCheck/AnalyzerLib.hs
@@ -175,7 +175,7 @@ makeCommentWithFix severity id code str fix =
makeParameters spec =
let params = Parameters {
rootNode = root,
- shellType = fromMaybe (determineShell root) $ asShellType spec,
+ shellType = fromMaybe (determineShell (asFallbackShell spec) root) $ asShellType spec,
hasSetE = containsSetE root,
hasLastpipe =
case shellType params of
@@ -227,11 +227,13 @@ prop_determineShell4 = determineShellTest "#!/bin/ksh\n#shellcheck shell=sh\nfoo
prop_determineShell5 = determineShellTest "#shellcheck shell=sh\nfoo" == Sh
prop_determineShell6 = determineShellTest "#! /bin/sh" == Sh
prop_determineShell7 = determineShellTest "#! /bin/ash" == Dash
+prop_determineShell8 = determineShellTest' (Just Ksh) "#!/bin/sh" == Sh
-determineShellTest = determineShell . fromJust . prRoot . pScript
-determineShell t = fromMaybe Bash $ do
+determineShellTest = determineShellTest' Nothing
+determineShellTest' fallbackShell = determineShell fallbackShell . fromJust . prRoot . pScript
+determineShell fallbackShell t = fromMaybe Bash $ do
shellString <- foldl mplus Nothing $ getCandidates t
- shellForExecutable shellString
+ shellForExecutable shellString `mplus` fallbackShell
where
forAnnotation t =
case t of
diff --git a/src/ShellCheck/Checker.hs b/src/ShellCheck/Checker.hs
index 10074e3..67bd1c3 100644
--- a/src/ShellCheck/Checker.hs
+++ b/src/ShellCheck/Checker.hs
@@ -48,6 +48,15 @@ tokenToPosition startMap t = fromMaybe fail $ do
where
fail = error "Internal shellcheck error: id doesn't exist. Please report!"
+shellFromFilename filename = foldl mplus Nothing candidates
+ where
+ shellExtensions = [(".ksh", Ksh)
+ ,(".sh", Sh)
+ ,(".bash", Bash)
+ ,(".dash", Dash)]
+ candidates =
+ map (\(ext,sh) -> if ext `isSuffixOf` filename then Just sh else Nothing) shellExtensions
+
checkScript :: Monad m => SystemInterface m -> CheckSpec -> m CheckResult
checkScript sys spec = do
results <- checkScript (csScript spec)
@@ -69,6 +78,7 @@ checkScript sys spec = do
as {
asScript = root,
asShellType = csShellTypeOverride spec,
+ asFallbackShell = shellFromFilename $ csFilename spec,
asCheckSourced = csCheckSourced spec,
asExecutionMode = Executed,
asTokenPositions = tokenPositions
diff --git a/src/ShellCheck/Interface.hs b/src/ShellCheck/Interface.hs
index dd53f6f..285042f 100644
--- a/src/ShellCheck/Interface.hs
+++ b/src/ShellCheck/Interface.hs
@@ -25,7 +25,7 @@ module ShellCheck.Interface
, CheckResult(crFilename, crComments)
, ParseSpec(psFilename, psScript, psCheckSourced, psShellTypeOverride)
, ParseResult(prComments, prTokenPositions, prRoot)
- , AnalysisSpec(asScript, asShellType, asExecutionMode, asCheckSourced, asTokenPositions)
+ , AnalysisSpec(asScript, asShellType, asFallbackShell, asExecutionMode, asCheckSourced, asTokenPositions)
, AnalysisResult(arComments)
, FormatterOptions(foColorOption, foWikiLinkCount)
, Shell(Ksh, Sh, Bash, Dash)
@@ -138,6 +138,7 @@ newParseResult = ParseResult {
data AnalysisSpec = AnalysisSpec {
asScript :: Token,
asShellType :: Maybe Shell,
+ asFallbackShell :: Maybe Shell,
asExecutionMode :: ExecutionMode,
asCheckSourced :: Bool,
asTokenPositions :: Map.Map Id (Position, Position)
@@ -146,6 +147,7 @@ data AnalysisSpec = AnalysisSpec {
newAnalysisSpec token = AnalysisSpec {
asScript = token,
asShellType = Nothing,
+ asFallbackShell = Nothing,
asExecutionMode = Executed,
asCheckSourced = False,
asTokenPositions = Map.empty
--
2.20.1
From 1e6a30905a986962a6d78ec55609168a724d253a Mon Sep 17 00:00:00 2001
From: Tito Sacchi <[email protected]>
Date: Mon, 14 Jan 2019 14:25:01 +0100
Subject: [PATCH 2/2] Make ShellCheck not emit warnings about the shebang if
the shell type is determined from the extension
---
src/ShellCheck/Analytics.hs | 2 +-
src/ShellCheck/AnalyzerLib.hs | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/ShellCheck/Analytics.hs b/src/ShellCheck/Analytics.hs
index 6230f5b..8f66aaf 100644
--- a/src/ShellCheck/Analytics.hs
+++ b/src/ShellCheck/Analytics.hs
@@ -484,7 +484,7 @@ checkShebang params (T_Annotation _ list t) =
checkShebang params (T_Script id sb _) = execWriter $ do
unless (shellTypeSpecified params) $ do
when (sb == "") $
- err id 2148 "Tips depend on target shell and yours is unknown. Add a shebang."
+ err id 2148 "Tips depend on target shell and yours is unknown. Add a shebang or an extension to the filename."
when (executableFromShebang sb == "ash") $
warn id 2187 "Ash scripts will be checked as Dash. Add '# shellcheck shell=dash' to silence."
unless (null sb) $ do
diff --git a/src/ShellCheck/AnalyzerLib.hs b/src/ShellCheck/AnalyzerLib.hs
index 5248d94..b2b4edd 100644
--- a/src/ShellCheck/AnalyzerLib.hs
+++ b/src/ShellCheck/AnalyzerLib.hs
@@ -184,7 +184,7 @@ makeParameters spec =
Sh -> False
Ksh -> True,
- shellTypeSpecified = isJust $ asShellType spec,
+ shellTypeSpecified = isJust (asShellType spec) || isJust (asFallbackShell spec),
parentMap = getParentTree root,
variableFlow = getVariableFlow params root,
tokenPositions = asTokenPositions spec
--
2.20.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment