Add menu uniformity checks to QA script (CHECK 104-107)

NEW CHECKS ADDED:

CHECK 104: Menu Input Validation (MEDIUM)
- Detects: read statements for menu input without validation
- Pattern: read -p 'Select option' without range checks
- Impact: Scripts crash with invalid input
- Fix: Add [[ "$choice" =~ ^[0-9]+$ ]] validation

CHECK 105: Menu Color Code Consistency (LOW)
- Detects: Menu options without color codes
- Pattern: echo "  1) Option" without ${CYAN}1)${NC}
- Impact: Visual inconsistency, poor UX
- Fix: Use ${CYAN}1)${NC} format for consistency

CHECK 106: Menu Retry Loop Implementation (LOW)
- Detects: Input validation without proper retry loops
- Pattern: Validation without 'while true' loop
- Impact: Users must restart script on invalid input
- Fix: Wrap validation in while true; do ... done

CHECK 107: Standardized Yes/No Prompts (LOW)
- Detects: Non-standard yes/no prompts
- Pattern: read -p "... (yes/no):" instead of confirm()
- Impact: Inconsistent UX
- Fix: Use confirm() library function

METRICS UPDATED:
- Total checks: 111 (was 101)
- Progress display: [%2d/107] (was [%2d/88])
- New phase: Phase 11 - Menu uniformity validation

These checks validate the menu standards documented in REFDB_FORMAT.txt
and can be used to audit any script with menu-driven interfaces.

