diff --git a/CHANGELOG.md b/CHANGELOG.md index ac5e8f2..dfc3506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ - json1 format like --format=json but treats tabs as single characters - Recognize FLAGS variables created by the shflags library. - Site-specific changes can now be made in Custom.hs for ease of patching +- Add portage as a bash-like shell for ebuild/eclass files. - SC2154: Also warn about unassigned uppercase variables (optional) - SC2252: Warn about `[ $a != x ] || [ $a != y ]`, similar to SC2055 - SC2251: Inform about ineffectual ! in front of commands diff --git a/shellcheck.1.md b/shellcheck.1.md index 02175dc..a754609 100644 --- a/shellcheck.1.md +++ b/shellcheck.1.md @@ -87,8 +87,9 @@ not warn at all, as `ksh` supports decimals in arithmetic contexts. : Specify Bourne shell dialect. Valid values are *sh*, *bash*, *dash* and *ksh*. The default is to deduce the shell from the file's `shell` directive, - shebang, or `.bash/.bats/.dash/.ksh` extension, in that order. *sh* refers to - POSIX `sh` (not the system's), and will warn of portability issues. + shebang, or `.bash/.bats/.dash/.ksh/.ebuild/.eclass` extension, in that + order. *sh* refers to POSIX `sh` (not the system's), and will warn of + portability issues. **-S**\ *SEVERITY*,\ **--severity=***severity* diff --git a/src/ShellCheck/AnalyzerLib.hs b/src/ShellCheck/AnalyzerLib.hs index 70b781e..250cf40 100644 --- a/src/ShellCheck/AnalyzerLib.hs +++ b/src/ShellCheck/AnalyzerLib.hs @@ -92,7 +92,9 @@ data Parameters = Parameters { -- The root node of the AST rootNode :: Token, -- map from token id to start and end position - tokenPositions :: Map.Map Id (Position, Position) + tokenPositions :: Map.Map Id (Position, Position), + -- True if script is being used as a portage build file + isPortageBuild :: Bool } deriving (Show) -- TODO: Cache results of common AST ops here @@ -195,7 +197,8 @@ makeParameters spec = shellTypeSpecified = isJust (asShellType spec) || isJust (asFallbackShell spec), parentMap = getParentTree root, variableFlow = getVariableFlow params root, - tokenPositions = asTokenPositions spec + tokenPositions = asTokenPositions spec, + isPortageBuild = asIsPortageBuild spec } in params where root = asScript spec diff --git a/src/ShellCheck/Checker.hs b/src/ShellCheck/Checker.hs index 2ea950d..365e1a2 100644 --- a/src/ShellCheck/Checker.hs +++ b/src/ShellCheck/Checker.hs @@ -53,12 +53,18 @@ shellFromFilename filename = foldl mplus Nothing candidates shellExtensions = [(".ksh", Ksh) ,(".bash", Bash) ,(".bats", Bash) - ,(".dash", Dash)] + ,(".dash", Dash) + ,(".ebuild", Bash) + ,(".eclass", Bash)] -- The `.sh` is too generic to determine the shell: -- We fallback to Bash in this case and emit SC2148 if there is no shebang candidates = map (\(ext,sh) -> if ext `isSuffixOf` filename then Just sh else Nothing) shellExtensions +isPortageBuildFile filename = any (\x -> isSuffixOf x filename) portageExtensions + where + portageExtensions = [".ebuild", ".eclass"] + checkScript :: Monad m => SystemInterface m -> CheckSpec -> m CheckResult checkScript sys spec = do results <- checkScript (csScript spec) @@ -85,7 +91,8 @@ checkScript sys spec = do asCheckSourced = csCheckSourced spec, asExecutionMode = Executed, asTokenPositions = tokenPositions, - asOptionalChecks = csOptionalChecks spec + asOptionalChecks = csOptionalChecks spec, + asIsPortageBuild = isPortageBuildFile $ csFilename spec } where as = newAnalysisSpec root let analysisMessages = fromMaybe [] $ diff --git a/src/ShellCheck/Interface.hs b/src/ShellCheck/Interface.hs index aa12fc2..fc79823 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, psIgnoreRC, psShellTypeOverride) , ParseResult(prComments, prTokenPositions, prRoot) - , AnalysisSpec(asScript, asShellType, asFallbackShell, asExecutionMode, asCheckSourced, asTokenPositions, asOptionalChecks) + , AnalysisSpec(asScript, asShellType, asFallbackShell, asExecutionMode, asCheckSourced, asTokenPositions, asOptionalChecks, asIsPortageBuild) , AnalysisResult(arComments) , FormatterOptions(foColorOption, foWikiLinkCount) , Shell(Ksh, Sh, Bash, Dash) @@ -161,7 +161,8 @@ data AnalysisSpec = AnalysisSpec { asExecutionMode :: ExecutionMode, asCheckSourced :: Bool, asOptionalChecks :: [String], - asTokenPositions :: Map.Map Id (Position, Position) + asTokenPositions :: Map.Map Id (Position, Position), + asIsPortageBuild :: Bool } newAnalysisSpec token = AnalysisSpec { @@ -171,7 +172,8 @@ newAnalysisSpec token = AnalysisSpec { asExecutionMode = Executed, asCheckSourced = False, asOptionalChecks = [], - asTokenPositions = Map.empty + asTokenPositions = Map.empty, + asIsPortageBuild = False } newtype AnalysisResult = AnalysisResult {