@@ -244,6 +244,13 @@ optionalTreeChecks = [
244244 cdPositive = " echo $VAR" ,
245245 cdNegative = " VAR=hello; echo $VAR"
246246 }, checkUnassignedReferences' True )
247+
248+ ,(newCheckDescription {
249+ cdName = " require-double-brackets" ,
250+ cdDescription = " Require [[ and warn about [ in Bash/Ksh" ,
251+ cdPositive = " [ -e /etc/issue ]" ,
252+ cdNegative = " [[ -e /etc/issue ]]"
253+ }, checkRequireDoubleBracket)
247254 ]
248255
249256optionalCheckMap :: Map. Map String (Parameters -> Token -> [TokenComment ])
@@ -4311,5 +4318,39 @@ checkCommandWithTrailingSymbol _ t =
43114318 ' \" ' -> " doublequote"
43124319 x -> ' \' ' : x : " \' "
43134320
4321+
4322+ prop_checkRequireDoubleBracket1 = verifyTree checkRequireDoubleBracket " [ -x foo ]"
4323+ prop_checkRequireDoubleBracket2 = verifyTree checkRequireDoubleBracket " [ foo -o bar ]"
4324+ prop_checkRequireDoubleBracket3 = verifyNotTree checkRequireDoubleBracket " #!/bin/sh\n [ -x foo ]"
4325+ prop_checkRequireDoubleBracket4 = verifyNotTree checkRequireDoubleBracket " [[ -x foo ]]"
4326+ checkRequireDoubleBracket params =
4327+ if isBashLike params
4328+ then nodeChecksToTreeCheck [check] params
4329+ else const []
4330+ where
4331+ check _ t = case t of
4332+ T_Condition id SingleBracket _ ->
4333+ styleWithFix id 2292 " Prefer [[ ]] over [ ] for tests in Bash/Ksh." (fixFor t)
4334+ _ -> return ()
4335+
4336+ fixFor t = fixWith $
4337+ if isSimple t
4338+ then
4339+ [
4340+ replaceStart (getId t) params 0 " [" ,
4341+ replaceEnd (getId t) params 0 " ]"
4342+ ]
4343+ else []
4344+
4345+ -- We don't tag operators like < and -o well enough to replace them,
4346+ -- so just handle the simple cases.
4347+ isSimple t = case t of
4348+ T_Condition _ _ s -> isSimple s
4349+ TC_Binary _ _ op _ _ -> not $ any (\ x -> x `elem` op) " <>"
4350+ TC_Unary {} -> True
4351+ TC_Nullary {} -> True
4352+ _ -> False
4353+
4354+
43144355return []
43154356runTests = $ ( [| $ (forAllProperties) (quickCheckWithResult (stdArgs { maxSuccess = 1 }) ) | ])
0 commit comments