Improve detection of for loops with single values
This commit is contained in:
parent
d28c8f883f
commit
a57f6d2886
|
@ -11,6 +11,7 @@
|
||||||
- SC2255: Suggest using `$((..))` in `[ 2*3 -eq 6 ]`
|
- SC2255: Suggest using `$((..))` in `[ 2*3 -eq 6 ]`
|
||||||
- SC2256: Warn about translated strings that are known variables
|
- SC2256: Warn about translated strings that are known variables
|
||||||
- SC2257: Warn about arithmetic mutation in redirections
|
- SC2257: Warn about arithmetic mutation in redirections
|
||||||
|
- SC2258: Warn about trailing commas in for loop elements
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- SC2230: 'command -v' suggestion is now off by default (-i deprecate-which)
|
- SC2230: 'command -v' suggestion is now off by default (-i deprecate-which)
|
||||||
|
|
|
@ -47,6 +47,7 @@ willSplit x =
|
||||||
T_BraceExpansion {} -> True
|
T_BraceExpansion {} -> True
|
||||||
T_Glob {} -> True
|
T_Glob {} -> True
|
||||||
T_Extglob {} -> True
|
T_Extglob {} -> True
|
||||||
|
T_DoubleQuoted _ l -> any willBecomeMultipleArgs l
|
||||||
T_NormalWord _ l -> any willSplit l
|
T_NormalWord _ l -> any willSplit l
|
||||||
_ -> False
|
_ -> False
|
||||||
|
|
||||||
|
|
|
@ -578,16 +578,30 @@ prop_checkForInQuoted4 = verify checkForInQuoted "for f in 1,2,3; do true; done"
|
||||||
prop_checkForInQuoted4a = verifyNot checkForInQuoted "for f in foo{1,2,3}; do true; done"
|
prop_checkForInQuoted4a = verifyNot checkForInQuoted "for f in foo{1,2,3}; do true; done"
|
||||||
prop_checkForInQuoted5 = verify checkForInQuoted "for f in ls; do true; done"
|
prop_checkForInQuoted5 = verify checkForInQuoted "for f in ls; do true; done"
|
||||||
prop_checkForInQuoted6 = verifyNot checkForInQuoted "for f in \"${!arr}\"; do true; done"
|
prop_checkForInQuoted6 = verifyNot checkForInQuoted "for f in \"${!arr}\"; do true; done"
|
||||||
|
prop_checkForInQuoted7 = verify checkForInQuoted "for f in ls, grep, mv; do true; done"
|
||||||
|
prop_checkForInQuoted8 = verify checkForInQuoted "for f in 'ls', 'grep', 'mv'; do true; done"
|
||||||
|
prop_checkForInQuoted9 = verifyNot checkForInQuoted "for f in 'ls,' 'grep,' 'mv'; do true; done"
|
||||||
checkForInQuoted _ (T_ForIn _ f [T_NormalWord _ [word@(T_DoubleQuoted id list)]] _)
|
checkForInQuoted _ (T_ForIn _ f [T_NormalWord _ [word@(T_DoubleQuoted id list)]] _)
|
||||||
| any (\x -> willSplit x && not (mayBecomeMultipleArgs x)) list
|
| any (\x -> willSplit x && not (mayBecomeMultipleArgs x)) list
|
||||||
|| (fmap wouldHaveBeenGlob (getLiteralString word) == Just True) =
|
|| (fmap wouldHaveBeenGlob (getLiteralString word) == Just True) =
|
||||||
err id 2066 "Since you double quoted this, it will not word split, and the loop will only run once."
|
err id 2066 "Since you double quoted this, it will not word split, and the loop will only run once."
|
||||||
checkForInQuoted _ (T_ForIn _ f [T_NormalWord _ [T_SingleQuoted id _]] _) =
|
checkForInQuoted _ (T_ForIn _ f [T_NormalWord _ [T_SingleQuoted id _]] _) =
|
||||||
warn id 2041 "This is a literal string. To run as a command, use $(..) instead of '..' . "
|
warn id 2041 "This is a literal string. To run as a command, use $(..) instead of '..' . "
|
||||||
checkForInQuoted _ (T_ForIn _ f [T_NormalWord _ [T_Literal id s]] _) =
|
checkForInQuoted _ (T_ForIn _ _ [single] _) | fromMaybe False $ fmap (',' `elem`) $ getUnquotedLiteral single =
|
||||||
if ',' `elem` s && '{' `notElem` s
|
warn (getId single) 2042 "Use spaces, not commas, to separate loop elements."
|
||||||
then warn id 2042 "Use spaces, not commas, to separate loop elements."
|
checkForInQuoted _ (T_ForIn _ _ [single] _) | not (willSplit single) && not (mayBecomeMultipleArgs single) =
|
||||||
else warn id 2043 "This loop will only ever run once for a constant value. Did you perhaps mean to loop over dir/*, $var or $(cmd)?"
|
warn (getId single) 2043 "This loop will only ever run once. Bad quoting or missing glob/expansion?"
|
||||||
|
checkForInQuoted params (T_ForIn _ _ multiple _) =
|
||||||
|
mapM_ f multiple
|
||||||
|
where
|
||||||
|
f arg = sequence_ $ do
|
||||||
|
suffix <- getTrailingUnquotedLiteral arg
|
||||||
|
string <- getLiteralString suffix
|
||||||
|
guard $ "," `isSuffixOf` string
|
||||||
|
return $
|
||||||
|
warnWithFix (getId arg) 2258
|
||||||
|
"The trailing comma is part of the value, not a separator. Delete or quote it."
|
||||||
|
(fixWith [replaceEnd (getId suffix) params 1 ""])
|
||||||
checkForInQuoted _ _ = return ()
|
checkForInQuoted _ _ = return ()
|
||||||
|
|
||||||
prop_checkForInCat1 = verify checkForInCat "for f in $(cat foo); do stuff; done"
|
prop_checkForInCat1 = verify checkForInCat "for f in $(cat foo); do stuff; done"
|
||||||
|
@ -1011,8 +1025,9 @@ prop_checkUnquotedN2 = verify checkUnquotedN "[ -n $cow ]"
|
||||||
prop_checkUnquotedN3 = verifyNot checkUnquotedN "[[ -n $foo ]] && echo cow"
|
prop_checkUnquotedN3 = verifyNot checkUnquotedN "[[ -n $foo ]] && echo cow"
|
||||||
prop_checkUnquotedN4 = verify checkUnquotedN "[ -n $cow -o -t 1 ]"
|
prop_checkUnquotedN4 = verify checkUnquotedN "[ -n $cow -o -t 1 ]"
|
||||||
prop_checkUnquotedN5 = verifyNot checkUnquotedN "[ -n \"$@\" ]"
|
prop_checkUnquotedN5 = verifyNot checkUnquotedN "[ -n \"$@\" ]"
|
||||||
checkUnquotedN _ (TC_Unary _ SingleBracket "-n" (T_NormalWord id [t])) | willSplit t =
|
checkUnquotedN _ (TC_Unary _ SingleBracket "-n" t) | willSplit t =
|
||||||
err id 2070 "-n doesn't work with unquoted arguments. Quote or use [[ ]]."
|
unless (any isArrayExpansion $ getWordParts t) $ -- There's SC2198 for these
|
||||||
|
err (getId t) 2070 "-n doesn't work with unquoted arguments. Quote or use [[ ]]."
|
||||||
checkUnquotedN _ _ = return ()
|
checkUnquotedN _ _ = return ()
|
||||||
|
|
||||||
prop_checkNumberComparisons1 = verify checkNumberComparisons "[[ $foo < 3 ]]"
|
prop_checkNumberComparisons1 = verify checkNumberComparisons "[[ $foo < 3 ]]"
|
||||||
|
|
Loading…
Reference in New Issue