Warn about cp/mv/ln with a single argument. Fixes #1080.
This commit is contained in:
parent
31d6b063d9
commit
2d5ed23ca1
|
@ -112,6 +112,7 @@ getFlagsUntil stopCondition (T_SimpleCommand _ _ (_:args)) =
|
||||||
getFlagsUntil _ _ = error "Internal shellcheck error, please report! (getFlags on non-command)"
|
getFlagsUntil _ _ = error "Internal shellcheck error, please report! (getFlags on non-command)"
|
||||||
|
|
||||||
-- Get all flags in a GNU way, up until --
|
-- Get all flags in a GNU way, up until --
|
||||||
|
getAllFlags :: Token -> [(Token, String)]
|
||||||
getAllFlags = getFlagsUntil (== "--")
|
getAllFlags = getFlagsUntil (== "--")
|
||||||
-- Get all flags in a BSD way, up until first non-flag argument or --
|
-- Get all flags in a BSD way, up until first non-flag argument or --
|
||||||
getLeadingFlags = getFlagsUntil (\x -> x == "--" || (not $ "-" `isPrefixOf` x))
|
getLeadingFlags = getFlagsUntil (\x -> x == "--" || (not $ "-" `isPrefixOf` x))
|
||||||
|
|
|
@ -845,6 +845,7 @@ prop_checkUnquotedN = verify checkUnquotedN "if [ -n $foo ]; then echo cow; fi"
|
||||||
prop_checkUnquotedN2 = verify checkUnquotedN "[ -n $cow ]"
|
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 \"$@\" ]"
|
||||||
checkUnquotedN _ (TC_Unary _ SingleBracket "-n" (T_NormalWord id [t])) | willSplit t =
|
checkUnquotedN _ (TC_Unary _ SingleBracket "-n" (T_NormalWord id [t])) | willSplit t =
|
||||||
err id 2070 "-n doesn't work with unquoted arguments. Quote or use [[ ]]."
|
err id 2070 "-n doesn't work with unquoted arguments. Quote or use [[ ]]."
|
||||||
checkUnquotedN _ _ = return ()
|
checkUnquotedN _ _ = return ()
|
||||||
|
|
|
@ -88,6 +88,7 @@ commandChecks = [
|
||||||
,checkWhileGetoptsCase
|
,checkWhileGetoptsCase
|
||||||
,checkCatastrophicRm
|
,checkCatastrophicRm
|
||||||
,checkLetUsage
|
,checkLetUsage
|
||||||
|
,checkMvArguments, checkCpArguments, checkLnArguments
|
||||||
]
|
]
|
||||||
|
|
||||||
buildCommandMap :: [CommandCheck] -> Map.Map CommandName (Token -> Analysis)
|
buildCommandMap :: [CommandCheck] -> Map.Map CommandName (Token -> Analysis)
|
||||||
|
@ -850,5 +851,41 @@ checkLetUsage = CommandCheck (Exactly "let") f
|
||||||
f t = whenShell [Bash,Ksh] $ do
|
f t = whenShell [Bash,Ksh] $ do
|
||||||
style (getId t) 2219 $ "Instead of 'let expr', prefer (( expr )) ."
|
style (getId t) 2219 $ "Instead of 'let expr', prefer (( expr )) ."
|
||||||
|
|
||||||
|
|
||||||
|
missingDestination handler token = do
|
||||||
|
case params of
|
||||||
|
[single] -> do
|
||||||
|
unless (hasTarget || mayBecomeMultipleArgs single) $
|
||||||
|
handler token
|
||||||
|
_ -> return ()
|
||||||
|
where
|
||||||
|
args = getAllFlags token
|
||||||
|
params = map fst $ filter (\(_,x) -> x == "") args
|
||||||
|
hasTarget =
|
||||||
|
any (\x -> x /= "" && x `isPrefixOf` "target-directory") $
|
||||||
|
map snd args
|
||||||
|
|
||||||
|
prop_checkMvArguments1 = verify checkMvArguments "mv 'foo bar'"
|
||||||
|
prop_checkMvArguments2 = verifyNot checkMvArguments "mv foo bar"
|
||||||
|
prop_checkMvArguments3 = verifyNot checkMvArguments "mv 'foo bar'{,bak}"
|
||||||
|
prop_checkMvArguments4 = verifyNot checkMvArguments "mv \"$@\""
|
||||||
|
prop_checkMvArguments5 = verifyNot checkMvArguments "mv -t foo bar"
|
||||||
|
prop_checkMvArguments6 = verifyNot checkMvArguments "mv --target-directory=foo bar"
|
||||||
|
prop_checkMvArguments7 = verifyNot checkMvArguments "mv --target-direc=foo bar"
|
||||||
|
prop_checkMvArguments8 = verifyNot checkMvArguments "mv --version"
|
||||||
|
prop_checkMvArguments9 = verifyNot checkMvArguments "mv \"${!var}\""
|
||||||
|
checkMvArguments = CommandCheck (Basename "mv") $ missingDestination f
|
||||||
|
where
|
||||||
|
f t = err (getId t) 2224 "This mv has no destination. Check the arguments."
|
||||||
|
|
||||||
|
checkCpArguments = CommandCheck (Basename "cp") $ missingDestination f
|
||||||
|
where
|
||||||
|
f t = err (getId t) 2225 "This cp has no destination. Check the arguments."
|
||||||
|
|
||||||
|
checkLnArguments = CommandCheck (Basename "ln") $ missingDestination f
|
||||||
|
where
|
||||||
|
f t = warn (getId t) 2226 "This ln has no destination. Check the arguments, or specify '.' explicitly."
|
||||||
|
|
||||||
|
|
||||||
return []
|
return []
|
||||||
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
runTests = $( [| $(forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) |])
|
||||||
|
|
Loading…
Reference in New Issue