feat: avoid double negative of a binary operator in test

suggest `[ a != b ]` over `[ ! a = b ]` and `! [ a = b ]`, and so forth.
c.f. SC2236 and SC2237 (unary operations)

close #3164
This commit is contained in:
Eisuke Kawashima 2025-04-15 02:19:31 +09:00
commit 34cdbaa5e0
No known key found for this signature in database
GPG key ID: AE0456361ACA5F4B
2 changed files with 31 additions and 0 deletions

View file

@ -5,6 +5,7 @@
- SC2330: Warn about unsupported glob matches with [[ .. ]] in BusyBox. - SC2330: Warn about unsupported glob matches with [[ .. ]] in BusyBox.
- SC2331: Suggest using standard -e instead of unary -a in tests. - SC2331: Suggest using standard -e instead of unary -a in tests.
- SC2332: Warn about `[ ! -o opt ]` being unconditionally true in Bash. - SC2332: Warn about `[ ! -o opt ]` being unconditionally true in Bash.
- SC2335: Avoid double negative of a binary operator in test—suggest `[ a != b ]` over `[ ! a = b ]` and `! [ a = b ]`, and so forth.
- SC3062: Warn about bashism `[ -o opt ]`. - SC3062: Warn about bashism `[ -o opt ]`.
- Precompiled binaries for Linux riscv64 (linux.riscv64) - Precompiled binaries for Linux riscv64 (linux.riscv64)
### Changed ### Changed

View file

@ -3992,6 +3992,11 @@ prop_checkInvertedStringTest2 = verify checkInvertedStringTest "! [[ -n $var ]]"
prop_checkInvertedStringTest3 = verifyNot checkInvertedStringTest "! [ -x $var ]" prop_checkInvertedStringTest3 = verifyNot checkInvertedStringTest "! [ -x $var ]"
prop_checkInvertedStringTest4 = verifyNot checkInvertedStringTest "[[ ! -w $var ]]" prop_checkInvertedStringTest4 = verifyNot checkInvertedStringTest "[[ ! -w $var ]]"
prop_checkInvertedStringTest5 = verifyNot checkInvertedStringTest "[ -z $var ]" prop_checkInvertedStringTest5 = verifyNot checkInvertedStringTest "[ -z $var ]"
prop_checkInvertedStringTest6 = verify checkInvertedStringTest "! [ $var != foo ]"
prop_checkInvertedStringTest7 = verify checkInvertedStringTest "[[ ! $var == foo ]]"
prop_checkInvertedStringTest8 = verifyNot checkInvertedStringTest "! [[ $var =~ .* ]]"
prop_checkInvertedStringTest9 = verify checkInvertedStringTest "[ ! $var -eq 0 ]"
prop_checkInvertedStringTest10 = verify checkInvertedStringTest "! [[ $var -gt 3 ]]"
checkInvertedStringTest _ t = checkInvertedStringTest _ t =
case t of case t of
TC_Unary _ _ "!" (TC_Unary _ _ op _) -> TC_Unary _ _ "!" (TC_Unary _ _ op _) ->
@ -3999,12 +4004,37 @@ checkInvertedStringTest _ t =
"-n" -> style (getId t) 2236 "Use -z instead of ! -n." "-n" -> style (getId t) 2236 "Use -z instead of ! -n."
"-z" -> style (getId t) 2236 "Use -n instead of ! -z." "-z" -> style (getId t) 2236 "Use -n instead of ! -z."
_ -> return () _ -> return ()
TC_Unary _ _ "!" (TC_Binary _ _ op _ _) ->
case op of
"=" -> style (getId t) 2335 "Use a != b instead of ! a = b."
"==" -> style (getId t) 2335 "Use a != b instead of ! a == b."
"!=" -> style (getId t) 2335 "Use a = b instead of ! a != b."
"-eq" -> style (getId t) 2335 "Use a -ne b instead of ! a -eq b."
"-ne" -> style (getId t) 2335 "Use a -eq b instead of ! a -ne b."
"-gt" -> style (getId t) 2335 "Use a -le b instead of ! a -gt b."
"-ge" -> style (getId t) 2335 "Use a -lt b instead of ! a -ge b."
"-lt" -> style (getId t) 2335 "Use a -ge b instead of ! a -lt b."
"-le" -> style (getId t) 2335 "Use a -gt b instead of ! a -le b."
_ -> return ()
T_Banged _ (T_Pipeline _ _ T_Banged _ (T_Pipeline _ _
[T_Redirecting _ _ (T_Condition _ _ (TC_Unary _ _ op _))]) -> [T_Redirecting _ _ (T_Condition _ _ (TC_Unary _ _ op _))]) ->
case op of case op of
"-n" -> style (getId t) 2237 "Use [ -z .. ] instead of ! [ -n .. ]." "-n" -> style (getId t) 2237 "Use [ -z .. ] instead of ! [ -n .. ]."
"-z" -> style (getId t) 2237 "Use [ -n .. ] instead of ! [ -z .. ]." "-z" -> style (getId t) 2237 "Use [ -n .. ] instead of ! [ -z .. ]."
_ -> return () _ -> return ()
T_Banged _ (T_Pipeline _ _
[T_Redirecting _ _ (T_Condition _ _ (TC_Binary _ _ op _ _))]) ->
case op of
"=" -> style (getId t) 2335 "Use [ a != b ] instead of ! [ a = b ]."
"==" -> style (getId t) 2335 "Use [[ a != b ]] instead of ! [[ a == b ]]."
"!=" -> style (getId t) 2335 "Use [ a = b ] instead of ! [ a != b ]."
"-eq" -> style (getId t) 2335 "Use [ a -ne b ] instead of ! [ a -eq b ]."
"-ne" -> style (getId t) 2335 "Use [ a -eq b ] instead of ! [ a -ne b ]."
"-gt" -> style (getId t) 2335 "Use [ a -le b ] instead of ! [ a -gt b ]."
"-ge" -> style (getId t) 2335 "Use [ a -lt b ] instead of ! [ a -ge b ]."
"-lt" -> style (getId t) 2335 "Use [ a -ge b ] instead of ! [ a -lt b ]."
"-le" -> style (getId t) 2335 "Use [ a -gt b ] instead of ! [ a -le b ]."
_ -> return ()
_ -> return () _ -> return ()
prop_checkRedirectionToCommand1 = verify checkRedirectionToCommand "ls > rm" prop_checkRedirectionToCommand1 = verify checkRedirectionToCommand "ls > rm"