Add 10 advanced QA checks based on research - AI code & beginner mistakes

RESEARCH-DRIVEN ENHANCEMENT:
Researched common bash mistakes made by:
- Beginner/green coders
- AI-generated code (ChatGPT, Claude)
- ShellCheck recommendations

ADDED 10 NEW CHECKS (21-30):

CHECK 21: Using [ ] instead of [[ ]] (MEDIUM)
- Single brackets less safe with empty vars
- Common beginner mistake
- [[ ]] handles special chars better

CHECK 22: Looping over ls output (HIGH)
- for f in $(ls) is fatally flawed antipattern
- Breaks with spaces/special characters
- Classic beginner mistake - use globs instead

CHECK 23: Missing set -euo pipefail (MEDIUM)
- Scripts continue silently after errors
- Unset variables expand to empty string
- No error propagation in pipes

CHECK 24: Unused variables (LOW)
- Variables declared but never used
- Common in AI-generated code
- Code smell indicating dead code

CHECK 25: Backticks instead of $() (LOW)
- Deprecated syntax
- Harder to nest
- Modern best practice: use $()

CHECK 26: Missing or wrong shebang (HIGH)
- Script won't execute correctly
- May run in wrong shell
- Critical for portability

CHECK 27: Unchecked command exit status (MEDIUM)
- curl/wget/git/ssh without error checks
- Silent failures in production
- Should use || or && or if checks

CHECK 28: Incorrect comparison operators (HIGH)
- Using -eq for strings or = for numbers
- Type confusion bugs
- Detects likely string vars with -eq

CHECK 29: Unsafe array iteration (MEDIUM)
- ${array[@]} without quotes
- Causes word splitting
- Should be "${array[@]}"

CHECK 30: Hardcoded credentials (CRITICAL)
- Passwords/API keys in code
- Major security vulnerability
- Detects password=, api_key=, etc.

IMPACT:
✓ 30 total checks (was 20)
✓ 106 issues found (was 52)
✓ Script: 1026 lines (was 769)
✓ Covers AI-generated code patterns
✓ Catches beginner antipatterns
✓ Security-focused checks

RESEARCH SOURCES:
- Common Bash Pitfalls (BashPitfalls wiki)
- AI Code Generation Issues (research papers)
- ShellCheck best practices
- Security vulnerability patterns

