bashrs 6.66.0

Rust-to-Shell transpiler for deterministic bootstrap scripts
//! Rule Registry Data — static rule metadata entries.
//!
//! Uses const array + loop to keep cyclomatic complexity O(1).

use std::collections::HashMap;
use super::rule_registry::RuleMetadata;
use super::shell_compatibility::ShellCompatibility;

const RULES_EXT: &[(&str, &str, ShellCompatibility)] = &[
    ("SC2173", "Trying to trap untrappable signals (SIGKILL, SIGSTOP)", ShellCompatibility::Universal),
    ("SC2174", "mkdir -p and chmod in one shot creates security race", ShellCompatibility::Universal),
    ("SC2175", "Quote this to prevent word splitting (placeholder check)", ShellCompatibility::Universal),
    ("SC2176", "'time' keyword affects full pipeline (not just first command)", ShellCompatibility::Universal),
    ("SC2177", "'time' only times the first command (placeholder check)", ShellCompatibility::Universal),
    ("SC2178", "Variable was used as an array but is now assigned a string", ShellCompatibility::NotSh),
    ("SC2179", "Use array+=(\"item\") to append items to an array", ShellCompatibility::NotSh),
    ("SC2180", "Trying to use an array as a scalar (missing index)", ShellCompatibility::NotSh),
    ("SC2181", "Check exit code directly with if mycmd, not if [ $? -eq 0 ]", ShellCompatibility::Universal),
    ("SC2182", "This printf format string has no variables", ShellCompatibility::Universal),
    ("SC2183", "This value looks like a variable but won't be expanded", ShellCompatibility::Universal),
    ("SC2184", "Quote arguments to cd to avoid glob expansion", ShellCompatibility::Universal),
    ("SC2185", "Some SSH commands don't pass on their exit codes", ShellCompatibility::Universal),
    ("SC2186", "mktemp argument may be evaluated as template", ShellCompatibility::Universal),
    ("SC2187", "Ash scripts will be checked as Dash (use #!/bin/dash)", ShellCompatibility::Universal),
    ("SC2188", "This redirection doesn't have a command", ShellCompatibility::Universal),
    ("SC2189", "Zsh directive will be checked as sh (use #!/bin/zsh)", ShellCompatibility::Universal),
    ("SC2190", "Elements in associative arrays need index", ShellCompatibility::NotSh),
    ("SC2191", "Trying to use an associative array without index", ShellCompatibility::NotSh),
    ("SC2192", "Piping to sudo: only last command will run as root", ShellCompatibility::Universal),
    ("SC2193", "RHS of regexes must be unquoted in [[]]", ShellCompatibility::Universal),
    ("SC2194", "This word is constant - did you forget $ or ()?", ShellCompatibility::Universal),
    ("SC2195", "Use single quotes to pass literal regex to grep", ShellCompatibility::Universal),
    ("SC2196", "Prefer explicit -n to check output", ShellCompatibility::Universal),
    ("SC2197", "Don't compare globs in []; use [[ ]] or case", ShellCompatibility::Universal),
    ("SC2202", "Order sensitivity (e.g., redirects)", ShellCompatibility::Universal),
    ("SC2203", "Variable assignment order matters", ShellCompatibility::Universal),
    ("SC2204", "Exit traps must come before commands", ShellCompatibility::Universal),
    ("SC2205", "Command ordering with pipes", ShellCompatibility::Universal),
    ("SC2206", "Quote to prevent word splitting/globbing in arrays", ShellCompatibility::NotSh),
    ("SC2207", "Prefer mapfile or read -a to split command output", ShellCompatibility::NotSh),
    ("SC2208", "Command grouping issues", ShellCompatibility::Universal),
    ("SC2209", "Use single quotes for literal strings in find", ShellCompatibility::Universal),
    ("SC2210", "Don't use arithmetic shortcuts like x=++y", ShellCompatibility::Universal),
    ("SC2211", "Arithmetic on variable without $(())", ShellCompatibility::Universal),
    ("SC2212", "Use [ p ] || [ q ] instead of [ p -o q ]", ShellCompatibility::Universal),
    ("SC2213", "getopts requires argument variable", ShellCompatibility::Universal),
    ("SC2214", "Arithmetic comparison outside test", ShellCompatibility::Universal),
    ("SC2215", "Expression precedence issues", ShellCompatibility::Universal),
    ("SC2216", "Piping find to shell with ; instead of +", ShellCompatibility::Universal),
    ("SC2217", "Useless cat with find", ShellCompatibility::Universal),
    ("SC2218", "Useless return in command substitution", ShellCompatibility::Universal),
    ("SC2219", "Instead of let expr, use (( expr ))", ShellCompatibility::Universal),
    ("SC2220", "Invalid arithmetic expression", ShellCompatibility::Universal),
    ("SC2221", "Arithmetic syntax errors", ShellCompatibility::Universal),
    ("SC2222", "Lexical error in case statement syntax", ShellCompatibility::Universal),
    ("SC2223", "This default case is unreachable (previous pattern catches all)", ShellCompatibility::Universal),
    ("SC2224", "Quote the word or use a glob", ShellCompatibility::Universal),
    ("SC2225", "Use : or true instead of /bin/true", ShellCompatibility::Universal),
    ("SC2226", "This expression is constant", ShellCompatibility::Universal),
    ("SC2227", "Redirection applies to the echo, not the assignment", ShellCompatibility::Universal),
    ("SC2228", "Declare -x is equivalent to export", ShellCompatibility::Universal),
    ("SC2229", "This does not read 'foo'. Remove $/${} for that", ShellCompatibility::Universal),
    ("SC2230", "which is non-standard, use command -v instead", ShellCompatibility::Universal),
    ("SC2231", "Quote expansions in this for loop glob to prevent word splitting", ShellCompatibility::Universal),
    ("SC2232", "Can't use sudo with builtins like cd", ShellCompatibility::Universal),
    ("SC2233", "Remove superfluous (..) around condition", ShellCompatibility::Universal),
    ("SC2234", "Remove superfluous () around here document", ShellCompatibility::Universal),
    ("SC2235", "Quote arguments to unalias to prevent word splitting", ShellCompatibility::Universal),
    ("SC2236", "Use -n instead of ! -z", ShellCompatibility::Universal),
    ("SC2237", "Use [ ] instead of [[ ]] (for sh compatibility)", ShellCompatibility::Universal),
    ("SC2238", "Prefer ${} over backticks (readability + nesting)", ShellCompatibility::Universal),
    ("SC2239", "Ensure consistent quoting for redirects", ShellCompatibility::Universal),
    ("SC2240", "The dot command does not support arguments in sh", ShellCompatibility::Universal),
    ("SC2241", "Exit code is always overridden by following command", ShellCompatibility::Universal),
    ("SC2242", "Can only break/continue from loops, not case", ShellCompatibility::Universal),
    ("SC2243", "Prefer explicit -n to check for output", ShellCompatibility::Universal),
    ("SC2244", "Prefer explicit -n to check for output (variation)", ShellCompatibility::Universal),
    ("SC2245", "-d test on assignment result", ShellCompatibility::Universal),
    ("SC2246", "This shebang was unrecognized", ShellCompatibility::Universal),
    ("SC2247", "Prefer [ p ] && [ q ] over [ p -a q ]", ShellCompatibility::Universal),
    ("SC2248", "Prefer explicit -n to check for output", ShellCompatibility::Universal),
    ("SC2249", "Consider adding default case in case statement", ShellCompatibility::Universal),
    ("SC2250", "Prefer $((..)) over let for arithmetic", ShellCompatibility::Universal),
    ("SC2251", "This loop will only ever run once for constant", ShellCompatibility::Universal),
    ("SC2252", "You probably wanted && here, not a second [", ShellCompatibility::Universal),
    ("SC2253", "Quote the RHS of = in [[ ]] to prevent glob matching", ShellCompatibility::Universal),
    ("SC2254", "Quote expansions in case patterns to prevent word splitting", ShellCompatibility::Universal),
    ("SC2255", "This [ .. ] is true whenever str is non-empty", ShellCompatibility::Universal),
    ("SC2256", "Prefer -n/-z over comparison with empty string", ShellCompatibility::Universal),
    ("SC2257", "Prefer explicit -n to check non-empty string", ShellCompatibility::Universal),
    ("SC2258", "Prefer explicit -n to check output", ShellCompatibility::Universal),
    ("SC2259", "This assumes $RANDOM is always positive", ShellCompatibility::Universal),
    ("SC2260", "Fix $((..)) arithmetic so [[ ]] can interpret it", ShellCompatibility::Universal),
    ("SC2261", "Unquoted operand will be glob expanded", ShellCompatibility::Universal),
    ("SC2262", "This command may need quoting (context sensitive)", ShellCompatibility::Universal),
    ("SC2263", "Use cd ... || exit to handle cd failures", ShellCompatibility::Universal),
    ("SC2264", "Prefer [ p ] && [ q ] over [ p -a q ]", ShellCompatibility::Universal),
    ("SC2265", "Use ${var:?} to ensure this never expands to /* /", ShellCompatibility::Universal),
    ("SC2266", "Prefer [ p ] || [ q ] over [ p -o q ]", ShellCompatibility::Universal),
    ("SC2267", "Use ${var:?} to ensure variable is set", ShellCompatibility::Universal),
    ("SC2268", "Avoid x-prefix in comparisons", ShellCompatibility::Universal),
    ("SC2269", "This regex should be put in a variable", ShellCompatibility::Universal),
    ("SC2270", "Prefer getopts over manual argument parsing", ShellCompatibility::Universal),
    ("SC2271", "Prefer printf over echo for non-trivial formatting", ShellCompatibility::Universal),
    ("SC2272", "This is a constant, not a variable", ShellCompatibility::Universal),
    ("SC2273", "Use ${var:?} if this should never be empty", ShellCompatibility::Universal),
    ("SC2274", "Quote the RHS of = in [ ] to prevent globbing", ShellCompatibility::Universal),
    ("SC2275", "Use ${var} to avoid field splitting", ShellCompatibility::Universal),
    ("SC2276", "Prefer explicit -n to check non-empty", ShellCompatibility::Universal),
    ("SC2277", "Use || instead of -o for test operators", ShellCompatibility::Universal),
    ("SC2278", "Use [[ ]] instead of deprecated syntax", ShellCompatibility::Universal),
    ("SC2279", "Use [[ < instead of [ <", ShellCompatibility::Universal),
    ("SC2280", "Remove redundant (..) or use 'if .. then'", ShellCompatibility::Universal),
    ("SC2281", "Don't use $@ in double quotes, it breaks word splitting", ShellCompatibility::Universal),
    ("SC2282", "Use ${var:?} to require variables to be set", ShellCompatibility::Universal),
    ("SC2283", "Remove extra spaces after ! in test expressions", ShellCompatibility::Universal),
    ("SC2284", "Use ${var:+value} for conditional value assignment", ShellCompatibility::Universal),
    ("SC2285", "Remove $ from variables in arithmetic contexts", ShellCompatibility::Universal),
    ("SC2286", "Prefer mapfile/readarray over read loops", ShellCompatibility::NotSh),
    ("SC2287", "Use [[ -v var ]] to check if variable is set", ShellCompatibility::NotSh),
    ("SC2288", "Use true/false directly instead of [ 1 = 1 ]", ShellCompatibility::Universal),
    ("SC2289", "Use ${#var} instead of expr length for string length", ShellCompatibility::Universal),
    ("SC2290", "Remove $ from array index: ${array[i]} not ${array[$i]}", ShellCompatibility::NotSh),
    ("SC2291", "Use [[ ! -v var ]] to check if variable is unset", ShellCompatibility::NotSh),
    ("SC2306", "Use ${var//old/new} instead of sed for simple substitutions", ShellCompatibility::NotSh),
    ("SC2307", "Use ${var#prefix} to remove prefix", ShellCompatibility::Universal),
    ("SC2308", "Use ${var%suffix} to remove suffix", ShellCompatibility::Universal),
    ("SC2309", "Use ${var##prefix} to remove longest prefix", ShellCompatibility::Universal),
    ("SC2311", "Use ${var%%suffix} to remove longest suffix", ShellCompatibility::Universal),
    ("SC2315", "Use ${var:+replacement} for conditional replacement", ShellCompatibility::Universal),
    ("SC2310", "Function in condition - set -e doesn't apply", ShellCompatibility::Universal),
    ("SC2316", "Command group and precedence issues", ShellCompatibility::Universal),
    ("SC2317", "Unreachable code detection", ShellCompatibility::Universal),
    ("SC2312", "Deprecated local -x syntax", ShellCompatibility::Universal),
    ("SC2313", "Use $(( )) for arithmetic", ShellCompatibility::Universal),
    ("SC2318", "Deprecated $[ ] syntax - use $(( ))", ShellCompatibility::Universal),
    ("SC2314", "Use [[ ]] for pattern matching", ShellCompatibility::NotSh),
    ("SC2320", "This $N expands to the parameter, not a separate word", ShellCompatibility::Universal),
    ("SC2322", "Arithmetic operations don't accept this argument count", ShellCompatibility::Universal),
    ("SC2323", "Arithmetic equality uses = not ==", ShellCompatibility::Universal),
    ("SC2324", "Use ${var:+value} for conditional value based on isset", ShellCompatibility::Universal),
    ("SC2325", "Use $var instead of ${var} in arithmetic contexts", ShellCompatibility::Universal),
    ("SC2321", "This && is not a logical AND but part of [[ ]]", ShellCompatibility::NotSh),
    ("SC2036", "Quotes in backticks need escaping. Use $( ) instead", ShellCompatibility::Universal),
    ("SC2037", "To assign command output, use var=$(cmd), not cmd > $var", ShellCompatibility::Universal),
    ("SC2119", "Use foo \"$@\" if function's $1 should mean script's $1", ShellCompatibility::Universal),
    ("SC2123", "PATH is the shell search path. Assign to path instead", ShellCompatibility::Universal),
    ("SC2124", "Use \"${var[@]}\" to prevent word splitting", ShellCompatibility::NotSh),
    ("SC2125", "Brace expansion doesn't happen in [[ ]]", ShellCompatibility::Universal),
    ("SC2292", "Prefer ${var:0:1} over expr substr for single character", ShellCompatibility::NotSh),
    ("SC2293", "Use += to append to arrays", ShellCompatibility::NotSh),
    ("SC2294", "Use arithmetic expansion ((...)) for simple assignments", ShellCompatibility::Universal),
    ("SC2295", "Expansions inside ${} need to be quoted separately", ShellCompatibility::Universal),
    ("SC2296", "Parameter expansions can't be nested", ShellCompatibility::Universal),
    ("SC2297", "Redirect before pipe", ShellCompatibility::Universal),
    ("SC2298", "Useless use of cat before pipe", ShellCompatibility::Universal),
    ("SC2299", "Parameter expansion only allows literals here", ShellCompatibility::Universal),
    ("SC2300", "Use ${var:?} for required environment variables", ShellCompatibility::Universal),
    ("SC2301", "Use [[ -v array[0] ]] to check if array element exists", ShellCompatibility::NotSh),
    ("SC2302", "Prefer ${var// /} over tr for simple substitution", ShellCompatibility::NotSh),
    ("SC2303", "Arithmetic base only allowed in assignments", ShellCompatibility::Universal),
    ("SC2304", "Command appears to be undefined", ShellCompatibility::Universal),
    ("SC2305", "Use ${var:=value} to assign default value", ShellCompatibility::Universal),
    ("SC2319", "This $? refers to a condition, not the previous command", ShellCompatibility::Universal),
    ("MAKE001", "Non-deterministic wildcard usage in Makefiles", ShellCompatibility::Universal),
    ("MAKE002", "Non-idempotent mkdir in Makefile recipes", ShellCompatibility::Universal),
    ("MAKE003", "Unsafe variable expansion in Makefile recipes", ShellCompatibility::Universal),
    ("MAKE004", "Missing .PHONY declaration for non-file targets", ShellCompatibility::Universal),
    ("MAKE005", "Recursive variable assignment in Makefiles", ShellCompatibility::Universal),
    ("MAKE006", "Missing target dependencies", ShellCompatibility::Universal),
    ("MAKE007", "Silent recipe errors (missing @ prefix)", ShellCompatibility::Universal),
    ("MAKE008", "Tab vs spaces in recipes (CRITICAL)", ShellCompatibility::Universal),
    ("MAKE009", "Hardcoded paths (non-portable)", ShellCompatibility::Universal),
    ("MAKE010", "Missing error handling (|| exit 1)", ShellCompatibility::Universal),
    ("MAKE011", "Dangerous pattern rules", ShellCompatibility::Universal),
    ("MAKE012", "Recursive make considered harmful", ShellCompatibility::Universal),
    ("MAKE013", "Missing .SUFFIXES (performance issue)", ShellCompatibility::Universal),
    ("MAKE014", "Inefficient shell invocation", ShellCompatibility::Universal),
    ("MAKE015", "Missing .DELETE_ON_ERROR", ShellCompatibility::Universal),
    ("MAKE016", "Unquoted variable in prerequisites", ShellCompatibility::Universal),
    ("MAKE017", "Missing .ONESHELL", ShellCompatibility::Universal),
    ("MAKE018", "Parallel-unsafe targets (race conditions)", ShellCompatibility::Universal),
    ("MAKE019", "Environment variable pollution", ShellCompatibility::Universal),
    ("MAKE020", "Missing include guard", ShellCompatibility::Universal),
    ("PERF001", "Useless use of cat", ShellCompatibility::Universal),
    ("PERF002", "Command substitution inside loop", ShellCompatibility::Universal),
    ("PERF003", "Useless use of echo", ShellCompatibility::Universal),
    ("PERF004", "find -exec with \\; instead of +", ShellCompatibility::Universal),
    ("PERF005", "/bin/echo instead of builtin echo", ShellCompatibility::Universal),
    ("PORT001", "Array syntax in POSIX sh", ShellCompatibility::ShOnly),
    ("PORT002", "local keyword in POSIX sh", ShellCompatibility::ShOnly),
    ("PORT003", "[[ ]] test in POSIX sh", ShellCompatibility::ShOnly),
    ("PORT004", "Process substitution in POSIX sh", ShellCompatibility::ShOnly),
    ("PORT005", "source instead of . in POSIX sh", ShellCompatibility::ShOnly),
    ("REL001", "Destructive command without error check", ShellCompatibility::Universal),
    ("REL002", "mktemp without trap cleanup", ShellCompatibility::Universal),
    ("REL003", "read without timeout", ShellCompatibility::Universal),
    ("REL004", "TOCTOU race condition", ShellCompatibility::Universal),
    ("REL005", "Predictable temp file name", ShellCompatibility::Universal),
    ("SC1037", "Braces required for positional parameters beyond $9", ShellCompatibility::Universal),
    ("SC1076", "Deprecated $[...] arithmetic syntax", ShellCompatibility::Universal),
    ("SC1087", "Braces required for array access", ShellCompatibility::Universal),
    ("SC1105", "Space between $ and ( breaks command substitution", ShellCompatibility::Universal),
    ("SC1106", "Use -lt/-gt not </>  in single brackets", ShellCompatibility::Universal),
    ("SC1131", "Use elif instead of else followed by if", ShellCompatibility::Universal),
    ("SC1139", "Use || instead of -o in [[ ]]", ShellCompatibility::NotSh),
    ("SC1140", "Unexpected extra token after ]", ShellCompatibility::Universal),
];

pub(super) fn extend_registry(registry: &mut HashMap<&'static str, RuleMetadata>) {
    for &(id, name, compatibility) in RULES_EXT {
        registry.insert(id, RuleMetadata { id, name, compatibility });
    }
}