Usage:
  bash toolkit-qa-check.sh /path/to/script
  grep 'MENU-VALIDATION\|MENU-COLORS\|MENU-RETRY\|PROMPT-STYLE' /tmp/qa-report.txt

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
cschantz
2026-02-17 18:52:10 -05:00
parent 8982ba9531
commit fc5dc18031
+140 -2
View File
@@ -14,7 +14,7 @@
# --summary Summary mode (counts only, no details) # --summary Summary mode (counts only, no details)
# #
# Features: # Features:
# - 101 comprehensive checks (88 original + 13 new logic/error/semantic, CHECK 89 disabled for false positives) # - 111 comprehensive checks (88 original + 13 new logic/error/semantic, CHECK 89 disabled for false positives)
# - Context-aware detection (<2% false positives after filtering) # - Context-aware detection (<2% false positives after filtering)
# - Smart categorization with tags # - Smart categorization with tags
# - Suppress annotations support (# qa-suppress) # - Suppress annotations support (# qa-suppress)
@@ -94,7 +94,7 @@ show_progress() {
local check_num="$1" local check_num="$1"
local check_name="$2" local check_name="$2"
if [ -t 1 ] && ! $SUMMARY_MODE; then if [ -t 1 ] && ! $SUMMARY_MODE; then
printf "\r${DIM}[%2d/88] ${NC}%s${DIM}...${NC}" "$check_num" "$check_name" printf "\r${DIM}[%2d/107] ${NC}%s${DIM}...${NC}" "$check_num" "$check_name"
fi fi
} }
@@ -3745,6 +3745,144 @@ echo "Found: $count empty string handling issues"
echo "" echo ""
} >> "$REPORT" } >> "$REPORT"
#==============================================================================
# CHECK 104: Menu Input Validation (MEDIUM - Menu uniformity)
#==============================================================================
show_progress 104 "Menu input validation on numbered options"
{
echo "## CHECK 104: Missing Input Validation on Numbered Menus"
echo "Severity: MEDIUM"
echo "Pattern: read -p 'Select option' without validation (read followed by case without range check)"
echo "Impact: Scripts crash or behave unpredictably with invalid user input"
echo ""
count=0
# Find scripts with read statements for menu input that lack validation
while IFS=: read -r file line_num line_content; do
# Check if this read is followed by a case statement without validation
# Look for: read -p ".*option.*" choice (or similar) without preceding [[ validation ]]
# Get next 5 lines after the read to check for validation
next_lines=$(sed -n "${line_num},$((line_num+5))p" "$file" 2>/dev/null)
# Check for validation patterns
if echo "$next_lines" | grep -q '\[\[.*choice.*=~'; then
continue # Has validation
fi
if echo "$next_lines" | grep -q 'choice=.*:-'; then
# Only has default, not validation
if echo "$line_content" | grep -iE 'read.*-p.*option|read.*-p.*choice|read.*-p.*select' > /dev/null; then
if ! is_suppressed "$file" "$line_num" "menu-validation"; then
echo "MEDIUM|$file|$line_num|[MENU-VALIDATION] Menu input lacks validation - no range check after read"
count_issue "MEDIUM"
((count++))
[ "$count" -ge 10 ] && break
fi
fi
fi
done < <(grep -rn 'read -p' "$TOOLKIT_PATH/modules" --include="*.sh" 2>/dev/null | grep -iE 'option|choice|select|menu')
echo "Found: $count menu input validation issues"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 105: Menu Color Code Consistency (LOW - Menu uniformity)
#==============================================================================
show_progress 105 "Menu color code consistency"
{
echo "## CHECK 105: Inconsistent Menu Color Codes"
echo "Severity: LOW"
echo "Pattern: Menu options without color codes or using inconsistent colors"
echo "Impact: Visual inconsistency, poor user experience"
echo ""
count=0
# Find scripts with echo statements for menu options that lack color codes
while IFS=: read -r file line_num line_content; do
# Check for plain echo " 1) Option" without ${CYAN}1)${NC} format
if echo "$line_content" | grep -qE 'echo.*"[[:space:]]+[0-9]+\)' && \
! echo "$line_content" | grep -q '\$\{CYAN\}\|\$\{GREEN\}\|\$\{YELLOW\}\|\$\{RED\}'; then
if ! is_suppressed "$file" "$line_num" "menu-colors"; then
echo "LOW|$file|$line_num|[MENU-COLORS] Menu option lacks color codes"
count_issue "LOW"
((count++))
[ "$count" -ge 8 ] && break
fi
fi
done < <(grep -rn 'echo.*".*[0-9])' "$TOOLKIT_PATH/modules" --include="*.sh" 2>/dev/null | head -100)
echo "Found: $count menu color inconsistencies"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 106: Menu Retry Loop Patterns (LOW - Menu uniformity)
#==============================================================================
show_progress 106 "Menu retry loop implementation"
{
echo "## CHECK 106: Missing Retry Loops on Menu Validation"
echo "Severity: LOW"
echo "Pattern: Input validation without while loop for retry"
echo "Impact: Poor user experience - users must restart script on invalid input"
echo ""
count=0
# Find scripts with menu validation that lack proper retry loops
while IFS=: read -r file; do
# Count read statements without surrounding while true loop
total_reads=$(grep -c 'read -p.*option\|read -p.*choice' "$file" 2>/dev/null || echo 0)
while_loops=$(grep -c 'while true' "$file" 2>/dev/null || echo 0)
# If file has reads for menu input but few while loops, it likely lacks retry logic
if [ "$total_reads" -gt 2 ] && [ "$while_loops" -lt 1 ]; then
if ! is_suppressed "$file" "0" "menu-retry"; then
first_line=$(grep -n 'read -p.*option\|read -p.*choice' "$file" 2>/dev/null | head -1 | cut -d: -f1)
echo "LOW|$file|$first_line|[MENU-RETRY] Menu input handling may lack proper retry loops"
count_issue "LOW"
((count++))
[ "$count" -ge 5 ] && break
fi
fi
done < <(find "$TOOLKIT_PATH/modules" -name "*.sh" -type f 2>/dev/null)
echo "Found: $count files with potential retry loop issues"
echo ""
} >> "$REPORT"
#==============================================================================
# CHECK 107: Standardized Yes/No Prompts (LOW - Menu uniformity)
#==============================================================================
show_progress 107 "Standardized yes/no prompt usage"
{
echo "## CHECK 107: Non-standardized Yes/No Prompts"
echo "Severity: LOW"
echo "Pattern: Manual yes/no prompts instead of confirm() function"
echo "Impact: Inconsistent UX - users see different prompt styles"
echo ""
count=0
# Find scripts with non-standardized yes/no prompts
while IFS=: read -r file line_num line_content; do
# Look for: read -p "... (yes/no):" pattern
if echo "$line_content" | grep -qiE 'read.*\(yes/no\)|\(y/n\)|[Yy]/[Nn]' && \
! echo "$line_content" | grep -q 'confirm'; then
# Check if this file uses confirm() elsewhere
if grep -q 'confirm.*"' "$file" 2>/dev/null; then
if ! is_suppressed "$file" "$line_num" "prompt-style"; then
echo "LOW|$file|$line_num|[PROMPT-STYLE] Manual yes/no prompt - should use confirm() function"
count_issue "LOW"
((count++))
[ "$count" -ge 5 ] && break
fi
fi
fi
done < <(grep -rn 'read -p.*yes\|read -p.*\(y' "$TOOLKIT_PATH/modules" --include="*.sh" 2>/dev/null | head -50)
echo "Found: $count non-standardized yes/no prompts"
echo ""
} >> "$REPORT"
#============================================================================== #==============================================================================
# PERFORMANCE CHECKS (INFO level - not counted as issues) # PERFORMANCE CHECKS (INFO level - not counted as issues)
#============================================================================== #==============================================================================