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:
+140
-2
@@ -14,7 +14,7 @@
|
||||
# --summary Summary mode (counts only, no details)
|
||||
#
|
||||
# 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)
|
||||
# - Smart categorization with tags
|
||||
# - Suppress annotations support (# qa-suppress)
|
||||
@@ -94,7 +94,7 @@ show_progress() {
|
||||
local check_num="$1"
|
||||
local check_name="$2"
|
||||
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
|
||||
}
|
||||
|
||||
@@ -3745,6 +3745,144 @@ echo "Found: $count empty string handling issues"
|
||||
echo ""
|
||||
} >> "$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)
|
||||
#==============================================================================
|
||||
|
||||
Reference in New Issue
Block a user