The QA script now catches the most common mistakes made by
both novice developers and AI code generators, making it a
comprehensive safety net for bash development.
This commit is contained in:
cschantz
2025-12-04 16:08:21 -05:00
parent 99e1fe5c74
commit bc617feea7
+288 -20
View File
@@ -58,7 +58,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 1: grep -F with regex anchors (CRITICAL - causes wrong results) # CHECK 1: grep -F with regex anchors (CRITICAL - causes wrong results)
#============================================================================== #==============================================================================
echo "[1/20] Checking: grep -F with regex anchors..." echo "[1/30] Checking: grep -F with regex anchors..."
{ {
echo "## CHECK 1: grep -F with regex anchors" echo "## CHECK 1: grep -F with regex anchors"
echo "Severity: CRITICAL" echo "Severity: CRITICAL"
@@ -79,7 +79,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 2: SCRIPT_DIR collisions (HIGH - causes path errors) # CHECK 2: SCRIPT_DIR collisions (HIGH - causes path errors)
#============================================================================== #==============================================================================
echo "[2/20] Checking: SCRIPT_DIR variable collisions..." echo "[2/30] Checking: SCRIPT_DIR variable collisions..."
{ {
echo "## CHECK 2: SCRIPT_DIR variable collisions" echo "## CHECK 2: SCRIPT_DIR variable collisions"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -99,7 +99,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 3: SYS_* variable resets (CRITICAL - breaks system detection) # CHECK 3: SYS_* variable resets (CRITICAL - breaks system detection)
#============================================================================== #==============================================================================
echo "[3/20] Checking: SYS_* variable resets..." echo "[3/30] Checking: SYS_* variable resets..."
{ {
echo "## CHECK 3: SYS_* variable resets without protection" echo "## CHECK 3: SYS_* variable resets without protection"
echo "Severity: CRITICAL" echo "Severity: CRITICAL"
@@ -120,7 +120,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 4: Missing function exports (HIGH - functions unavailable) # CHECK 4: Missing function exports (HIGH - functions unavailable)
#============================================================================== #==============================================================================
echo "[4/20] Checking: Missing function exports..." echo "[4/30] Checking: Missing function exports..."
{ {
echo "## CHECK 4: Missing function exports in libraries" echo "## CHECK 4: Missing function exports in libraries"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -145,7 +145,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 5: Integer comparisons without empty checks (HIGH - causes errors) # CHECK 5: Integer comparisons without empty checks (HIGH - causes errors)
#============================================================================== #==============================================================================
echo "[5/20] Checking: Unsafe integer comparisons (top 10)..." echo "[5/30] Checking: Unsafe integer comparisons (top 10)..."
{ {
echo "## CHECK 5: Integer comparisons without empty checks" echo "## CHECK 5: Integer comparisons without empty checks"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -170,7 +170,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 6: Missing common-functions.sh (HIGH - command not found) # CHECK 6: Missing common-functions.sh (HIGH - command not found)
#============================================================================== #==============================================================================
echo "[6/20] Checking: Missing common-functions.sh..." echo "[6/30] Checking: Missing common-functions.sh..."
{ {
echo "## CHECK 6: Missing common-functions.sh sourcing" echo "## CHECK 6: Missing common-functions.sh sourcing"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -190,7 +190,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 7: exit in libraries (HIGH - terminates parent script) # CHECK 7: exit in libraries (HIGH - terminates parent script)
#============================================================================== #==============================================================================
echo "[7/20] Checking: exit in library files..." echo "[7/30] Checking: exit in library files..."
{ {
echo "## CHECK 7: exit in sourced libraries" echo "## CHECK 7: exit in sourced libraries"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -215,7 +215,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 8: bc command usage (LOW - external dependency) # CHECK 8: bc command usage (LOW - external dependency)
#============================================================================== #==============================================================================
echo "[8/20] Checking: bc command usage..." echo "[8/30] Checking: bc command usage..."
{ {
echo "## CHECK 8: bc command usage" echo "## CHECK 8: bc command usage"
echo "Severity: LOW" echo "Severity: LOW"
@@ -238,7 +238,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 9: Hardcoded /var/cpanel paths (MEDIUM - breaks multi-panel) # CHECK 9: Hardcoded /var/cpanel paths (MEDIUM - breaks multi-panel)
#============================================================================== #==============================================================================
echo "[9/20] Checking: Hardcoded /var/cpanel paths..." echo "[9/30] Checking: Hardcoded /var/cpanel paths..."
{ {
echo "## CHECK 9: Hardcoded /var/cpanel paths" echo "## CHECK 9: Hardcoded /var/cpanel paths"
echo "Severity: MEDIUM" echo "Severity: MEDIUM"
@@ -264,7 +264,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 10: Undefined color variables (LOW - cosmetic issue) # CHECK 10: Undefined color variables (LOW - cosmetic issue)
#============================================================================== #==============================================================================
echo "[10/20] Checking: Undefined color variables..." echo "[10/30] Checking: Undefined color variables..."
{ {
echo "## CHECK 10: Undefined color variables" echo "## CHECK 10: Undefined color variables"
echo "Severity: LOW" echo "Severity: LOW"
@@ -289,7 +289,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 11: Bash syntax validation (CRITICAL - prevents execution) # CHECK 11: Bash syntax validation (CRITICAL - prevents execution)
#============================================================================== #==============================================================================
echo "[11/20] Checking: Bash syntax errors..." echo "[11/30] Checking: Bash syntax errors..."
{ {
echo "## CHECK 11: Bash syntax validation" echo "## CHECK 11: Bash syntax validation"
echo "Severity: CRITICAL" echo "Severity: CRITICAL"
@@ -310,7 +310,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 12: Dangerous rm commands (CRITICAL - data loss risk) # CHECK 12: Dangerous rm commands (CRITICAL - data loss risk)
#============================================================================== #==============================================================================
echo "[12/20] Checking: Dangerous rm commands..." echo "[12/30] Checking: Dangerous rm commands..."
{ {
echo "## CHECK 12: Dangerous rm commands" echo "## CHECK 12: Dangerous rm commands"
echo "Severity: CRITICAL" echo "Severity: CRITICAL"
@@ -334,7 +334,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 13: Unquoted variable expansions (HIGH - word splitting/globbing risks) # CHECK 13: Unquoted variable expansions (HIGH - word splitting/globbing risks)
#============================================================================== #==============================================================================
echo "[13/20] Checking: Unquoted variables in dangerous contexts..." echo "[13/30] Checking: Unquoted variables in dangerous contexts..."
{ {
echo "## CHECK 13: Unquoted variable expansions" echo "## CHECK 13: Unquoted variable expansions"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -358,7 +358,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 14: Command injection via eval (CRITICAL - arbitrary code execution) # CHECK 14: Command injection via eval (CRITICAL - arbitrary code execution)
#============================================================================== #==============================================================================
echo "[14/20] Checking: Command injection risks..." echo "[14/30] Checking: Command injection risks..."
{ {
echo "## CHECK 14: Command injection via eval" echo "## CHECK 14: Command injection via eval"
echo "Severity: CRITICAL" echo "Severity: CRITICAL"
@@ -379,7 +379,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 15: Temp file security (MEDIUM - race conditions/predictable names) # CHECK 15: Temp file security (MEDIUM - race conditions/predictable names)
#============================================================================== #==============================================================================
echo "[15/20] Checking: Temp file security..." echo "[15/30] Checking: Temp file security..."
{ {
echo "## CHECK 15: Insecure temp file creation" echo "## CHECK 15: Insecure temp file creation"
echo "Severity: MEDIUM" echo "Severity: MEDIUM"
@@ -402,7 +402,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 16: TODO/FIXME/HACK markers (LOW - technical debt tracking) # CHECK 16: TODO/FIXME/HACK markers (LOW - technical debt tracking)
#============================================================================== #==============================================================================
echo "[16/20] Checking: Technical debt markers..." echo "[16/30] Checking: Technical debt markers..."
{ {
echo "## CHECK 16: TODO/FIXME/HACK comments" echo "## CHECK 16: TODO/FIXME/HACK comments"
echo "Severity: LOW" echo "Severity: LOW"
@@ -426,7 +426,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 17: Duplicate function definitions (MEDIUM - causes conflicts) # CHECK 17: Duplicate function definitions (MEDIUM - causes conflicts)
#============================================================================== #==============================================================================
echo "[17/20] Checking: Duplicate function definitions..." echo "[17/30] Checking: Duplicate function definitions..."
{ {
echo "## CHECK 17: Duplicate function definitions" echo "## CHECK 17: Duplicate function definitions"
echo "Severity: MEDIUM" echo "Severity: MEDIUM"
@@ -452,7 +452,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 18: Missing input validation (HIGH - security/reliability risk) # CHECK 18: Missing input validation (HIGH - security/reliability risk)
#============================================================================== #==============================================================================
echo "[18/20] Checking: Missing input validation..." echo "[18/30] Checking: Missing input validation..."
{ {
echo "## CHECK 18: Functions without parameter validation" echo "## CHECK 18: Functions without parameter validation"
echo "Severity: HIGH" echo "Severity: HIGH"
@@ -486,7 +486,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 19: Long functions (MEDIUM - maintainability issue) # CHECK 19: Long functions (MEDIUM - maintainability issue)
#============================================================================== #==============================================================================
echo "[19/20] Checking: Overly long functions..." echo "[19/30] Checking: Overly long functions..."
{ {
echo "## CHECK 19: Long functions (>100 lines)" echo "## CHECK 19: Long functions (>100 lines)"
echo "Severity: MEDIUM" echo "Severity: MEDIUM"
@@ -531,7 +531,7 @@ echo ""
#============================================================================== #==============================================================================
# CHECK 20: ShellCheck integration (if available) # CHECK 20: ShellCheck integration (if available)
#============================================================================== #==============================================================================
echo "[20/20] Checking: ShellCheck warnings (if available)..." echo "[20/30] Checking: ShellCheck warnings (if available)..."
{ {
echo "## CHECK 20: ShellCheck static analysis" echo "## CHECK 20: ShellCheck static analysis"
echo "Severity: VARIES" echo "Severity: VARIES"
@@ -564,6 +564,274 @@ fi
echo "" echo ""
} >> "$REPORT" } >> "$REPORT"
#==============================================================================
# CHECK 21: Using [ ] instead of [[ ]] (MEDIUM - less safe)
#==============================================================================
echo "[21/30] Checking: Single bracket conditionals..."
{
echo "## CHECK 21: Using [ ] instead of [[ ]]"
echo "Severity: MEDIUM"
echo "Issue: Single brackets don't handle empty vars/special chars safely"
echo ""
count=0
while IFS=: read -r file line_num line_content; do
# Check for [ with string comparisons or variable tests
if echo "$line_content" | grep -qE '\[\s+[^]]*(\$[a-zA-Z_]|==|!=)[^]]*\]'; then
# Skip if it's already [[ ]] or a comment
if ! echo "$line_content" | grep -qE '^\s*#|\[\['; then
echo "MEDIUM|$file|$line_num|Using [ ] instead of safer [[ ]]"
count_issue "MEDIUM"
((count++))
[ "$count" -ge 10 ] && break
fi
fi
done < <(grep -rn '\[\s' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null)
echo "Found: $count issues (showing first 10)"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 22: Looping over ls output (HIGH - fatally flawed pattern)
#==============================================================================
echo "[22/30] Checking: Loops over ls output..."
{
echo "## CHECK 22: Looping over ls output"
echo "Severity: HIGH"
echo "Issue: for f in \$(ls) breaks with spaces/special chars"
echo ""
while IFS=: read -r file line_num line_content; do
if ! echo "$line_content" | grep -q '^\s*#'; then
echo "HIGH|$file|$line_num|Looping over ls output (use glob or find -print0)"
count_issue "HIGH"
fi
done < <(grep -rnE 'for\s+\w+\s+in\s+\$\(ls' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null | head -10)
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 23: Missing set -euo pipefail (MEDIUM - silent failures)
#==============================================================================
echo "[23/30] Checking: Missing error handling flags..."
{
echo "## CHECK 23: Missing set -euo pipefail"
echo "Severity: MEDIUM"
echo "Issue: Scripts continue after errors, unset vars expand to empty"
echo ""
count=0
while read -r file; do
# Skip library files (they're sourced, not executed)
if [[ "$file" == */lib/* ]]; then
continue
fi
# Check for shebang (executable script)
if head -1 "$file" 2>/dev/null | grep -q '^#!/bin/bash'; then
# Check if it has any error handling
if ! grep -q 'set -[euo]' "$file" 2>/dev/null; then
echo "MEDIUM|$file|N/A|Missing set -e/-u/-o pipefail (consider 'set -euo pipefail')"
count_issue "MEDIUM"
((count++))
[ "$count" -ge 10 ] && break
fi
fi
done < <(find "$TOOLKIT_PATH/modules" "$TOOLKIT_PATH/tools" -name "*.sh" 2>/dev/null)
echo "Found: $count scripts without error handling"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 24: Unused variables (LOW - dead code)
#==============================================================================
echo "[24/30] Checking: Unused variables..."
{
echo "## CHECK 24: Unused variables"
echo "Severity: LOW"
echo "Issue: Variables declared but never used (AI code smell)"
echo ""
count=0
while read -r file; do
# Find all variable assignments
while IFS=: read -r line_num var_line; do
var_name=$(echo "$var_line" | grep -oE '^[[:space:]]*(local[[:space:]]+)?([a-zA-Z_][a-zA-Z0-9_]*)=' | sed 's/local //; s/=//')
if [ -n "$var_name" ]; then
# Check if variable is used anywhere after declaration
if ! grep -q "\$$var_name\b" "$file" 2>/dev/null; then
echo "LOW|$file|$line_num|Unused variable: $var_name"
count_issue "LOW"
((count++))
[ "$count" -ge 15 ] && break 2
fi
fi
done < <(grep -n '^\s*\(local \)\?[a-zA-Z_][a-zA-Z0-9_]*=' "$file" 2>/dev/null | head -20)
done < <(find "$TOOLKIT_PATH" -name "*.sh" -not -name "toolkit-qa-check.sh" 2>/dev/null | head -5)
echo "Note: Checked first 5 files, showing first 15 issues"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 25: Backticks instead of $() (LOW - deprecated syntax)
#==============================================================================
echo "[25/30] Checking: Deprecated backticks..."
{
echo "## CHECK 25: Using backticks instead of \$()"
echo "Severity: LOW"
echo "Issue: Backticks are deprecated, harder to nest"
echo ""
while IFS=: read -r file line_num line_content; do
if ! echo "$line_content" | grep -q '^\s*#'; then
echo "LOW|$file|$line_num|Uses backticks (use \$(...) instead)"
count_issue "LOW"
fi
done < <(grep -rn '`[^`]*`' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null | head -10)
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 26: Missing or wrong shebang (HIGH - execution issues)
#==============================================================================
echo "[26/30] Checking: Shebang issues..."
{
echo "## CHECK 26: Missing or incorrect shebang"
echo "Severity: HIGH"
echo "Issue: Script won't execute correctly without proper shebang"
echo ""
while read -r file; do
# Skip library files (sourced, not executed)
if [[ "$file" == */lib/* ]]; then
continue
fi
first_line=$(head -1 "$file" 2>/dev/null)
# Check if missing shebang
if [ ! "$first_line" = "#!/bin/bash" ] && [ ! "$first_line" = "#!/usr/bin/env bash" ]; then
if [ "${first_line:0:2}" != "#!" ]; then
echo "HIGH|$file|1|Missing shebang (add #!/bin/bash)"
count_issue "HIGH"
else
echo "MEDIUM|$file|1|Non-standard shebang: $first_line"
count_issue "MEDIUM"
fi
fi
done < <(find "$TOOLKIT_PATH/modules" "$TOOLKIT_PATH/tools" -name "*.sh" 2>/dev/null | head -20)
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 27: Not checking command exit status (MEDIUM - silent failures)
#==============================================================================
echo "[27/30] Checking: Unchecked critical commands..."
{
echo "## CHECK 27: Critical commands without exit status checks"
echo "Severity: MEDIUM"
echo "Issue: Commands that can fail should be checked"
echo ""
count=0
while IFS=: read -r file line_num line_content; do
# Check for critical commands without || or && or if checks
if echo "$line_content" | grep -qE '^\s*(curl|wget|rsync|mysql|ssh|git)\s' && \
! echo "$line_content" | grep -qE '(\|\||&&|if\s)'; then
# Skip comments
if ! echo "$line_content" | grep -q '^\s*#'; then
cmd=$(echo "$line_content" | awk '{print $1}')
echo "MEDIUM|$file|$line_num|$cmd command without exit status check"
count_issue "MEDIUM"
((count++))
[ "$count" -ge 10 ] && break
fi
fi
done < <(grep -rnE '^\s*(curl|wget|rsync|mysql|ssh|git)\s' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null)
echo "Found: $count unchecked commands (showing first 10)"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 28: Incorrect string/number comparison (HIGH - type confusion)
#==============================================================================
echo "[28/30] Checking: Type confusion in comparisons..."
{
echo "## CHECK 28: Using wrong comparison operators"
echo "Severity: HIGH"
echo "Issue: -eq for strings or = for numbers causes bugs"
echo ""
count=0
# Check for -eq with likely string variables
while IFS=: read -r file line_num line_content; do
if echo "$line_content" | grep -qE '\$[A-Z_]*[a-z][A-Za-z_]*(name|user|status|type|mode|method)\s+-eq\s'; then
echo "HIGH|$file|$line_num|Using -eq for likely string comparison (use = or ==)"
count_issue "HIGH"
((count++))
[ "$count" -ge 5 ] && break
fi
done < <(grep -rnE '\-eq\s' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null)
echo "Found: $count type confusion issues (showing first 5)"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 29: Unsafe array iteration (MEDIUM - word splitting)
#==============================================================================
echo "[29/30] Checking: Unsafe array expansions..."
{
echo "## CHECK 29: Array iteration without quotes"
echo "Severity: MEDIUM"
echo "Issue: Use \"\${array[@]}\" not \${array[@]} or \$array"
echo ""
count=0
while IFS=: read -r file line_num line_content; do
# Check for unquoted array expansions
if echo "$line_content" | grep -qE 'for\s+\w+\s+in\s+\$\{[^}]+\[@\]\}' && \
! echo "$line_content" | grep -q '"\${'; then
echo "MEDIUM|$file|$line_num|Unquoted array expansion (causes word splitting)"
count_issue "MEDIUM"
((count++))
[ "$count" -ge 10 ] && break
fi
done < <(grep -rnE 'for\s+\w+\s+in\s+\$\{.*\[@\]' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null)
echo "Found: $count unsafe array iterations"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 30: Hardcoded credentials or secrets (CRITICAL - security)
#==============================================================================
echo "[30/30] Checking: Hardcoded credentials..."
{
echo "## CHECK 30: Hardcoded passwords/API keys"
echo "Severity: CRITICAL"
echo "Issue: Credentials in code = major security vulnerability"
echo ""
while IFS=: read -r file line_num line_content; do
# Look for suspicious patterns
if echo "$line_content" | grep -qiE '(password|passwd|pwd|api_key|apikey|secret|token|auth)=["'"'"'][^"'"'"']+["'"'"']' && \
! echo "$line_content" | grep -qE '^\s*#|<password>|REDACTED|YOUR_|ENTER_|example'; then
echo "CRITICAL|$file|$line_num|Possible hardcoded credential detected"
count_issue "CRITICAL"
fi
done < <(grep -rniE '(password|passwd|api_key|apikey|secret|token)=' "$TOOLKIT_PATH" --include="*.sh" --exclude="toolkit-qa-check.sh" 2>/dev/null | head -10)
echo ""
} >> "$REPORT"
#============================================================================== #==============================================================================
# PERFORMANCE CHECKS (INFO level - not counted as issues) # PERFORMANCE CHECKS (INFO level - not counted as issues)
#============================================================================== #==============================================================================