Big Commit

The changes affects multiple places in the repo and this one of the rare
instances where I cant be bothered writing a comprehensive commit. Look
at the diff for changes.

Signed-off-by: Ronald Caesar <github43132@proton.me>
This commit is contained in:
Ronald Caesar 2025-09-23 19:20:25 -04:00
parent 4dd8506346
commit 6bdfd6fcea
No known key found for this signature in database
GPG key ID: 04307C401999C596
10 changed files with 669 additions and 25 deletions

381
scripts/setup_submodules.sh Executable file
View file

@ -0,0 +1,381 @@
#!/bin/bash
# Setup submodules with proper pinning configuration
# DISCLAIMER: This was written by AI. GLM-4.5 wrote this better than I ever could.
DIR="${BASH_SOURCE%/*}"
if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi
. "$DIR/log.sh"
set -uo pipefail errtrace
IFS=$'\n\t'
# Global variables
SCRIPT_NAME="$(basename "$0")"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(git rev-parse --show-toplevel)"
# Status tracking
declare -i VALIDATION_ERRORS=0
declare -i CONFIGURATION_ERRORS=0
declare -i INITIALIZATION_ERRORS=0
# =============================================================================
# VALIDATION FUNCTIONS
# =============================================================================
validate_environment() {
log_info "Validating environment..."
# Check if we're in the correct repository
if [[ ! -f ".gitmodules" ]]; then
log_critical "Not in pound repository root or .gitmodules missing"
exit 1
fi
# Check required tools
local required_tools=("git" "bash" "mkdir" "rm" "tee")
for tool in "${required_tools[@]}"; do
if ! command -v "$tool" >/dev/null 2>&1; then
log_critical "Required tool '$tool' not found in PATH"
exit 1
fi
done
# Check git repository state
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
log_critical "Not inside a git repository"
exit 1
fi
# Check for uncommitted changes
if ! git diff-index --quiet HEAD --; then
log_warn "Uncommitted changes detected - this may affect submodule setup"
fi
# Check disk space
local available_space
available_space=$(df . | awk 'NR==2 {print $4}')
if [[ $available_space -lt 1048576 ]]; then # Less than 1GB
log_warn "Low disk space available: $available_space KB"
fi
log_info "Environment validation complete."
}
validate_submodules() {
log_info "Validating submodule configuration..."
# Check if .gitmodules exists and is readable
if [[ ! -r ".gitmodules" ]]; then
log_critical ".gitmodules file not found or not readable"
exit 1
fi
# Parse and validate submodule configurations
local submodules=()
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
submodules+=("${BASH_REMATCH[1]}")
fi
done < .gitmodules
if [[ ${#submodules[@]} -eq 0 ]]; then
log_critical "No submodules found in .gitmodules"
exit 1
fi
log_info "Found ${#submodules[@]} submodules: ${submodules[*]}"
# Validate each submodule configuration
for submodule in "${submodules[@]}"; do
local submodule_path
local submodule_url
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
submodule_url=$(git config -f .gitmodules --get submodule."$submodule".url)
if [[ -z "$submodule_path" ]]; then
log_error "Missing path configuration for submodule '$submodule'"
((VALIDATION_ERRORS++))
fi
if [[ -z "$submodule_url" ]]; then
log_error "Missing URL configuration for submodule '$submodule'"
((VALIDATION_ERRORS++))
fi
# Validate URL format
if [[ "$submodule_url" =~ ^(https?|git):// ]] || [[ "$submodule_url" =~ ^git@ ]]; then
log_info "Submodule '$submodule' URL format valid: $submodule_url"
else
log_error "Invalid URL format for submodule '$submodule': $submodule_url"
((VALIDATION_ERRORS++))
fi
done
if [[ $VALIDATION_ERRORS -gt 0 ]]; then
log_critical "Submodule configuration validation failed with $VALIDATION_ERRORS errors"
exit 1
fi
log_info "Submodule configuration validation complete."
}
# =============================================================================
# EXECUTION FUNCTIONS
# =============================================================================
initialize_submodules() {
local max_retries=3
local retry_delay=5
local success_count=0
local failure_count=0
# Get list of submodules
local submodules=()
local submodule_paths=()
# Parse .gitmodules file
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule_name="${BASH_REMATCH[1]}"
submodules+=("$submodule_name")
# Get the path for this submodule
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule_name".path)
submodule_paths+=("$submodule_path")
fi
done < .gitmodules
log_info "Found ${#submodules[@]} submodules to initialize"
# Process each submodule
for i in "${!submodules[@]}"; do
local submodule="${submodules[i]}"
local submodule_path="${submodule_paths[i]}"
log_info "Submodule path: '$submodule_path'"
# Try to initialize the submodule
local submodule_initialized=false
for ((attempt=1; attempt<=max_retries; attempt++)); do
log_info "Attempt $attempt of $max_retries for submodule '$submodule'"
# Execute git command with explicit error handling
local output
output=$(git submodule update --init "$submodule_path" 2>&1)
local exit_code=$?
if [[ $exit_code -eq 0 ]]; then
log_info "Successfully initialized submodule '$submodule'"
((success_count++))
submodule_initialized=true
break
else
log_warn "Failed to initialize submodule '$submodule' (exit code: $exit_code)"
log_warn "Git output: $output"
if [[ $attempt -lt $max_retries ]]; then
log_info "Waiting $retry_delay seconds before retry..."
sleep $retry_delay
else
log_error "Failed to initialize submodule '$submodule' after $max_retries attempts"
((failure_count++))
fi
fi
done
done
log_info "Results: $success_count successful, $failure_count failed"
# Return success even if some submodules failed
# We'll handle failures in the validation phase
return 0
}
configure_submodules() {
log_info "Configuring submodules to prevent automatic updates..."
# Get all configured submodules
local submodules=()
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
submodules+=("${BASH_REMATCH[1]}")
fi
done < .gitmodules
local configured_count=0
local failed_count=0
for submodule in "${submodules[@]}"; do
log_info "Configuring submodule: $submodule"
if git config "submodule.$submodule.update" none; then
log_info "Successfully configured $submodule"
((configured_count++))
else
log_error "Failed to configure $submodule"
((failed_count++))
fi
done
log_info "Configuration complete: $configured_count successful, $failed_count failed"
# Return success even if some configurations failed
return 0
}
validate_setup() {
log_info "Validating submodule setup..."
local validation_errors=0
# Check each submodule
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule="${BASH_REMATCH[1]}"
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
# Check if submodule directory exists
if [[ ! -d "$submodule_path" ]]; then
log_error "Submodule directory '$submodule_path' does not exist"
((validation_errors++))
continue
fi
# Check if it's a valid git repository
if [[ ! -f "$submodule_path/.git" ]]; then
log_error "Submodule '$submodule_path' is not a valid git repository"
((validation_errors++))
continue
fi
# Check if submodule is properly initialized
if ! (cd "$submodule_path" && git rev-parse --git-dir >/dev/null 2>&1); then
log_error "Submodule '$submodule_path' is not properly initialized"
((validation_errors++))
continue
fi
# Check update configuration
local update_config
update_config=$(git config submodule."$submodule".update)
if [[ "$update_config" != "none" ]]; then
log_error "Submodule '$submodule' update configuration is '$update_config', expected 'none'"
((validation_errors++))
fi
log_info "Submodule '$submodule' validation passed"
fi
done < .gitmodules
if [[ $validation_errors -gt 0 ]]; then
log_critical "Setup validation failed with $validation_errors errors"
exit 1
fi
log_info "All submodules validated successfully"
return 0
}
# =============================================================================
# CLEANUP FUNCTIONS
# =============================================================================
cleanup_on_failure() {
log_warn "Initiating cleanup due to failure..."
# Remove any partially initialized submodules
while IFS= read -r line; do
if [[ $line =~ ^\[submodule\ \"(.*)\"\]$ ]]; then
local submodule="${BASH_REMATCH[1]}"
local submodule_path
submodule_path=$(git config -f .gitmodules --get submodule."$submodule".path)
if [[ -d "$submodule_path" ]]; then
log_info "Cleaning up partially initialized submodule: $submodule_path"
rm -rf "$submodule_path"
fi
fi
done < .gitmodules
# Clean up temporary files
if [[ -d "$TEMP_DIR" ]]; then
log_info "Cleaning up temporary directory: $TEMP_DIR"
rm -rf "$TEMP_DIR"
fi
log_info "Cleanup complete"
}
# =============================================================================
# DISPLAY FUNCTIONS
# =============================================================================
display_header() {
cat << 'EOF'
===============================================================================
POUND SUBMODULE SETUP
===============================================================================
This script configures submodules with commit pinning for stability.
WARNING: This operation modifies Git configuration and affects repository state.
Result:
- Submodules will be initialized and pinned to specific commits
- Automatic updates will be disabled
===============================================================================
EOF
}
display_summary() {
cat << 'EOF'
===============================================================================
SUMMARY
===============================================================================
Submodule setup completed successfully.
SYSTEM STATUS: STABLE
SUBMODULES: PINNED
AUTOMATIC UPDATES: DISABLED
Next Steps:
1. Verify submodule configurations in .gitmodules
2. Review pinned versions in 3rd_party/PINNED_VERSIONS.md
3. Test build system with pinned submodules
===============================================================================
EOF
}
# =============================================================================
# MAIN
# =============================================================================
main() {
# Display mission header
display_header
# Change to repository root
cd "$REPO_ROOT"
# Execute phases
validate_environment
validate_submodules
initialize_submodules
configure_submodules
validate_setup
display_summary
log_info "Submodule setup successful"
exit 0
}
# Execute main function
main "$@"