mirror of
https://github.com/koalaman/shellcheck
synced 2025-08-24 15:15:42 -07:00
Initial support for portage
Portage (Gentoo's package manager) packages are made up of ebuild and eclass files. These are essentially bash scripts with a bunch of predefined functions, global variables, and some external semantics (e.g. "inherit" is a wrapper around "source" that incorporates an expected filesystem layout). Add automatic detection of portage by mapping .ebuild and .eclass files to bash with an extra Parameters flag that indicates they're a portage build file. This leaves all the bash checks as they are, but allows additional tweaks to be made for "portage mode". No actual checks are added here; subsequent changes will add portage-specific behavior.
This commit is contained in:
parent
c175971bf0
commit
f6e4bc828f
5 changed files with 23 additions and 9 deletions
|
@ -16,6 +16,7 @@
|
||||||
- json1 format like --format=json but treats tabs as single characters
|
- json1 format like --format=json but treats tabs as single characters
|
||||||
- Recognize FLAGS variables created by the shflags library.
|
- Recognize FLAGS variables created by the shflags library.
|
||||||
- Site-specific changes can now be made in Custom.hs for ease of patching
|
- 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)
|
- SC2154: Also warn about unassigned uppercase variables (optional)
|
||||||
- SC2252: Warn about `[ $a != x ] || [ $a != y ]`, similar to SC2055
|
- SC2252: Warn about `[ $a != x ] || [ $a != y ]`, similar to SC2055
|
||||||
- SC2251: Inform about ineffectual ! in front of commands
|
- SC2251: Inform about ineffectual ! in front of commands
|
||||||
|
|
|
@ -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*.
|
: 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,
|
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
|
shebang, or `.bash/.bats/.dash/.ksh/.ebuild/.eclass` extension, in that
|
||||||
POSIX `sh` (not the system's), and will warn of portability issues.
|
order. *sh* refers to POSIX `sh` (not the system's), and will warn of
|
||||||
|
portability issues.
|
||||||
|
|
||||||
**-S**\ *SEVERITY*,\ **--severity=***severity*
|
**-S**\ *SEVERITY*,\ **--severity=***severity*
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,9 @@ data Parameters = Parameters {
|
||||||
-- The root node of the AST
|
-- The root node of the AST
|
||||||
rootNode :: Token,
|
rootNode :: Token,
|
||||||
-- map from token id to start and end position
|
-- 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)
|
} deriving (Show)
|
||||||
|
|
||||||
-- TODO: Cache results of common AST ops here
|
-- TODO: Cache results of common AST ops here
|
||||||
|
@ -195,7 +197,8 @@ makeParameters spec =
|
||||||
shellTypeSpecified = isJust (asShellType spec) || isJust (asFallbackShell spec),
|
shellTypeSpecified = isJust (asShellType spec) || isJust (asFallbackShell spec),
|
||||||
parentMap = getParentTree root,
|
parentMap = getParentTree root,
|
||||||
variableFlow = getVariableFlow params root,
|
variableFlow = getVariableFlow params root,
|
||||||
tokenPositions = asTokenPositions spec
|
tokenPositions = asTokenPositions spec,
|
||||||
|
isPortageBuild = asIsPortageBuild spec
|
||||||
} in params
|
} in params
|
||||||
where root = asScript spec
|
where root = asScript spec
|
||||||
|
|
||||||
|
|
|
@ -53,12 +53,18 @@ shellFromFilename filename = foldl mplus Nothing candidates
|
||||||
shellExtensions = [(".ksh", Ksh)
|
shellExtensions = [(".ksh", Ksh)
|
||||||
,(".bash", Bash)
|
,(".bash", Bash)
|
||||||
,(".bats", Bash)
|
,(".bats", Bash)
|
||||||
,(".dash", Dash)]
|
,(".dash", Dash)
|
||||||
|
,(".ebuild", Bash)
|
||||||
|
,(".eclass", Bash)]
|
||||||
-- The `.sh` is too generic to determine the shell:
|
-- The `.sh` is too generic to determine the shell:
|
||||||
-- We fallback to Bash in this case and emit SC2148 if there is no shebang
|
-- We fallback to Bash in this case and emit SC2148 if there is no shebang
|
||||||
candidates =
|
candidates =
|
||||||
map (\(ext,sh) -> if ext `isSuffixOf` filename then Just sh else Nothing) shellExtensions
|
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 :: Monad m => SystemInterface m -> CheckSpec -> m CheckResult
|
||||||
checkScript sys spec = do
|
checkScript sys spec = do
|
||||||
results <- checkScript (csScript spec)
|
results <- checkScript (csScript spec)
|
||||||
|
@ -85,7 +91,8 @@ checkScript sys spec = do
|
||||||
asCheckSourced = csCheckSourced spec,
|
asCheckSourced = csCheckSourced spec,
|
||||||
asExecutionMode = Executed,
|
asExecutionMode = Executed,
|
||||||
asTokenPositions = tokenPositions,
|
asTokenPositions = tokenPositions,
|
||||||
asOptionalChecks = csOptionalChecks spec
|
asOptionalChecks = csOptionalChecks spec,
|
||||||
|
asIsPortageBuild = isPortageBuildFile $ csFilename spec
|
||||||
} where as = newAnalysisSpec root
|
} where as = newAnalysisSpec root
|
||||||
let analysisMessages =
|
let analysisMessages =
|
||||||
fromMaybe [] $
|
fromMaybe [] $
|
||||||
|
|
|
@ -25,7 +25,7 @@ module ShellCheck.Interface
|
||||||
, CheckResult(crFilename, crComments)
|
, CheckResult(crFilename, crComments)
|
||||||
, ParseSpec(psFilename, psScript, psCheckSourced, psIgnoreRC, psShellTypeOverride)
|
, ParseSpec(psFilename, psScript, psCheckSourced, psIgnoreRC, psShellTypeOverride)
|
||||||
, ParseResult(prComments, prTokenPositions, prRoot)
|
, ParseResult(prComments, prTokenPositions, prRoot)
|
||||||
, AnalysisSpec(asScript, asShellType, asFallbackShell, asExecutionMode, asCheckSourced, asTokenPositions, asOptionalChecks)
|
, AnalysisSpec(asScript, asShellType, asFallbackShell, asExecutionMode, asCheckSourced, asTokenPositions, asOptionalChecks, asIsPortageBuild)
|
||||||
, AnalysisResult(arComments)
|
, AnalysisResult(arComments)
|
||||||
, FormatterOptions(foColorOption, foWikiLinkCount)
|
, FormatterOptions(foColorOption, foWikiLinkCount)
|
||||||
, Shell(Ksh, Sh, Bash, Dash)
|
, Shell(Ksh, Sh, Bash, Dash)
|
||||||
|
@ -161,7 +161,8 @@ data AnalysisSpec = AnalysisSpec {
|
||||||
asExecutionMode :: ExecutionMode,
|
asExecutionMode :: ExecutionMode,
|
||||||
asCheckSourced :: Bool,
|
asCheckSourced :: Bool,
|
||||||
asOptionalChecks :: [String],
|
asOptionalChecks :: [String],
|
||||||
asTokenPositions :: Map.Map Id (Position, Position)
|
asTokenPositions :: Map.Map Id (Position, Position),
|
||||||
|
asIsPortageBuild :: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
newAnalysisSpec token = AnalysisSpec {
|
newAnalysisSpec token = AnalysisSpec {
|
||||||
|
@ -171,7 +172,8 @@ newAnalysisSpec token = AnalysisSpec {
|
||||||
asExecutionMode = Executed,
|
asExecutionMode = Executed,
|
||||||
asCheckSourced = False,
|
asCheckSourced = False,
|
||||||
asOptionalChecks = [],
|
asOptionalChecks = [],
|
||||||
asTokenPositions = Map.empty
|
asTokenPositions = Map.empty,
|
||||||
|
asIsPortageBuild = False
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype AnalysisResult = AnalysisResult {
|
newtype AnalysisResult = AnalysisResult {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue