Skip to content

Commit

Permalink
Add warning about uninvoked functions, reduce repeated triggering of …
Browse files Browse the repository at this point in the history
…SC2317 (fixes #2966)
  • Loading branch information
koalaman committed May 4, 2024
1 parent 2c5155e commit 4f81dbe
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 3 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
## Git
### Added
- SC2327/SC2328: Warn about capturing the output of redirected commands.
- SC2329: Warn when (non-escaping) functions are never invoked.
### Fixed
- SC2317 about unreachable commands is now less spammy for nested ones.


## v0.10.0 - 2024-03-07
Expand Down
23 changes: 20 additions & 3 deletions src/ShellCheck/Analytics.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4896,16 +4896,33 @@ checkBatsTestDoesNotUseNegation params t =
prop_checkCommandIsUnreachable1 = verify checkCommandIsUnreachable "foo; bar; exit; baz"
prop_checkCommandIsUnreachable2 = verify checkCommandIsUnreachable "die() { exit; }; foo; bar; die; baz"
prop_checkCommandIsUnreachable3 = verifyNot checkCommandIsUnreachable "foo; bar || exit; baz"
prop_checkCommandIsUnreachable4 = verifyNot checkCommandIsUnreachable "f() { foo; }; # Maybe sourced"
prop_checkCommandIsUnreachable5 = verify checkCommandIsUnreachable "f() { foo; }; exit # Not sourced"
checkCommandIsUnreachable params t =
case t of
T_Pipeline {} -> sequence_ $ do
cfga <- cfgAnalysis params
state <- CF.getIncomingState cfga id
state <- CF.getIncomingState cfga (getId t)
guard . not $ CF.stateIsReachable state
guard . not $ isSourced params t
return $ info id 2317 "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
guard . not $ any (\t -> isUnreachable t || isUnreachableFunction t) $ NE.drop 1 $ getPath (parentMap params) t
return $ info (getId t) 2317 "Command appears to be unreachable. Check usage (or ignore if invoked indirectly)."
T_Function id _ _ _ _ ->
when (isUnreachableFunction t
&& (not . any isUnreachableFunction . NE.drop 1 $ getPath (parentMap params) t)
&& (not $ isSourced params t)) $
info id 2329 "This function is never invoked. Check usage (or ignored if invoked indirectly)."
_ -> return ()
where id = getId t
where
isUnreachableFunction :: Token -> Bool
isUnreachableFunction f =
case f of
T_Function id _ _ _ t -> isUnreachable t
_ -> False
isUnreachable t = fromMaybe False $ do
cfga <- cfgAnalysis params
state <- CF.getIncomingState cfga (getId t)
return . not $ CF.stateIsReachable state


prop_checkOverwrittenExitCode1 = verify checkOverwrittenExitCode "x; [ $? -eq 1 ] || [ $? -eq 2 ]"
Expand Down

0 comments on commit 4f81dbe

Please sign in to comment.