website-htmx-rustelo-code/scripts/sh/content/validate-content-consistency.sh
2026-07-10 03:44:13 +01:00

293 lines
No EOL
9.2 KiB
Bash
Executable file
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Content Consistency Validation Script
# Validates that content structure is consistent and server can process all content
# set -e removed - handle errors explicitly to avoid early exits on warnings
# Configuration
CONTENT_DIR="${SITE_CONTENT_PATH:-site/content}"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Counters
TOTAL_CHECKS=0
PASSED_CHECKS=0
FAILED_CHECKS=0
# Function to print colored output
print_status() {
local status=$1
local message=$2
case $status in
"PASS")
echo -e "${GREEN}✅ PASS${NC}: $message"
((PASSED_CHECKS++))
;;
"FAIL")
echo -e "${RED}❌ FAIL${NC}: $message"
((FAILED_CHECKS++))
;;
"WARN")
echo -e "${YELLOW}⚠️ WARN${NC}: $message"
;;
"INFO")
echo -e "${BLUE} INFO${NC}: $message"
;;
esac
((TOTAL_CHECKS++))
}
# Function to check if directory exists and is not empty
check_directory() {
local dir=$1
local description=$2
if [ ! -d "$dir" ]; then
print_status "FAIL" "$description directory missing: $dir"
return 1
fi
local file_count
file_count=$(ls -A "$dir" 2>/dev/null | wc -l)
if [ "$file_count" -eq 0 ]; then
print_status "WARN" "$description directory is empty: $dir"
return 0 # Return 0 for warnings to not exit with set -e
fi
print_status "PASS" "$description directory exists and has content: $dir"
return 0
}
# Function to validate markdown files
validate_markdown_files() {
local base_dir=$1
local content_type=$2
print_status "INFO" "Validating $content_type markdown files in $base_dir"
local md_count=0
local invalid_count=0
while IFS= read -r -d '' file; do
((md_count++))
# Check if file has frontmatter
if ! head -n1 "$file" | grep -q "^---$"; then
print_status "FAIL" "Missing frontmatter in: ${file#$PROJECT_ROOT/}"
((invalid_count++))
continue
fi
# Check if file has closing frontmatter
if ! sed -n '2,$p' "$file" | grep -q "^---$"; then
print_status "FAIL" "Invalid frontmatter (no closing ---) in: ${file#$PROJECT_ROOT/}"
((invalid_count++))
continue
fi
# Check for required frontmatter fields
local frontmatter=$(sed -n '/^---$/,/^---$/p' "$file")
if ! echo "$frontmatter" | grep -q "^title:"; then
print_status "FAIL" "Missing 'title' field in: ${file#$PROJECT_ROOT/}"
((invalid_count++))
fi
if ! echo "$frontmatter" | grep -q "^slug:"; then
print_status "FAIL" "Missing 'slug' field in: ${file#$PROJECT_ROOT/}"
((invalid_count++))
fi
done < <(find "$base_dir" -name "*.md" -type f -print0)
if [ $md_count -eq 0 ]; then
print_status "WARN" "No markdown files found in $base_dir"
else
if [ $invalid_count -eq 0 ]; then
print_status "PASS" "All $md_count $content_type markdown files are valid"
else
print_status "FAIL" "$invalid_count of $md_count $content_type markdown files have issues"
fi
fi
}
# Function to validate content structure
validate_content_structure() {
print_status "INFO" "=== Content Structure Validation ==="
# Check main content directory
check_directory "$CONTENT_DIR" "Main content"
# Check content-kinds.toml exists
local content_kinds_file="$CONTENT_DIR/content-kinds.toml"
if [ ! -f "$content_kinds_file" ]; then
print_status "FAIL" "content-kinds.toml missing: $content_kinds_file"
return 1
fi
print_status "PASS" "content-kinds.toml exists"
# Check routes configuration
if [ -f "$CONTENT_DIR/routes.toml" ]; then
print_status "PASS" "routes.toml exists"
elif [ -d "$CONTENT_DIR/routes/" ]; then
print_status "PASS" "routes/ directory exists"
else
print_status "FAIL" "No routes configuration found (routes.toml or routes/ directory)"
fi
# Validate each enabled content type
while IFS= read -r content_type; do
local content_dir="$CONTENT_DIR/$content_type"
if check_directory "$content_dir" "Content type '$content_type'"; then
# Check for language directories
local lang_count=0
for lang_dir in "$content_dir"/*/; do
if [ -d "$lang_dir" ]; then
local lang=$(basename "$lang_dir")
check_directory "$lang_dir" "Language '$lang' in '$content_type'"
validate_markdown_files "$lang_dir" "$content_type/$lang"
((lang_count++))
fi
done
if [ $lang_count -eq 0 ]; then
print_status "WARN" "No language directories found in $content_type"
fi
fi
done < <(get_enabled_content_types)
}
# Function to get enabled content types from content-kinds.toml
get_enabled_content_types() {
local content_kinds_file="$CONTENT_DIR/content-kinds.toml"
if [ ! -f "$content_kinds_file" ]; then
echo "blog"
echo "recipes"
return
fi
# Simplified parsing - look for directory entries that aren't commented out
grep -E '^\s*directory\s*=' "$content_kinds_file" | \
sed 's/.*directory\s*=\s*"\([^"]*\)".*/\1/' | \
while read -r dir; do
if [ -d "$CONTENT_DIR/$dir" ]; then
echo "$dir"
fi
done
}
# Function to check server can process content
validate_server_processing() {
print_status "INFO" "=== Server Content Processing Validation ==="
# Check if server binary exists
if [ ! -f "$PROJECT_ROOT/target/debug/server" ] && [ ! -f "$PROJECT_ROOT/target/release/server" ]; then
print_status "WARN" "Server binary not found - run 'cargo build --features content-static' first"
return
fi
print_status "PASS" "Server binary is available for content processing"
}
# Function to validate i18n structure
validate_i18n_structure() {
print_status "INFO" "=== Internationalization Structure Validation ==="
local locales_dir="$CONTENT_DIR/locales"
if check_directory "$locales_dir" "Locales"; then
# Check for language directories in locales
for lang_dir in "$locales_dir"/*/; do
if [ -d "$lang_dir" ]; then
local lang=$(basename "$lang_dir")
check_directory "$lang_dir" "Locale '$lang'"
# Check for common.ftl
if [ -f "$lang_dir/common.ftl" ]; then
print_status "PASS" "common.ftl exists for language '$lang'"
else
print_status "WARN" "common.ftl missing for language '$lang'"
fi
fi
done
fi
# Check menus
local menus_dir="$CONTENT_DIR/menus"
if check_directory "$menus_dir" "Menus"; then
for menu_file in "$menus_dir"/*.toml; do
if [ -f "$menu_file" ]; then
local lang=$(basename "$menu_file" .toml)
print_status "PASS" "Menu configuration exists for language '$lang'"
fi
done
fi
}
# Function to remove deprecated files/directories
cleanup_deprecated() {
print_status "INFO" "=== Cleanup Deprecated Build Outputs ==="
# The /public directory is now deprecated since server processes content dynamically
if [ -d "$PROJECT_ROOT/public" ]; then
local item_count=$(find "$PROJECT_ROOT/public" -type f | wc -l)
if [ "$item_count" -gt 5 ]; then # Allow for a few static files
print_status "WARN" "Found $item_count files in /public - consider removing pre-built HTML"
print_status "INFO" "Server now processes content dynamically from /content"
else
print_status "PASS" "/public directory has minimal static files"
fi
fi
}
# Main validation function
main() {
echo "🔍 Content Consistency Validation"
echo "=================================="
echo "Content directory: $CONTENT_DIR"
echo "Project root: $PROJECT_ROOT"
echo ""
validate_content_structure
echo ""
validate_i18n_structure
echo ""
validate_server_processing
echo ""
cleanup_deprecated
echo ""
# Summary
echo "🏁 Validation Summary"
echo "===================="
echo "Total checks: $TOTAL_CHECKS"
echo "Passed: $PASSED_CHECKS"
echo "Failed: $FAILED_CHECKS"
if [ $FAILED_CHECKS -eq 0 ]; then
print_status "PASS" "All content validation checks passed!"
echo ""
echo "✅ Content structure is consistent and ready for server processing"
echo "🚀 You can run: cargo run --features content-static"
exit 0
else
echo ""
echo "❌ Content validation found $FAILED_CHECKS issues"
echo "🔧 Please fix the issues above before building"
exit 1
fi
}
# Run main function
main "$@"