Commit local changes before merging with remote

This commit is contained in:
Peter Wood
2025-05-29 11:25:02 -04:00
parent 868b340fb5
commit be4f6a8d8c
75 changed files with 14107 additions and 562 deletions

227
validate-env-backups.sh Executable file
View File

@@ -0,0 +1,227 @@
#!/bin/bash
# validate-env-backups.sh - Validate .env file backups
# Author: Shell Repository
# Description: Verify integrity and consistency of .env file backups
set -e
# Colors for output
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
RED='\033[0;31m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
DOCKER_DIR="$HOME/docker"
BACKUP_DIR="$HOME/.env-backup"
LOG_FILE="$SCRIPT_DIR/logs/env-backup-validation.log"
# Ensure logs directory exists
mkdir -p "$(dirname "$LOG_FILE")"
# Logging function
log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
}
# Display usage information
usage() {
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Validate .env file backups against source files"
echo ""
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Verbose output"
echo " -s, --summary-only Show only summary"
echo " -m, --missing-only Show only missing files"
echo " -d, --diff Show differences between files"
echo ""
echo "Examples:"
echo " $0 # Basic validation"
echo " $0 --verbose # Detailed validation"
echo " $0 --missing-only # Show only missing backups"
echo " $0 --diff # Show file differences"
}
# Validate backups
validate_backups() {
local verbose="$1"
local summary_only="$2"
local missing_only="$3"
local show_diff="$4"
echo -e "${BLUE}=== .env Backup Validation ===${NC}"
echo "Source: $DOCKER_DIR"
echo "Backup: $BACKUP_DIR"
echo ""
if [ ! -d "$BACKUP_DIR" ]; then
echo -e "${RED}Error: Backup directory not found at $BACKUP_DIR${NC}"
echo "Run backup-env-files.sh --init first"
exit 1
fi
local total_source=0
local total_backup=0
local missing_backup=0
local outdated_backup=0
local identical_files=0
local different_files=0
local backup_only=0
# Arrays to store file lists
declare -a missing_files=()
declare -a outdated_files=()
declare -a different_files_list=()
declare -a backup_only_files=()
# Count and validate source files
echo -e "${YELLOW}Scanning source files...${NC}"
while IFS= read -r source_file; do
if [ -n "$source_file" ]; then
((total_source++))
# Determine backup path
local rel_path="${source_file#$DOCKER_DIR/}"
local backup_file="$BACKUP_DIR/docker-containers/$rel_path"
if [ ! -f "$backup_file" ]; then
((missing_backup++))
missing_files+=("$rel_path")
[ "$summary_only" != true ] && [ "$missing_only" != true ] && echo -e "${RED}✗ Missing backup: $rel_path${NC}"
else
# Compare files
if cmp -s "$source_file" "$backup_file"; then
((identical_files++))
[ "$verbose" = true ] && [ "$summary_only" != true ] && [ "$missing_only" != true ] && echo -e "${GREEN}✓ Identical: $rel_path${NC}"
else
# Check if backup is older
if [ "$source_file" -nt "$backup_file" ]; then
((outdated_backup++))
outdated_files+=("$rel_path")
[ "$summary_only" != true ] && [ "$missing_only" != true ] && echo -e "${YELLOW}⚠ Outdated backup: $rel_path${NC}"
else
((different_files++))
different_files_list+=("$rel_path")
[ "$summary_only" != true ] && [ "$missing_only" != true ] && echo -e "${BLUE}△ Different: $rel_path${NC}"
fi
# Show diff if requested
if [ "$show_diff" = true ] && [ "$summary_only" != true ] && [ "$missing_only" != true ]; then
echo -e "${YELLOW} Differences:${NC}"
diff -u "$backup_file" "$source_file" | head -20 || true
echo ""
fi
fi
fi
fi
done < <(find "$DOCKER_DIR" -type f \( -name "*.env" -o -name ".env*" -o -name "env.*" \) 2>/dev/null | sort)
# Check for backup-only files
echo -e "${YELLOW}Scanning backup files...${NC}"
if [ -d "$BACKUP_DIR/docker-containers" ]; then
while IFS= read -r backup_file; do
if [ -n "$backup_file" ]; then
((total_backup++))
# Determine source path
local rel_path="${backup_file#$BACKUP_DIR/docker-containers/}"
local source_file="$DOCKER_DIR/$rel_path"
if [ ! -f "$source_file" ]; then
((backup_only++))
backup_only_files+=("$rel_path")
[ "$summary_only" != true ] && [ "$missing_only" != true ] && echo -e "${BLUE}⚡ Backup only: $rel_path${NC}"
fi
fi
done < <(find "$BACKUP_DIR/docker-containers" -type f \( -name "*.env" -o -name ".env*" -o -name "env.*" \) 2>/dev/null | sort)
fi
# Display missing files if requested
if [ "$missing_only" = true ] && [ ${#missing_files[@]} -gt 0 ]; then
echo -e "${RED}=== Missing Backup Files ===${NC}"
for file in "${missing_files[@]}"; do
echo -e "${RED}$file${NC}"
done
echo ""
fi
# Summary
echo -e "${BLUE}=== Validation Summary ===${NC}"
echo -e "Source files: ${BLUE}$total_source${NC}"
echo -e "Backup files: ${BLUE}$total_backup${NC}"
echo -e "Identical: ${GREEN}$identical_files${NC}"
echo -e "Missing backups: ${RED}$missing_backup${NC}"
echo -e "Outdated backups: ${YELLOW}$outdated_backup${NC}"
echo -e "Different files: ${BLUE}$different_files${NC}"
echo -e "Backup only: ${BLUE}$backup_only${NC}"
echo ""
# Recommendations
if [ $missing_backup -gt 0 ] || [ $outdated_backup -gt 0 ]; then
echo -e "${YELLOW}=== Recommendations ===${NC}"
if [ $missing_backup -gt 0 ]; then
echo -e "${YELLOW}• Run backup-env-files.sh to backup missing files${NC}"
fi
if [ $outdated_backup -gt 0 ]; then
echo -e "${YELLOW}• Run backup-env-files.sh to update outdated backups${NC}"
fi
echo ""
fi
# Log summary
log "Validation completed - Source: $total_source, Backup: $total_backup, Missing: $missing_backup, Outdated: $outdated_backup"
# Exit with error code if issues found
if [ $missing_backup -gt 0 ] || [ $outdated_backup -gt 0 ]; then
exit 1
fi
}
# Main function
main() {
local verbose=false
local summary_only=false
local missing_only=false
local show_diff=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
case $1 in
-h|--help)
usage
exit 0
;;
-v|--verbose)
verbose=true
shift
;;
-s|--summary-only)
summary_only=true
shift
;;
-m|--missing-only)
missing_only=true
shift
;;
-d|--diff)
show_diff=true
shift
;;
*)
echo "Unknown option: $1"
usage
exit 1
;;
esac
done
validate_backups "$verbose" "$summary_only" "$missing_only" "$show_diff"
}
# Run main function with all arguments
main "$@"