hadolint-2.0.0: src/Hadolint/Rule/Shellcheck.hs
module Hadolint.Rule.Shellcheck (rule) where
import qualified Data.Set as Set
import qualified Data.Text as Text
import Hadolint.Rule
import Hadolint.Shell (ParsedShell)
import qualified Hadolint.Shell as Shell
import Language.Docker.Syntax
import qualified ShellCheck.Interface
rule :: Rule ParsedShell
rule = customRule check (emptyState Shell.defaultShellOpts)
where
check _ st (From _) = st |> replaceWith Shell.defaultShellOpts -- Reset the state
check _ st (Arg name _) = st |> modify (Shell.addVars [name])
check _ st (Env pairs) = st |> modify (Shell.addVars (map fst pairs))
check _ st (Shell args) = st |> modify (Shell.setShell (foldArguments Shell.original args))
check line st (Run (RunArgs args _)) = getFailures |> foldr addFail st
where
getFailures = foldArguments (runShellCheck (state st)) args
runShellCheck opts script = Set.fromList [toFailure line c | c <- Shell.shellcheck opts script]
check _ st _ = st
{-# INLINEABLE rule #-}
-- | Converts ShellCheck errors into our own errors type
toFailure :: Linenumber -> ShellCheck.Interface.PositionedComment -> CheckFailure
toFailure line c =
CheckFailure
{ code = RuleCode $ Text.pack ("SC" ++ show (code c)),
severity = getDLSeverity $ severity c,
message = Text.pack (message c),
line = line
}
where
getDLSeverity :: ShellCheck.Interface.Severity -> DLSeverity
getDLSeverity s =
case s of
ShellCheck.Interface.WarningC -> DLWarningC
ShellCheck.Interface.InfoC -> DLInfoC
ShellCheck.Interface.StyleC -> DLStyleC
_ -> DLErrorC
severity pc = ShellCheck.Interface.cSeverity $ ShellCheck.Interface.pcComment pc
code pc = ShellCheck.Interface.cCode $ ShellCheck.Interface.pcComment pc
message pc = ShellCheck.Interface.cMessage $ ShellCheck.Interface.pcComment pc