#!/usr/bin/env zsh # Color definitions autoload -U colors && colors BOLD="\033[1m" RESET="\033[0m" GREEN="\033[32m" BLUE="\033[34m" YELLOW="\033[33m" RED="\033[31m" # Configuration SCRIPT_DIR="${0:a:h}" SYSTEM_DIR="${SCRIPT_DIR}/../system" MODULES_DIR="${SCRIPT_DIR}/.." CONFIG_SOURCE="/etc/nixos/configuration.nix" MODULES_SOURCE="/etc/nixos/modules" # Function to print colored messages (use printf for portability) print_info() { printf "%b\n" "${BLUE}${BOLD}[INFO]${RESET} $1"; } print_success(){ printf "%b\n" "${GREEN}${BOLD}[SUCCESS]${RESET} $1"; } print_error() { printf "%b\n" "${RED}${BOLD}[ERROR]${RESET} $1"; } print_warn() { printf "%b\n" "${YELLOW}${BOLD}[WARN]${RESET} $1"; } # Check if running from correct directory if [[ ! -d "$SYSTEM_DIR" ]]; then print_error "System directory not found: $SYSTEM_DIR" exit 1 fi # Get available system configurations (use portable glob + basename) systems=() for f in "$SYSTEM_DIR"/*.nix; do [ -f "$f" ] || continue base="$(basename "$f")" systems+=("${base%.nix}") done if [[ ${#systems[@]} -eq 0 ]]; then print_error "No system configurations found in $SYSTEM_DIR" exit 1 fi # Check for command-line argument selected_system="" if [[ -n "$1" ]]; then # Argument provided, check membership with explicit loop for s in "${systems[@]}"; do if [[ "$s" == "$1" ]]; then selected_system="$1" break fi done if [[ -n "$selected_system" ]]; then print_info "Preselected system: ${BOLD}${selected_system}${RESET}" else print_error "Invalid system: $1" print_info "Available systems: ${systems[*]}" exit 1 fi else # Interactive selection print_info "Available system configurations:" echo "" i=1 for s in "${systems[@]}"; do printf " %b)%b %s\n" "${GREEN}${i}" "${RESET}" "$s" i=$((i+1)) done echo "" # Prompt for selection while true; do printf "%b" "${BOLD}Select a system configuration (1-${#systems[@]}): ${RESET}" read -r selection if [[ "$selection" =~ ^[0-9]+$ ]] && (( selection >= 1 && selection <= ${#systems[@]} )); then selected_system="${systems[$selection]}" break else print_error "Invalid selection. Please enter a number between 1 and ${#systems[@]}" fi done fi # Confirm selection print_info "Selected: ${BOLD}${selected_system}${RESET}" printf "%b" "${YELLOW}${BOLD}Continue? (y/N): ${RESET}" read -r confirm if [[ ! "$confirm" =~ ^[Yy]$ ]]; then print_warn "Aborted by user" exit 0 fi # Execute push steps print_info "Starting push process..." echo "" # Step 1: Rebuild system print_info "Rebuilding NixOS system..." echo "" if sudo nixos-rebuild switch --upgrade-all; then print_success "System rebuild completed" else print_error "System rebuild failed" exit 1 fi # Step 2: Git pull print_info "Pulling latest changes from git..." if git pull; then print_success "Git pull completed" else print_error "Git pull failed" exit 1 fi # Step 3: Copy configuration from /etc/nixos back to repo target_file="${SYSTEM_DIR}/${selected_system}.nix" print_info "Copying ${BOLD}${CONFIG_SOURCE}${RESET} to ${BOLD}${target_file}${RESET}..." if sudo cp "$CONFIG_SOURCE" "$target_file"; then print_success "Configuration copied" else print_error "Failed to copy configuration" exit 1 fi # Step 4: Sync modules directory back to repo print_info "Syncing modules from ${BOLD}${MODULES_SOURCE}${RESET}..." if sudo rsync -av --delete --exclude='scripts' "${MODULES_SOURCE}/" "${MODULES_DIR}/"; then print_success "Modules synced" else print_error "Failed to sync modules" exit 1 fi # Step 5: Add files to git print_info "Adding changes to git..." if git add "${target_file}"; then print_success "Files staged" else print_error "Failed to stage files" exit 1 fi # Step 6: Commit with timestamp timestamp=$(date) commit_message="Update local Nix Config - ${selected_system} - ${timestamp}" print_info "Committing changes..." if git commit -m "${commit_message}"; then print_success "Changes committed" else print_warn "No changes to commit or commit failed" fi # Step 7: Push to remote print_info "Pushing to remote repository..." if git push; then print_success "Changes pushed to remote" else print_error "Failed to push changes" exit 1 fi echo "" print_success "${BOLD}Push complete!${RESET}" print_info "System: ${BOLD}${selected_system}${RESET}" print_info "Commit: ${commit_message}"