website-htmx-rustelo-code/scripts/wrks/merge-ftl.sh
2026-07-10 03:44:13 +01:00

346 lines
9 KiB
Bash
Executable file

#!/usr/bin/env bash
# Script to merge individual FTL files or create legacy format
# Handles the new structured directory format
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
# Configuration
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
CONTENT_DIR="$PROJECT_ROOT/content"
LEGACY_FILES=false
CREATE_INDICES=false
print_usage() {
cat << EOF
Usage: $0 [OPTIONS] [LANGUAGE]
Merge structured FTL files into legacy format or manage directory structure.
OPTIONS:
--legacy Create legacy .ftl files from structure
--indices Create index files for content directories
--all Process both en and es languages
-h, --help Show this help message
EXAMPLES:
$0 --legacy # Create content/en.ftl, content/es.ftl
$0 --indices # Create index.json files
$0 --legacy en # Create only content/en.ftl
$0 --all --legacy # Process all languages and create legacy files
ENVIRONMENT:
PROJECT_ROOT Override project root directory
EOF
}
log() {
echo -e "${CYAN}[MERGE]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1" >&2
}
log_success() {
echo -e "${GREEN}[OK]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
# Generate prefix for key based on file structure
generate_prefix() {
local filepath="$1"
local lang_dir="$2"
local relative_path="${filepath#$lang_dir/}"
relative_path="${relative_path%.*}"
# Handle different directory structures
case "$relative_path" in
*/*)
local dir="$(dirname "$relative_path")"
local file="$(basename "$relative_path")"
if [[ "$dir" == "pages" ]]; then
echo ""
elif [[ "$dir" == "components" ]]; then
echo ""
else
echo "${dir#pages/}${dir#components/}${dir#auth/}${dir#}"
fi
;;
*)
echo ""
;;
esac
}
# Merge FTL files from a directory
merge_ftl_directory() {
local lang_dir="$1"
local output_file="$2"
local lang="$(basename "$lang_dir")"
log "Processing $lang directory..."
# Find all FTL files
local ftl_files=()
while IFS= read -r -d '' file; do
ftl_files+=("$file")
done < <(find "$lang_dir" -name "*.ftl" -type f -print0)
if [[ ${#ftl_files[@]} -eq 0 ]]; then
log "No FTL files found in $lang_dir"
return 1
fi
log "Found ${#ftl_files[@]} FTL files to process"
# Sort files for consistent ordering
readarray -t ftl_files < <(printf '%s\0' "${ftl_files[@]}" | sort -z)
: > "$output_file" # Clear output file
for file in "${ftl_files[@]}"; do
local relative_path="${file#$lang_dir/}"
local prefix=""
# Determine prefix based on file location
case "$relative_path" in
common.ftl|auth.ftl)
prefix=""
;;
pages/*.ftl)
prefix=""
;;
components/*.ftl)
prefix=""
;;
*)
prefix="${relative_path%.ftl}-"
prefix="${prefix#pages-}"
prefix="${prefix#components-}"
prefix="${prefix#common-}"
prefix="${prefix#auth-}"
;;
esac
log "Processing: $relative_path"
{
echo "# === ${relative_path} ==="
while IFS= read -r line; do
line="${line%%$'\r\n'}" # Remove CRLF
# Skip processing comment and empty lines
if [[ -z "$line" ]] || [[ "$line" =~ ^[[:space:]]*# ]]; then
echo "$line"
continue
fi
# Handle key-value pairs
if [[ "$line" == *"="* ]]; then
local key="${line%%=*}"
local value="${line#*=}"
key="${key#${key%%[![:space:]]*}}" # trim leading
key="${key%${key##*[![:space:]]}}" # trim trailing
value="${value#${value%%[![:space:]]*}}" # trim leading
value="${value%${value##*[![:space:]]}}" # trim trailing
if [[ -n "$prefix" ]] && [[ "$key" != *"-"* ]]; then
echo "${prefix}${key} = ${value}"
else
echo "$key = ${value}"
fi
else
echo "$line"
fi
done < "$file"
echo # Add empty line between files
} >> "$output_file"
done
log_success "Created: $output_file (${#ftl_files[@]} files merged)"
}
# Create basic content indices
create_content_indices() {
local lang_dir="$1"
local lang="$(basename "$lang_dir")"
log "Creating indices for: $lang"
local content_types=("blog" "recipes" "pages")
for content_type in "${content_types[@]}"; do
local type_dir="$CONTENT_DIR/$content_type/$lang"
if [[ -d "$type_dir" ]]; then
local index_file="$type_dir/index.json"
if [[ ! -f "$index_file" ]]; then
case "$content_type" in
blog)
echo '{"blog": []}' > "$index_file"
;;
recipes)
echo '{"recipes": []}' > "$index_file"
;;
pages)
echo '{"pages": []}' > "$index_file"
;;
esac
log_success "Created: $index_file"
fi
fi
done
}
# Validate FTL file format
validate_ftl_file() {
local file="$1"
local errors=0
# Check for basic syntax issues
local brace_count
brace_count=$(grep -Ec '[{}]' "$file" 2>/dev/null || echo 0)
if [[ $brace_count -gt 0 ]]; then
local open_braces
local close_braces
open_braces=$(grep -o '{' "$file" | wc -l)
close_braces=$(grep -o '}' "$file" | wc -l)
if [[ $open_braces -ne $close_braces ]]; then
log_error "$file: Unbalanced braces ($open_braces open, $close_braces close)"
return 1
fi
fi
# Check for empty messages
if grep -q '^[a-zA-Z0-9_-][[:space:]]*=$' "$file"; then
log_warning "$file: Contains empty message values"
fi
return 0
}
# Process a single language
check_subdirectories() {
local lang="$1"
local lang_dir="$CONTENT_DIR/$lang"
echo
log "=== Processing $lang directory ==="
log "Directory: $lang_dir"
# Check directory structure
if [[ ! -d "$lang_dir" ]]; then
log_warning "$lang_dir does not exist"
return 1
fi
echo "Subdirectories found:"
find "$lang_dir" -type d -mindepth 1 -maxdepth 2 | head -10
echo "FTL files found:"
find "$lang_dir" -name "*.ftl" -printf " %p\n"
}
# Main processing function
main() {
local LANGS=("en" "es")
local PROCESS_LANG=""
local ALL_LANGS=false
# Parse arguments
while [[ $# -gt 0 ]]; do
case "$1" in
--legacy)
LEGACY_FILES=true
shift
;;
--indices)
CREATE_INDICES=true
shift
;;
--all)
ALL_LANGS=true
shift
;;
-h|--help)
print_usage
exit 0
;;
en|es)
PROCESS_LANG="$1"
shift
;;
*)
log_error "Unknown option: $1"
print_usage
exit 1
;;
esac
done
log "Starting FTL merge process"
# Set languages to process
if [[ -n "$PROCESS_LANG" ]]; then
LANGS=("$PROCESS_LANG")
fi
# Process directories
for lang in "${LANGS[@]}"; do
lang_dir="$CONTENT_DIR/$lang"
if [[ ! -d "$lang_dir" ]]; then
log_warning "Directory not found: $lang_dir"
continue
fi
# Show files being processed
check_subdirectories "$lang"
# Validate existing files
log "Validating FTL files..."
while IFS= read -r -d '' ftl_file; do
validate_ftl_file "$ftl_file"
done < <(find "$lang_dir" -name "*.ftl" -type f -print0)
# Processing based on flags
if [[ "$LEGACY_FILES" == "true" ]]; then
local legacy_file="$CONTENT_DIR/$lang.ftl"
merge_ftl_directory "$lang_dir" "$legacy_file"
fi
if [[ "$CREATE_INDICES" == "true" ]]; then
create_content_indices "$lang_dir"
fi
done
echo
log_success "Processing complete!"
if [[ "$LEGACY_FILES" == "true" ]]; then
echo "Legacy files created:"
for lang in "${LANGS[@]}"; do
echo " - $CONTENT_DIR/$lang.ftl"
done
fi
}
# Run main function
main "$@"