diff --git a/.github/workflows/xmlvalidate.sh b/.github/workflows/xmlvalidate.sh index 79d52c16..962dcf00 100755 --- a/.github/workflows/xmlvalidate.sh +++ b/.github/workflows/xmlvalidate.sh @@ -1,42 +1,196 @@ #!/bin/bash -fail=false +set -euo pipefail # Exit on error, undefined variable, or pipe failure -# Get all string keys -KEYS=$(grep -oP '&2; } +log_detail() { echo -e " $1"; } +log_detail_success() { echo -e " ${COLOR_GREEN}$1${COLOR_RESET}"; } +log_detail_error() { echo -e " ${COLOR_RED}$1${COLOR_RESET}"; } +log_detail_warning() { echo -e " ${COLOR_YELLOW}$1${COLOR_RESET}"; } +log_detail_magenta() { echo -e " ${COLOR_MAGENTA}$1${COLOR_RESET}"; } - # Ensure each key found in common xml is found in translation xmls - for key in $KEYS; do - if ! grep -q "$key" "$file"; then - echo "Key $key not found in $file" - passes=false - fail=true +# --- Parameter Validation --- +if [ "$#" -ne 1 ]; then + log_error "Usage: $SCRIPT_NAME " + log_error "Example: $SCRIPT_NAME /path/to/VeraCrypt" + exit 1 +fi + +ROOT_PATH="$1" + +if [ ! -d "$ROOT_PATH" ]; then + log_error "Root path '$ROOT_PATH' not found or is not a directory." + exit 1 +fi + +# Define the path to the common Language.xml +COMMON_FILE="$ROOT_PATH/src/Common/Language.xml" + +# Check if the common Language.xml exists +if [ ! -f "$COMMON_FILE" ]; then + log_error "Common Language.xml not found or is not a file at path: $COMMON_FILE" + exit 1 +fi + +log_info "Extracting keys from $COMMON_FILE" + +# Define regex pattern to extract 'key' attributes from elements +KEY_EXTRACTION_PATTERN='&1) + FXPARSER_EXIT_CODE=$? + + if [ "$FXPARSER_EXIT_CODE" -ne 0 ]; then + CURRENT_FILE_PASSES=false + FAIL_FLAG=true + log_detail_error "XML Validation Failed for $file (fxparser exit code: $FXPARSER_EXIT_CODE):" + while IFS= read -r line; do + log_detail_error " $line" + done <<< "$FXPARSER_OUTPUT" + else + log_detail_success "XML structure is valid." + fi + + # 2. Check for invalid backslash escape sequences + log_detail "Checking for invalid escape sequences..." + # Use grep -P for PCRE, -n for line numbers. --color=never to avoid grep's own coloring here. + # We check grep's exit code: 0 if found, 1 if not found, >1 for error. + INVALID_ESCAPE_MATCHES=$(grep -P -n --color=never "$INVALID_ESCAPE_REGEX" "$file" || true) + + if [ -n "$INVALID_ESCAPE_MATCHES" ]; then + log_detail_error "File '$file' contains potentially invalid backslash escape sequences." + log_detail_error "$ALLOWED_ESCAPES_MESSAGE" + log_detail_error "Instances found:" + while IFS= read -r line_match; do + # Extract line number and the line content from grep's output (e.g., "123:content") + LINE_NUMBER=$(echo "$line_match" | cut -d: -f1) + LINE_CONTENT=$(echo "$line_match" | cut -d: -f2-) + # Trim whitespace (optional, but PowerShell did it) + TRIMMED_LINE_CONTENT=$(echo "$LINE_CONTENT" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + log_detail_magenta "Line $LINE_NUMBER: $TRIMMED_LINE_CONTENT" + done <<< "$INVALID_ESCAPE_MATCHES" + CURRENT_FILE_PASSES=false + FAIL_FLAG=true + else + log_detail_success "No invalid escape sequences found." + fi + + # 3. Check for the presence of each key in the current file (if keys were found) + if [ ${#KEYS[@]} -gt 0 ]; then + log_detail "Checking for key completeness..." + KEYS_MISSING_IN_CURRENT_FILE=0 + for key_entry in "${KEYS[@]}"; do + # Search for key="KEY_NAME" + SEARCH_PATTERN_FOR_KEY="key=\"$key_entry\"" + if ! grep -q "$SEARCH_PATTERN_FOR_KEY" "$file"; then + log_detail_error "Key '$key_entry' (from $COMMON_FILE) not found in $file" + CURRENT_FILE_PASSES=false + FAIL_FLAG=true + ((KEYS_MISSING_IN_CURRENT_FILE++)) + fi + done + if [ "$KEYS_MISSING_IN_CURRENT_FILE" -eq 0 ]; then + log_detail_success "All keys from $COMMON_FILE are present." + else + log_detail_error "$KEYS_MISSING_IN_CURRENT_FILE key(s) missing." + fi + else + log_detail_warning "Skipping key completeness check as no keys were extracted from $COMMON_FILE." + fi + + # Output the result for the current file + if [ "$CURRENT_FILE_PASSES" = true ]; then + log_success "$file PASSED all checks." + else + log_error "$file FAILED one or more checks." fi - done - - if [ "$passes" = true ]; then - echo -e "\e[32m$file passes xml validation.\e[0m" - else - echo -e "\e[31m$file fails xml validation.\e[0m" - fi - done -if [ "$fail" = true ]; then - exit 1 +# Exit with appropriate status code +echo # Newline for readability +if [ "$FAIL_FLAG" = true ]; then + log_error "Overall Result: One or more files failed validation." + exit 1 else - exit 0 + log_success "Overall Result: All processed files passed all checks successfully." + exit 0 fi