feat(core): complete phase 0 infrastructure with helpers and main orchestrator
- commit
- 37e8d87f36805b7efbd8acc5a8690fb5edffec85
- author
- bnema · · 2025-10-19 07:08 UTC
- parent
- b11f127
- signature
- unsigned
11 files · +605 -1
M .gitignore +1 -0
| @@ -12,3 +12,4 @@ | |||
| 12 | 12 | ||
| 13 | 13 | pkg/ | |
| 14 | 14 | src/ | |
| 15 | + | CLAUDE.md | |
| @@ -12,3 +12,4 @@ | |||||
| 12 | 12 | ||||
| 13 | pkg/ | 13 | pkg/ | ||
| 14 | src/ | 14 | src/ | ||
| 15 | + | CLAUDE.md | |||
A Makefile +56 -0
| @@ -0,0 +1,56 @@ | |||
| 1 | + | .PHONY: check check-syntax check-shellcheck clean help | |
| 2 | + | ||
| 3 | + | # Default target | |
| 4 | + | help: | |
| 5 | + | @echo "archup - Makefile targets:" | |
| 6 | + | @echo "" | |
| 7 | + | @echo " make check - Run all checks (syntax + shellcheck)" | |
| 8 | + | @echo " make check-syntax - Check shell script syntax with bash -n" | |
| 9 | + | @echo " make check-shellcheck - Run shellcheck linting" | |
| 10 | + | @echo " make clean - Remove generated files" | |
| 11 | + | @echo "" | |
| 12 | + | ||
| 13 | + | # Run all checks | |
| 14 | + | check: check-syntax check-shellcheck | |
| 15 | + | @echo "" | |
| 16 | + | @echo "✓ All checks passed!" | |
| 17 | + | ||
| 18 | + | # Check syntax with bash -n | |
| 19 | + | check-syntax: | |
| 20 | + | @echo "=========================================" | |
| 21 | + | @echo "Checking shell script syntax..." | |
| 22 | + | @echo "=========================================" | |
| 23 | + | @for script in install.sh install/helpers/*.sh; do \ | |
| 24 | + | if [ -f "$$script" ]; then \ | |
| 25 | + | echo "Checking: $$script"; \ | |
| 26 | + | bash -n "$$script" || exit 1; \ | |
| 27 | + | fi \ | |
| 28 | + | done | |
| 29 | + | @echo "✓ Syntax check passed" | |
| 30 | + | ||
| 31 | + | # Run shellcheck | |
| 32 | + | check-shellcheck: | |
| 33 | + | @echo "" | |
| 34 | + | @echo "=========================================" | |
| 35 | + | @echo "Running shellcheck..." | |
| 36 | + | @echo "=========================================" | |
| 37 | + | @if ! command -v shellcheck >/dev/null 2>&1; then \ | |
| 38 | + | echo "⚠ shellcheck not found, skipping..."; \ | |
| 39 | + | echo "Install with: sudo pacman -S shellcheck"; \ | |
| 40 | + | exit 0; \ | |
| 41 | + | fi | |
| 42 | + | @for script in install.sh install/helpers/*.sh; do \ | |
| 43 | + | if [ -f "$$script" ]; then \ | |
| 44 | + | echo ""; \ | |
| 45 | + | echo "Checking: $$script"; \ | |
| 46 | + | shellcheck --exclude=SC1091,SC2086,SC2004,SC2059,SC2129,SC2155 "$$script" || exit 1; \ | |
| 47 | + | fi \ | |
| 48 | + | done | |
| 49 | + | @echo "" | |
| 50 | + | @echo "✓ shellcheck passed" | |
| 51 | + | ||
| 52 | + | # Clean generated files | |
| 53 | + | clean: | |
| 54 | + | @echo "Cleaning generated files..." | |
| 55 | + | @rm -f /var/log/archup-install.log | |
| 56 | + | @echo "✓ Clean complete" | |
| @@ -0,0 +1,56 @@ | |||||
| 1 | + | .PHONY: check check-syntax check-shellcheck clean help | |||
| 2 | + | ||||
| 3 | + | # Default target | |||
| 4 | + | help: | |||
| 5 | + | @echo "archup - Makefile targets:" | |||
| 6 | + | @echo "" | |||
| 7 | + | @echo " make check - Run all checks (syntax + shellcheck)" | |||
| 8 | + | @echo " make check-syntax - Check shell script syntax with bash -n" | |||
| 9 | + | @echo " make check-shellcheck - Run shellcheck linting" | |||
| 10 | + | @echo " make clean - Remove generated files" | |||
| 11 | + | @echo "" | |||
| 12 | + | ||||
| 13 | + | # Run all checks | |||
| 14 | + | check: check-syntax check-shellcheck | |||
| 15 | + | @echo "" | |||
| 16 | + | @echo "✓ All checks passed!" | |||
| 17 | + | ||||
| 18 | + | # Check syntax with bash -n | |||
| 19 | + | check-syntax: | |||
| 20 | + | @echo "=========================================" | |||
| 21 | + | @echo "Checking shell script syntax..." | |||
| 22 | + | @echo "=========================================" | |||
| 23 | + | @for script in install.sh install/helpers/*.sh; do \ | |||
| 24 | + | if [ -f "$$script" ]; then \ | |||
| 25 | + | echo "Checking: $$script"; \ | |||
| 26 | + | bash -n "$$script" || exit 1; \ | |||
| 27 | + | fi \ | |||
| 28 | + | done | |||
| 29 | + | @echo "✓ Syntax check passed" | |||
| 30 | + | ||||
| 31 | + | # Run shellcheck | |||
| 32 | + | check-shellcheck: | |||
| 33 | + | @echo "" | |||
| 34 | + | @echo "=========================================" | |||
| 35 | + | @echo "Running shellcheck..." | |||
| 36 | + | @echo "=========================================" | |||
| 37 | + | @if ! command -v shellcheck >/dev/null 2>&1; then \ | |||
| 38 | + | echo "⚠ shellcheck not found, skipping..."; \ | |||
| 39 | + | echo "Install with: sudo pacman -S shellcheck"; \ | |||
| 40 | + | exit 0; \ | |||
| 41 | + | fi | |||
| 42 | + | @for script in install.sh install/helpers/*.sh; do \ | |||
| 43 | + | if [ -f "$$script" ]; then \ | |||
| 44 | + | echo ""; \ | |||
| 45 | + | echo "Checking: $$script"; \ | |||
| 46 | + | shellcheck --exclude=SC1091,SC2086,SC2004,SC2059,SC2129,SC2155 "$$script" || exit 1; \ | |||
| 47 | + | fi \ | |||
| 48 | + | done | |||
| 49 | + | @echo "" | |||
| 50 | + | @echo "✓ shellcheck passed" | |||
| 51 | + | ||||
| 52 | + | # Clean generated files | |||
| 53 | + | clean: | |||
| 54 | + | @echo "Cleaning generated files..." | |||
| 55 | + | @rm -f /var/log/archup-install.log | |||
| 56 | + | @echo "✓ Clean complete" | |||
M README.md +116 -1
| @@ -1,2 +1,117 @@ | |||
| 1 | 1 | # archup | |
| 2 | - | A fast, minimal Arch Linux auto-installer alternative to archinstall | |
| 2 | + | ||
| 3 | + | **A fast, minimal Arch Linux auto-installer alternative to archinstall** | |
| 4 | + | ||
| 5 | + | ## Project Status | |
| 6 | + | ||
| 7 | + | ✅ **Phase 0: Core Infrastructure - COMPLETE** | |
| 8 | + | ||
| 9 | + | ### Completed | |
| 10 | + | - ✅ Project structure created | |
| 11 | + | - ✅ Helper utilities implemented (logging, errors, presentation, chroot) | |
| 12 | + | - ✅ Main orchestrator (install.sh) | |
| 13 | + | - ✅ Barebone package list | |
| 14 | + | - ✅ Logo designed | |
| 15 | + | ||
| 16 | + | ### Project Structure | |
| 17 | + | ``` | |
| 18 | + | archup/ | |
| 19 | + | ├── README.md | |
| 20 | + | ├── logo.txt | |
| 21 | + | ├── install.sh # Main orchestrator | |
| 22 | + | ├── install/ | |
| 23 | + | │ ├── helpers/ | |
| 24 | + | │ │ ├── all.sh # Source all helpers | |
| 25 | + | │ │ ├── logging.sh # Log file + colorized output | |
| 26 | + | │ │ ├── errors.sh # Trap handlers, error display | |
| 27 | + | │ │ ├── presentation.sh # UI helpers (cursor, colors) | |
| 28 | + | │ │ └── chroot.sh # Chroot utilities | |
| 29 | + | │ ├── preflight/ # (Phase 1 - TODO) | |
| 30 | + | │ ├── partitioning/ # (Phase 2 - TODO) | |
| 31 | + | │ ├── base/ # (Phase 3 - TODO) | |
| 32 | + | │ ├── config/ # (Phase 4 - TODO) | |
| 33 | + | │ ├── security/ # (Phase 5 - TODO) | |
| 34 | + | │ ├── bootloader/ # (Phase 6 - TODO) | |
| 35 | + | │ ├── post-install/ # (Phase 7 - TODO) | |
| 36 | + | │ └── presets/ | |
| 37 | + | │ └── barebone.packages # Minimal package list (~15 packages) | |
| 38 | + | ├── bin/ # (Future utilities) | |
| 39 | + | └── docs/ # (Future documentation) | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | ## Installation | |
| 43 | + | ||
| 44 | + | ### Quick Install (from Arch ISO) | |
| 45 | + | ||
| 46 | + | ```bash | |
| 47 | + | # Download and run archup installer | |
| 48 | + | wget -O- https://raw.githubusercontent.com/bnema/archup/main/install.sh | bash | |
| 49 | + | ``` | |
| 50 | + | ||
| 51 | + | Or download first, then run: | |
| 52 | + | ||
| 53 | + | ```bash | |
| 54 | + | # Download the installer | |
| 55 | + | wget https://raw.githubusercontent.com/bnema/archup/main/install.sh | |
| 56 | + | ||
| 57 | + | # Make it executable | |
| 58 | + | chmod +x install.sh | |
| 59 | + | ||
| 60 | + | # Run the installer | |
| 61 | + | ./install.sh | |
| 62 | + | ``` | |
| 63 | + | ||
| 64 | + | **Note:** Currently in Phase 0 development. Full installation not yet available. | |
| 65 | + | ||
| 66 | + | --- | |
| 67 | + | ||
| 68 | + | ## Development | |
| 69 | + | ||
| 70 | + | ### Testing Syntax | |
| 71 | + | ```bash | |
| 72 | + | # Check all shell scripts for syntax errors and linting issues | |
| 73 | + | make check | |
| 74 | + | ||
| 75 | + | # Check syntax only (bash -n) | |
| 76 | + | make check-syntax | |
| 77 | + | ||
| 78 | + | # Run shellcheck linting | |
| 79 | + | make check-shellcheck | |
| 80 | + | ``` | |
| 81 | + | ||
| 82 | + | ### Testing Installation (Phase 0) | |
| 83 | + | Currently in development. To test Phase 0: | |
| 84 | + | ||
| 85 | + | ```bash | |
| 86 | + | # Set the archup path | |
| 87 | + | export ARCHUP_PATH=/path/to/archup | |
| 88 | + | ||
| 89 | + | # Run the installer (currently just tests helpers) | |
| 90 | + | ./install.sh | |
| 91 | + | ``` | |
| 92 | + | ||
| 93 | + | ## Environment Variables | |
| 94 | + | ||
| 95 | + | - `ARCHUP_PATH` - Installation directory (default: `$HOME/.local/share/archup`) | |
| 96 | + | - `ARCHUP_REPO_URL` - Repository URL for bug reports (default: `https://github.com/bnema/archup`) | |
| 97 | + | - `ARCHUP_CHROOT_INSTALL` - Set to `1` for chroot mode | |
| 98 | + | ||
| 99 | + | ## Next Steps | |
| 100 | + | ||
| 101 | + | **Phase 1: Preflight Validation** (Week 1) | |
| 102 | + | - [ ] Guards (vanilla Arch check) | |
| 103 | + | - [ ] UEFI check | |
| 104 | + | - [ ] x86_64 architecture check | |
| 105 | + | - [ ] Secure Boot disabled check | |
| 106 | + | - [ ] Begin installation (display logo, start log) | |
| 107 | + | ||
| 108 | + | ## Reference | |
| 109 | + | ||
| 110 | + | Inspired by: | |
| 111 | + | - **Omarchy installer** - Modular architecture and security implementations | |
| 112 | + | - **archinstall** - Official Arch installer | |
| 113 | + | - **Arch philosophy** - Simplicity, minimalism, user choice | |
| 114 | + | ||
| 115 | + | ## License | |
| 116 | + | ||
| 117 | + | TBD⏎̸ | |
| @@ -1,2 +1,117 @@ | |||||
| 1 | # archup | 1 | # archup | ||
| 2 | - | A fast, minimal Arch Linux auto-installer alternative to archinstall | 2 | + | |
| 3 | + | **A fast, minimal Arch Linux auto-installer alternative to archinstall** | |||
| 4 | + | ||||
| 5 | + | ## Project Status | |||
| 6 | + | ||||
| 7 | + | ✅ **Phase 0: Core Infrastructure - COMPLETE** | |||
| 8 | + | ||||
| 9 | + | ### Completed | |||
| 10 | + | - ✅ Project structure created | |||
| 11 | + | - ✅ Helper utilities implemented (logging, errors, presentation, chroot) | |||
| 12 | + | - ✅ Main orchestrator (install.sh) | |||
| 13 | + | - ✅ Barebone package list | |||
| 14 | + | - ✅ Logo designed | |||
| 15 | + | ||||
| 16 | + | ### Project Structure | |||
| 17 | + | ``` | |||
| 18 | + | archup/ | |||
| 19 | + | ├── README.md | |||
| 20 | + | ├── logo.txt | |||
| 21 | + | ├── install.sh # Main orchestrator | |||
| 22 | + | ├── install/ | |||
| 23 | + | │ ├── helpers/ | |||
| 24 | + | │ │ ├── all.sh # Source all helpers | |||
| 25 | + | │ │ ├── logging.sh # Log file + colorized output | |||
| 26 | + | │ │ ├── errors.sh # Trap handlers, error display | |||
| 27 | + | │ │ ├── presentation.sh # UI helpers (cursor, colors) | |||
| 28 | + | │ │ └── chroot.sh # Chroot utilities | |||
| 29 | + | │ ├── preflight/ # (Phase 1 - TODO) | |||
| 30 | + | │ ├── partitioning/ # (Phase 2 - TODO) | |||
| 31 | + | │ ├── base/ # (Phase 3 - TODO) | |||
| 32 | + | │ ├── config/ # (Phase 4 - TODO) | |||
| 33 | + | │ ├── security/ # (Phase 5 - TODO) | |||
| 34 | + | │ ├── bootloader/ # (Phase 6 - TODO) | |||
| 35 | + | │ ├── post-install/ # (Phase 7 - TODO) | |||
| 36 | + | │ └── presets/ | |||
| 37 | + | │ └── barebone.packages # Minimal package list (~15 packages) | |||
| 38 | + | ├── bin/ # (Future utilities) | |||
| 39 | + | └── docs/ # (Future documentation) | |||
| 40 | + | ``` | |||
| 41 | + | ||||
| 42 | + | ## Installation | |||
| 43 | + | ||||
| 44 | + | ### Quick Install (from Arch ISO) | |||
| 45 | + | ||||
| 46 | + | ```bash | |||
| 47 | + | # Download and run archup installer | |||
| 48 | + | wget -O- https://raw.githubusercontent.com/bnema/archup/main/install.sh | bash | |||
| 49 | + | ``` | |||
| 50 | + | ||||
| 51 | + | Or download first, then run: | |||
| 52 | + | ||||
| 53 | + | ```bash | |||
| 54 | + | # Download the installer | |||
| 55 | + | wget https://raw.githubusercontent.com/bnema/archup/main/install.sh | |||
| 56 | + | ||||
| 57 | + | # Make it executable | |||
| 58 | + | chmod +x install.sh | |||
| 59 | + | ||||
| 60 | + | # Run the installer | |||
| 61 | + | ./install.sh | |||
| 62 | + | ``` | |||
| 63 | + | ||||
| 64 | + | **Note:** Currently in Phase 0 development. Full installation not yet available. | |||
| 65 | + | ||||
| 66 | + | --- | |||
| 67 | + | ||||
| 68 | + | ## Development | |||
| 69 | + | ||||
| 70 | + | ### Testing Syntax | |||
| 71 | + | ```bash | |||
| 72 | + | # Check all shell scripts for syntax errors and linting issues | |||
| 73 | + | make check | |||
| 74 | + | ||||
| 75 | + | # Check syntax only (bash -n) | |||
| 76 | + | make check-syntax | |||
| 77 | + | ||||
| 78 | + | # Run shellcheck linting | |||
| 79 | + | make check-shellcheck | |||
| 80 | + | ``` | |||
| 81 | + | ||||
| 82 | + | ### Testing Installation (Phase 0) | |||
| 83 | + | Currently in development. To test Phase 0: | |||
| 84 | + | ||||
| 85 | + | ```bash | |||
| 86 | + | # Set the archup path | |||
| 87 | + | export ARCHUP_PATH=/path/to/archup | |||
| 88 | + | ||||
| 89 | + | # Run the installer (currently just tests helpers) | |||
| 90 | + | ./install.sh | |||
| 91 | + | ``` | |||
| 92 | + | ||||
| 93 | + | ## Environment Variables | |||
| 94 | + | ||||
| 95 | + | - `ARCHUP_PATH` - Installation directory (default: `$HOME/.local/share/archup`) | |||
| 96 | + | - `ARCHUP_REPO_URL` - Repository URL for bug reports (default: `https://github.com/bnema/archup`) | |||
| 97 | + | - `ARCHUP_CHROOT_INSTALL` - Set to `1` for chroot mode | |||
| 98 | + | ||||
| 99 | + | ## Next Steps | |||
| 100 | + | ||||
| 101 | + | **Phase 1: Preflight Validation** (Week 1) | |||
| 102 | + | - [ ] Guards (vanilla Arch check) | |||
| 103 | + | - [ ] UEFI check | |||
| 104 | + | - [ ] x86_64 architecture check | |||
| 105 | + | - [ ] Secure Boot disabled check | |||
| 106 | + | - [ ] Begin installation (display logo, start log) | |||
| 107 | + | ||||
| 108 | + | ## Reference | |||
| 109 | + | ||||
| 110 | + | Inspired by: | |||
| 111 | + | - **Omarchy installer** - Modular architecture and security implementations | |||
| 112 | + | - **archinstall** - Official Arch installer | |||
| 113 | + | - **Arch philosophy** - Simplicity, minimalism, user choice | |||
| 114 | + | ||||
| 115 | + | ## License | |||
| 116 | + | ||||
| 117 | + | TBD⏎̸ | |||
A install.sh +50 -0
| @@ -0,0 +1,50 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # archup - Fast, minimal Arch Linux auto-installer | |
| 3 | + | # Main installation orchestrator | |
| 4 | + | ||
| 5 | + | set -eEo pipefail | |
| 6 | + | ||
| 7 | + | # Export global paths | |
| 8 | + | export ARCHUP_PATH="${ARCHUP_PATH:-$HOME/.local/share/archup}" | |
| 9 | + | export ARCHUP_INSTALL="$ARCHUP_PATH/install" | |
| 10 | + | export ARCHUP_INSTALL_LOG_FILE="/var/log/archup-install.log" | |
| 11 | + | export ARCHUP_REPO_URL="${ARCHUP_REPO_URL:-https://github.com/bnema/archup}" | |
| 12 | + | ||
| 13 | + | # Source all helper utilities | |
| 14 | + | source "$ARCHUP_INSTALL/helpers/all.sh" | |
| 15 | + | ||
| 16 | + | # Display logo and start installation | |
| 17 | + | clear_logo | |
| 18 | + | start_install_log | |
| 19 | + | ||
| 20 | + | # Phase 0 test: Display welcome message | |
| 21 | + | gum style --foreground 4 --padding "1 0 1 $PADDING_LEFT" "Welcome to archup!" | |
| 22 | + | gum style --padding "0 0 0 $PADDING_LEFT" "Phase 0: Testing helper utilities..." | |
| 23 | + | ||
| 24 | + | # Test logging | |
| 25 | + | echo "Testing logging functionality..." | tee -a "$ARCHUP_INSTALL_LOG_FILE" | |
| 26 | + | sleep 1 | |
| 27 | + | ||
| 28 | + | # Test gum styling | |
| 29 | + | gum style --foreground 2 --padding "1 0 0 $PADDING_LEFT" "✓ Helpers loaded successfully" | |
| 30 | + | gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "✓ Logging initialized" | |
| 31 | + | gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "✓ Error handling ready" | |
| 32 | + | gum style --foreground 2 --padding "0 0 1 $PADDING_LEFT" "✓ Presentation utilities working" | |
| 33 | + | ||
| 34 | + | # Test confirmation prompt | |
| 35 | + | if gum confirm "Continue with Phase 0 test?"; then | |
| 36 | + | gum style --foreground 4 --padding "1 0 0 $PADDING_LEFT" "Great! Phase 0 infrastructure is ready." | |
| 37 | + | gum style --padding "0 0 0 $PADDING_LEFT" "Next steps:" | |
| 38 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 1: Preflight validation" | |
| 39 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 2: Partitioning & encryption" | |
| 40 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 3: Base installation" | |
| 41 | + | echo | |
| 42 | + | else | |
| 43 | + | gum style --foreground 3 --padding "1 0 1 $PADDING_LEFT" "Installation cancelled by user" | |
| 44 | + | exit 0 | |
| 45 | + | fi | |
| 46 | + | ||
| 47 | + | # Stop logging and cleanup | |
| 48 | + | stop_install_log | |
| 49 | + | ||
| 50 | + | gum style --foreground 2 --padding "1 0 1 $PADDING_LEFT" "Phase 0 complete! ✓" | |
| @@ -0,0 +1,50 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # archup - Fast, minimal Arch Linux auto-installer | |||
| 3 | + | # Main installation orchestrator | |||
| 4 | + | ||||
| 5 | + | set -eEo pipefail | |||
| 6 | + | ||||
| 7 | + | # Export global paths | |||
| 8 | + | export ARCHUP_PATH="${ARCHUP_PATH:-$HOME/.local/share/archup}" | |||
| 9 | + | export ARCHUP_INSTALL="$ARCHUP_PATH/install" | |||
| 10 | + | export ARCHUP_INSTALL_LOG_FILE="/var/log/archup-install.log" | |||
| 11 | + | export ARCHUP_REPO_URL="${ARCHUP_REPO_URL:-https://github.com/bnema/archup}" | |||
| 12 | + | ||||
| 13 | + | # Source all helper utilities | |||
| 14 | + | source "$ARCHUP_INSTALL/helpers/all.sh" | |||
| 15 | + | ||||
| 16 | + | # Display logo and start installation | |||
| 17 | + | clear_logo | |||
| 18 | + | start_install_log | |||
| 19 | + | ||||
| 20 | + | # Phase 0 test: Display welcome message | |||
| 21 | + | gum style --foreground 4 --padding "1 0 1 $PADDING_LEFT" "Welcome to archup!" | |||
| 22 | + | gum style --padding "0 0 0 $PADDING_LEFT" "Phase 0: Testing helper utilities..." | |||
| 23 | + | ||||
| 24 | + | # Test logging | |||
| 25 | + | echo "Testing logging functionality..." | tee -a "$ARCHUP_INSTALL_LOG_FILE" | |||
| 26 | + | sleep 1 | |||
| 27 | + | ||||
| 28 | + | # Test gum styling | |||
| 29 | + | gum style --foreground 2 --padding "1 0 0 $PADDING_LEFT" "✓ Helpers loaded successfully" | |||
| 30 | + | gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "✓ Logging initialized" | |||
| 31 | + | gum style --foreground 2 --padding "0 0 0 $PADDING_LEFT" "✓ Error handling ready" | |||
| 32 | + | gum style --foreground 2 --padding "0 0 1 $PADDING_LEFT" "✓ Presentation utilities working" | |||
| 33 | + | ||||
| 34 | + | # Test confirmation prompt | |||
| 35 | + | if gum confirm "Continue with Phase 0 test?"; then | |||
| 36 | + | gum style --foreground 4 --padding "1 0 0 $PADDING_LEFT" "Great! Phase 0 infrastructure is ready." | |||
| 37 | + | gum style --padding "0 0 0 $PADDING_LEFT" "Next steps:" | |||
| 38 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 1: Preflight validation" | |||
| 39 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 2: Partitioning & encryption" | |||
| 40 | + | gum style --padding "0 0 0 $PADDING_LEFT" " • Phase 3: Base installation" | |||
| 41 | + | echo | |||
| 42 | + | else | |||
| 43 | + | gum style --foreground 3 --padding "1 0 1 $PADDING_LEFT" "Installation cancelled by user" | |||
| 44 | + | exit 0 | |||
| 45 | + | fi | |||
| 46 | + | ||||
| 47 | + | # Stop logging and cleanup | |||
| 48 | + | stop_install_log | |||
| 49 | + | ||||
| 50 | + | gum style --foreground 2 --padding "1 0 1 $PADDING_LEFT" "Phase 0 complete! ✓" | |||
A install/helpers/all.sh +8 -0
| @@ -0,0 +1,8 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Source all helper utilities | |
| 3 | + | # This file is sourced by install.sh to load all helper functions | |
| 4 | + | ||
| 5 | + | source "$ARCHUP_INSTALL/helpers/presentation.sh" | |
| 6 | + | source "$ARCHUP_INSTALL/helpers/logging.sh" | |
| 7 | + | source "$ARCHUP_INSTALL/helpers/errors.sh" | |
| 8 | + | source "$ARCHUP_INSTALL/helpers/chroot.sh" | |
| @@ -0,0 +1,8 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Source all helper utilities | |||
| 3 | + | # This file is sourced by install.sh to load all helper functions | |||
| 4 | + | ||||
| 5 | + | source "$ARCHUP_INSTALL/helpers/presentation.sh" | |||
| 6 | + | source "$ARCHUP_INSTALL/helpers/logging.sh" | |||
| 7 | + | source "$ARCHUP_INSTALL/helpers/errors.sh" | |||
| 8 | + | source "$ARCHUP_INSTALL/helpers/chroot.sh" | |||
A install/helpers/chroot.sh +15 -0
| @@ -0,0 +1,15 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Chroot utilities for archup installer | |
| 3 | + | # Adapted from Omarchy chroot.sh | |
| 4 | + | ||
| 5 | + | # Starting the installer with ARCHUP_CHROOT_INSTALL=1 will put it into chroot mode | |
| 6 | + | chrootable_systemctl_enable() { | |
| 7 | + | if [ -n "${ARCHUP_CHROOT_INSTALL:-}" ]; then | |
| 8 | + | sudo systemctl enable $1 | |
| 9 | + | else | |
| 10 | + | sudo systemctl enable --now $1 | |
| 11 | + | fi | |
| 12 | + | } | |
| 13 | + | ||
| 14 | + | # Export the function so it's available in subshells | |
| 15 | + | export -f chrootable_systemctl_enable | |
| @@ -0,0 +1,15 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Chroot utilities for archup installer | |||
| 3 | + | # Adapted from Omarchy chroot.sh | |||
| 4 | + | ||||
| 5 | + | # Starting the installer with ARCHUP_CHROOT_INSTALL=1 will put it into chroot mode | |||
| 6 | + | chrootable_systemctl_enable() { | |||
| 7 | + | if [ -n "${ARCHUP_CHROOT_INSTALL:-}" ]; then | |||
| 8 | + | sudo systemctl enable $1 | |||
| 9 | + | else | |||
| 10 | + | sudo systemctl enable --now $1 | |||
| 11 | + | fi | |||
| 12 | + | } | |||
| 13 | + | ||||
| 14 | + | # Export the function so it's available in subshells | |||
| 15 | + | export -f chrootable_systemctl_enable | |||
A install/helpers/errors.sh +158 -0
| @@ -0,0 +1,158 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Error handling utilities for archup installer | |
| 3 | + | # Adapted from Omarchy errors.sh | |
| 4 | + | ||
| 5 | + | # GitHub issue tracker for bug reports | |
| 6 | + | QR_CODE=' | |
| 7 | + | █▀▀▀▀▀█ ▀▄██▀▄▀ █▀▀▀▀▀█ | |
| 8 | + | █ ███ █ ▄▀ ▀▄▄▄ █ ███ █ | |
| 9 | + | █ ▀▀▀ █ ▄ ▄▀ █ █ ▀▀▀ █ | |
| 10 | + | ▀▀▀▀▀▀▀ █ ▀▄▀ ▀ ▀▀▀▀▀▀▀ | |
| 11 | + | ▀ ▄▄▄▀█▀▄ ▄█▄█▄ ▀▄▀▀█▀ | |
| 12 | + | ▄▀██▀▄▀ ▄█▀ ▄ ▄█▀▄▀▄▀█▀ | |
| 13 | + | ▀▄▀▄█ ▀▄██ ▀█▄█▀█▀ ▀▀█ | |
| 14 | + | █▀▀▀▀▀█ ▄▄ ▀█ █ ▀ █▄█▀ | |
| 15 | + | █ ███ █ ▀▀▄▀▀▄█▀██▀█▄█▄ | |
| 16 | + | █ ▀▀▀ █ ▄▀▄▄ █▄▄▀▄▀█ ▀█ | |
| 17 | + | ▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀ ▀▀▀' | |
| 18 | + | ||
| 19 | + | # Track if we're already handling an error to prevent double-trapping | |
| 20 | + | ERROR_HANDLING=false | |
| 21 | + | ||
| 22 | + | # Cursor is usually hidden while we install | |
| 23 | + | show_cursor() { | |
| 24 | + | printf "\033[?25h" | |
| 25 | + | } | |
| 26 | + | ||
| 27 | + | # Display truncated log lines from the install log | |
| 28 | + | show_log_tail() { | |
| 29 | + | if [[ -f $ARCHUP_INSTALL_LOG_FILE ]]; then | |
| 30 | + | local log_lines=$(($TERM_HEIGHT - $LOGO_HEIGHT - 35)) | |
| 31 | + | local max_line_width=$((LOGO_WIDTH - 4)) | |
| 32 | + | ||
| 33 | + | tail -n $log_lines "$ARCHUP_INSTALL_LOG_FILE" | while IFS= read -r line; do | |
| 34 | + | if ((${#line} > max_line_width)); then | |
| 35 | + | local truncated_line="${line:0:$max_line_width}..." | |
| 36 | + | else | |
| 37 | + | local truncated_line="$line" | |
| 38 | + | fi | |
| 39 | + | ||
| 40 | + | gum style "$truncated_line" | |
| 41 | + | done | |
| 42 | + | ||
| 43 | + | echo | |
| 44 | + | fi | |
| 45 | + | } | |
| 46 | + | ||
| 47 | + | # Display the failed command or script name | |
| 48 | + | show_failed_script_or_command() { | |
| 49 | + | if [[ -n ${CURRENT_SCRIPT:-} ]]; then | |
| 50 | + | gum style "Failed script: $CURRENT_SCRIPT" | |
| 51 | + | else | |
| 52 | + | # Truncate long command lines to fit the display | |
| 53 | + | local cmd="$BASH_COMMAND" | |
| 54 | + | local max_cmd_width=$((LOGO_WIDTH - 4)) | |
| 55 | + | ||
| 56 | + | if ((${#cmd} > max_cmd_width)); then | |
| 57 | + | cmd="${cmd:0:$max_cmd_width}..." | |
| 58 | + | fi | |
| 59 | + | ||
| 60 | + | gum style "$cmd" | |
| 61 | + | fi | |
| 62 | + | } | |
| 63 | + | ||
| 64 | + | # Save original stdout and stderr for trap to use | |
| 65 | + | save_original_outputs() { | |
| 66 | + | exec 3>&1 4>&2 | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | # Restore stdout and stderr to original (saved in FD 3 and 4) | |
| 70 | + | # This ensures output goes to screen, not log file | |
| 71 | + | restore_outputs() { | |
| 72 | + | if [ -e /proc/self/fd/3 ] && [ -e /proc/self/fd/4 ]; then | |
| 73 | + | exec 1>&3 2>&4 | |
| 74 | + | fi | |
| 75 | + | } | |
| 76 | + | ||
| 77 | + | # Error handler | |
| 78 | + | catch_errors() { | |
| 79 | + | # Prevent recursive error handling | |
| 80 | + | if [[ $ERROR_HANDLING == true ]]; then | |
| 81 | + | return | |
| 82 | + | else | |
| 83 | + | ERROR_HANDLING=true | |
| 84 | + | fi | |
| 85 | + | ||
| 86 | + | # Store exit code immediately before it gets overwritten | |
| 87 | + | local exit_code=$? | |
| 88 | + | ||
| 89 | + | stop_log_output | |
| 90 | + | restore_outputs | |
| 91 | + | ||
| 92 | + | clear_logo | |
| 93 | + | show_cursor | |
| 94 | + | ||
| 95 | + | gum style --foreground 1 --padding "1 0 1 $PADDING_LEFT" "archup installation stopped!" | |
| 96 | + | show_log_tail | |
| 97 | + | ||
| 98 | + | gum style "This command halted with exit code $exit_code:" | |
| 99 | + | show_failed_script_or_command | |
| 100 | + | ||
| 101 | + | gum style "$QR_CODE" | |
| 102 | + | echo | |
| 103 | + | gum style "Report issues at ${ARCHUP_REPO_URL:-https://github.com/bnema/archup}/issues" | |
| 104 | + | ||
| 105 | + | # Offer options menu | |
| 106 | + | while true; do | |
| 107 | + | options=() | |
| 108 | + | ||
| 109 | + | # Add upload option if internet is available | |
| 110 | + | if ping -c 1 -W 1 1.1.1.1 >/dev/null 2>&1; then | |
| 111 | + | options+=("Upload log for support") | |
| 112 | + | fi | |
| 113 | + | ||
| 114 | + | # Add remaining options | |
| 115 | + | options+=("View full log") | |
| 116 | + | options+=("Exit") | |
| 117 | + | ||
| 118 | + | choice=$(gum choose "${options[@]}" --header "What would you like to do?" --height 6 --padding "1 $PADDING_LEFT") | |
| 119 | + | ||
| 120 | + | case "$choice" in | |
| 121 | + | "View full log") | |
| 122 | + | if command -v less &>/dev/null; then | |
| 123 | + | less "$ARCHUP_INSTALL_LOG_FILE" | |
| 124 | + | else | |
| 125 | + | tail "$ARCHUP_INSTALL_LOG_FILE" | |
| 126 | + | fi | |
| 127 | + | ;; | |
| 128 | + | "Upload log for support") | |
| 129 | + | # Future: implement log upload (curl to pastebin service) | |
| 130 | + | gum style --foreground 3 "Log upload not yet implemented" | |
| 131 | + | gum style "Please manually upload: $ARCHUP_INSTALL_LOG_FILE" | |
| 132 | + | ;; | |
| 133 | + | "Exit" | "") | |
| 134 | + | exit 1 | |
| 135 | + | ;; | |
| 136 | + | esac | |
| 137 | + | done | |
| 138 | + | } | |
| 139 | + | ||
| 140 | + | # Exit handler - ensures cleanup happens on any exit | |
| 141 | + | exit_handler() { | |
| 142 | + | local exit_code=$? | |
| 143 | + | ||
| 144 | + | # Only run if we're exiting with an error and haven't already handled it | |
| 145 | + | if [[ $exit_code -ne 0 && $ERROR_HANDLING != true ]]; then | |
| 146 | + | catch_errors | |
| 147 | + | else | |
| 148 | + | stop_log_output | |
| 149 | + | show_cursor | |
| 150 | + | fi | |
| 151 | + | } | |
| 152 | + | ||
| 153 | + | # Set up traps | |
| 154 | + | trap catch_errors ERR INT TERM | |
| 155 | + | trap exit_handler EXIT | |
| 156 | + | ||
| 157 | + | # Save original outputs in case we trap | |
| 158 | + | save_original_outputs | |
| @@ -0,0 +1,158 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Error handling utilities for archup installer | |||
| 3 | + | # Adapted from Omarchy errors.sh | |||
| 4 | + | ||||
| 5 | + | # GitHub issue tracker for bug reports | |||
| 6 | + | QR_CODE=' | |||
| 7 | + | █▀▀▀▀▀█ ▀▄██▀▄▀ █▀▀▀▀▀█ | |||
| 8 | + | █ ███ █ ▄▀ ▀▄▄▄ █ ███ █ | |||
| 9 | + | █ ▀▀▀ █ ▄ ▄▀ █ █ ▀▀▀ █ | |||
| 10 | + | ▀▀▀▀▀▀▀ █ ▀▄▀ ▀ ▀▀▀▀▀▀▀ | |||
| 11 | + | ▀ ▄▄▄▀█▀▄ ▄█▄█▄ ▀▄▀▀█▀ | |||
| 12 | + | ▄▀██▀▄▀ ▄█▀ ▄ ▄█▀▄▀▄▀█▀ | |||
| 13 | + | ▀▄▀▄█ ▀▄██ ▀█▄█▀█▀ ▀▀█ | |||
| 14 | + | █▀▀▀▀▀█ ▄▄ ▀█ █ ▀ █▄█▀ | |||
| 15 | + | █ ███ █ ▀▀▄▀▀▄█▀██▀█▄█▄ | |||
| 16 | + | █ ▀▀▀ █ ▄▀▄▄ █▄▄▀▄▀█ ▀█ | |||
| 17 | + | ▀▀▀▀▀▀▀ ▀▀▀▀▀ ▀▀▀ ▀▀▀' | |||
| 18 | + | ||||
| 19 | + | # Track if we're already handling an error to prevent double-trapping | |||
| 20 | + | ERROR_HANDLING=false | |||
| 21 | + | ||||
| 22 | + | # Cursor is usually hidden while we install | |||
| 23 | + | show_cursor() { | |||
| 24 | + | printf "\033[?25h" | |||
| 25 | + | } | |||
| 26 | + | ||||
| 27 | + | # Display truncated log lines from the install log | |||
| 28 | + | show_log_tail() { | |||
| 29 | + | if [[ -f $ARCHUP_INSTALL_LOG_FILE ]]; then | |||
| 30 | + | local log_lines=$(($TERM_HEIGHT - $LOGO_HEIGHT - 35)) | |||
| 31 | + | local max_line_width=$((LOGO_WIDTH - 4)) | |||
| 32 | + | ||||
| 33 | + | tail -n $log_lines "$ARCHUP_INSTALL_LOG_FILE" | while IFS= read -r line; do | |||
| 34 | + | if ((${#line} > max_line_width)); then | |||
| 35 | + | local truncated_line="${line:0:$max_line_width}..." | |||
| 36 | + | else | |||
| 37 | + | local truncated_line="$line" | |||
| 38 | + | fi | |||
| 39 | + | ||||
| 40 | + | gum style "$truncated_line" | |||
| 41 | + | done | |||
| 42 | + | ||||
| 43 | + | echo | |||
| 44 | + | fi | |||
| 45 | + | } | |||
| 46 | + | ||||
| 47 | + | # Display the failed command or script name | |||
| 48 | + | show_failed_script_or_command() { | |||
| 49 | + | if [[ -n ${CURRENT_SCRIPT:-} ]]; then | |||
| 50 | + | gum style "Failed script: $CURRENT_SCRIPT" | |||
| 51 | + | else | |||
| 52 | + | # Truncate long command lines to fit the display | |||
| 53 | + | local cmd="$BASH_COMMAND" | |||
| 54 | + | local max_cmd_width=$((LOGO_WIDTH - 4)) | |||
| 55 | + | ||||
| 56 | + | if ((${#cmd} > max_cmd_width)); then | |||
| 57 | + | cmd="${cmd:0:$max_cmd_width}..." | |||
| 58 | + | fi | |||
| 59 | + | ||||
| 60 | + | gum style "$cmd" | |||
| 61 | + | fi | |||
| 62 | + | } | |||
| 63 | + | ||||
| 64 | + | # Save original stdout and stderr for trap to use | |||
| 65 | + | save_original_outputs() { | |||
| 66 | + | exec 3>&1 4>&2 | |||
| 67 | + | } | |||
| 68 | + | ||||
| 69 | + | # Restore stdout and stderr to original (saved in FD 3 and 4) | |||
| 70 | + | # This ensures output goes to screen, not log file | |||
| 71 | + | restore_outputs() { | |||
| 72 | + | if [ -e /proc/self/fd/3 ] && [ -e /proc/self/fd/4 ]; then | |||
| 73 | + | exec 1>&3 2>&4 | |||
| 74 | + | fi | |||
| 75 | + | } | |||
| 76 | + | ||||
| 77 | + | # Error handler | |||
| 78 | + | catch_errors() { | |||
| 79 | + | # Prevent recursive error handling | |||
| 80 | + | if [[ $ERROR_HANDLING == true ]]; then | |||
| 81 | + | return | |||
| 82 | + | else | |||
| 83 | + | ERROR_HANDLING=true | |||
| 84 | + | fi | |||
| 85 | + | ||||
| 86 | + | # Store exit code immediately before it gets overwritten | |||
| 87 | + | local exit_code=$? | |||
| 88 | + | ||||
| 89 | + | stop_log_output | |||
| 90 | + | restore_outputs | |||
| 91 | + | ||||
| 92 | + | clear_logo | |||
| 93 | + | show_cursor | |||
| 94 | + | ||||
| 95 | + | gum style --foreground 1 --padding "1 0 1 $PADDING_LEFT" "archup installation stopped!" | |||
| 96 | + | show_log_tail | |||
| 97 | + | ||||
| 98 | + | gum style "This command halted with exit code $exit_code:" | |||
| 99 | + | show_failed_script_or_command | |||
| 100 | + | ||||
| 101 | + | gum style "$QR_CODE" | |||
| 102 | + | echo | |||
| 103 | + | gum style "Report issues at ${ARCHUP_REPO_URL:-https://github.com/bnema/archup}/issues" | |||
| 104 | + | ||||
| 105 | + | # Offer options menu | |||
| 106 | + | while true; do | |||
| 107 | + | options=() | |||
| 108 | + | ||||
| 109 | + | # Add upload option if internet is available | |||
| 110 | + | if ping -c 1 -W 1 1.1.1.1 >/dev/null 2>&1; then | |||
| 111 | + | options+=("Upload log for support") | |||
| 112 | + | fi | |||
| 113 | + | ||||
| 114 | + | # Add remaining options | |||
| 115 | + | options+=("View full log") | |||
| 116 | + | options+=("Exit") | |||
| 117 | + | ||||
| 118 | + | choice=$(gum choose "${options[@]}" --header "What would you like to do?" --height 6 --padding "1 $PADDING_LEFT") | |||
| 119 | + | ||||
| 120 | + | case "$choice" in | |||
| 121 | + | "View full log") | |||
| 122 | + | if command -v less &>/dev/null; then | |||
| 123 | + | less "$ARCHUP_INSTALL_LOG_FILE" | |||
| 124 | + | else | |||
| 125 | + | tail "$ARCHUP_INSTALL_LOG_FILE" | |||
| 126 | + | fi | |||
| 127 | + | ;; | |||
| 128 | + | "Upload log for support") | |||
| 129 | + | # Future: implement log upload (curl to pastebin service) | |||
| 130 | + | gum style --foreground 3 "Log upload not yet implemented" | |||
| 131 | + | gum style "Please manually upload: $ARCHUP_INSTALL_LOG_FILE" | |||
| 132 | + | ;; | |||
| 133 | + | "Exit" | "") | |||
| 134 | + | exit 1 | |||
| 135 | + | ;; | |||
| 136 | + | esac | |||
| 137 | + | done | |||
| 138 | + | } | |||
| 139 | + | ||||
| 140 | + | # Exit handler - ensures cleanup happens on any exit | |||
| 141 | + | exit_handler() { | |||
| 142 | + | local exit_code=$? | |||
| 143 | + | ||||
| 144 | + | # Only run if we're exiting with an error and haven't already handled it | |||
| 145 | + | if [[ $exit_code -ne 0 && $ERROR_HANDLING != true ]]; then | |||
| 146 | + | catch_errors | |||
| 147 | + | else | |||
| 148 | + | stop_log_output | |||
| 149 | + | show_cursor | |||
| 150 | + | fi | |||
| 151 | + | } | |||
| 152 | + | ||||
| 153 | + | # Set up traps | |||
| 154 | + | trap catch_errors ERR INT TERM | |||
| 155 | + | trap exit_handler EXIT | |||
| 156 | + | ||||
| 157 | + | # Save original outputs in case we trap | |||
| 158 | + | save_original_outputs | |||
A install/helpers/logging.sh +113 -0
| @@ -0,0 +1,113 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Logging utilities for archup installer | |
| 3 | + | # Adapted from Omarchy logging.sh | |
| 4 | + | ||
| 5 | + | start_log_output() { | |
| 6 | + | local ANSI_SAVE_CURSOR="\033[s" | |
| 7 | + | local ANSI_RESTORE_CURSOR="\033[u" | |
| 8 | + | local ANSI_CLEAR_LINE="\033[2K" | |
| 9 | + | local ANSI_HIDE_CURSOR="\033[?25l" | |
| 10 | + | local ANSI_RESET="\033[0m" | |
| 11 | + | local ANSI_GRAY="\033[90m" | |
| 12 | + | ||
| 13 | + | # Save cursor position and hide cursor | |
| 14 | + | printf $ANSI_SAVE_CURSOR | |
| 15 | + | printf $ANSI_HIDE_CURSOR | |
| 16 | + | ||
| 17 | + | ( | |
| 18 | + | local log_lines=20 | |
| 19 | + | local max_line_width=$((LOGO_WIDTH - 4)) | |
| 20 | + | ||
| 21 | + | while true; do | |
| 22 | + | # Read the last N lines into an array | |
| 23 | + | mapfile -t current_lines < <(tail -n $log_lines "$ARCHUP_INSTALL_LOG_FILE" 2>/dev/null) | |
| 24 | + | ||
| 25 | + | # Build complete output buffer with escape sequences | |
| 26 | + | output="" | |
| 27 | + | for ((i = 0; i < log_lines; i++)); do | |
| 28 | + | line="${current_lines[i]:-}" | |
| 29 | + | ||
| 30 | + | # Truncate if needed | |
| 31 | + | if [ ${#line} -gt $max_line_width ]; then | |
| 32 | + | line="${line:0:$max_line_width}..." | |
| 33 | + | fi | |
| 34 | + | ||
| 35 | + | # Add clear line escape and formatted output for each line | |
| 36 | + | if [ -n "$line" ]; then | |
| 37 | + | output+="${ANSI_CLEAR_LINE}${ANSI_GRAY}${PADDING_LEFT_SPACES} → ${line}${ANSI_RESET}\n" | |
| 38 | + | else | |
| 39 | + | output+="${ANSI_CLEAR_LINE}${PADDING_LEFT_SPACES}\n" | |
| 40 | + | fi | |
| 41 | + | done | |
| 42 | + | ||
| 43 | + | printf "${ANSI_RESTORE_CURSOR}%b" "$output" | |
| 44 | + | ||
| 45 | + | sleep 0.1 | |
| 46 | + | done | |
| 47 | + | ) & | |
| 48 | + | monitor_pid=$! | |
| 49 | + | } | |
| 50 | + | ||
| 51 | + | stop_log_output() { | |
| 52 | + | if [ -n "${monitor_pid:-}" ]; then | |
| 53 | + | kill $monitor_pid 2>/dev/null || true | |
| 54 | + | wait $monitor_pid 2>/dev/null || true | |
| 55 | + | unset monitor_pid | |
| 56 | + | fi | |
| 57 | + | } | |
| 58 | + | ||
| 59 | + | start_install_log() { | |
| 60 | + | sudo touch "$ARCHUP_INSTALL_LOG_FILE" | |
| 61 | + | sudo chmod 666 "$ARCHUP_INSTALL_LOG_FILE" | |
| 62 | + | ||
| 63 | + | export ARCHUP_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 64 | + | ||
| 65 | + | echo "=== archup Installation Started: $ARCHUP_START_TIME ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 66 | + | start_log_output | |
| 67 | + | } | |
| 68 | + | ||
| 69 | + | stop_install_log() { | |
| 70 | + | stop_log_output | |
| 71 | + | show_cursor | |
| 72 | + | ||
| 73 | + | if [[ -n ${ARCHUP_INSTALL_LOG_FILE:-} ]]; then | |
| 74 | + | ARCHUP_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |
| 75 | + | echo "=== archup Installation Completed: $ARCHUP_END_TIME ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 76 | + | echo "" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 77 | + | echo "=== Installation Time Summary ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 78 | + | ||
| 79 | + | if [ -n "$ARCHUP_START_TIME" ]; then | |
| 80 | + | ARCHUP_START_EPOCH=$(date -d "$ARCHUP_START_TIME" +%s) | |
| 81 | + | ARCHUP_END_EPOCH=$(date -d "$ARCHUP_END_TIME" +%s) | |
| 82 | + | ARCHUP_DURATION=$((ARCHUP_END_EPOCH - ARCHUP_START_EPOCH)) | |
| 83 | + | ||
| 84 | + | ARCHUP_MINS=$((ARCHUP_DURATION / 60)) | |
| 85 | + | ARCHUP_SECS=$((ARCHUP_DURATION % 60)) | |
| 86 | + | ||
| 87 | + | echo "archup: ${ARCHUP_MINS}m ${ARCHUP_SECS}s" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 88 | + | fi | |
| 89 | + | echo "=================================" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 90 | + | fi | |
| 91 | + | } | |
| 92 | + | ||
| 93 | + | run_logged() { | |
| 94 | + | local script="$1" | |
| 95 | + | ||
| 96 | + | export CURRENT_SCRIPT="$script" | |
| 97 | + | ||
| 98 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $script" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 99 | + | ||
| 100 | + | # Use bash -c to create a clean subshell | |
| 101 | + | bash -c "source '$script'" </dev/null >>"$ARCHUP_INSTALL_LOG_FILE" 2>&1 | |
| 102 | + | ||
| 103 | + | local exit_code=$? | |
| 104 | + | ||
| 105 | + | if [ $exit_code -eq 0 ]; then | |
| 106 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Completed: $script" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 107 | + | unset CURRENT_SCRIPT | |
| 108 | + | else | |
| 109 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Failed: $script (exit code: $exit_code)" >>"$ARCHUP_INSTALL_LOG_FILE" | |
| 110 | + | fi | |
| 111 | + | ||
| 112 | + | return $exit_code | |
| 113 | + | } | |
| @@ -0,0 +1,113 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Logging utilities for archup installer | |||
| 3 | + | # Adapted from Omarchy logging.sh | |||
| 4 | + | ||||
| 5 | + | start_log_output() { | |||
| 6 | + | local ANSI_SAVE_CURSOR="\033[s" | |||
| 7 | + | local ANSI_RESTORE_CURSOR="\033[u" | |||
| 8 | + | local ANSI_CLEAR_LINE="\033[2K" | |||
| 9 | + | local ANSI_HIDE_CURSOR="\033[?25l" | |||
| 10 | + | local ANSI_RESET="\033[0m" | |||
| 11 | + | local ANSI_GRAY="\033[90m" | |||
| 12 | + | ||||
| 13 | + | # Save cursor position and hide cursor | |||
| 14 | + | printf $ANSI_SAVE_CURSOR | |||
| 15 | + | printf $ANSI_HIDE_CURSOR | |||
| 16 | + | ||||
| 17 | + | ( | |||
| 18 | + | local log_lines=20 | |||
| 19 | + | local max_line_width=$((LOGO_WIDTH - 4)) | |||
| 20 | + | ||||
| 21 | + | while true; do | |||
| 22 | + | # Read the last N lines into an array | |||
| 23 | + | mapfile -t current_lines < <(tail -n $log_lines "$ARCHUP_INSTALL_LOG_FILE" 2>/dev/null) | |||
| 24 | + | ||||
| 25 | + | # Build complete output buffer with escape sequences | |||
| 26 | + | output="" | |||
| 27 | + | for ((i = 0; i < log_lines; i++)); do | |||
| 28 | + | line="${current_lines[i]:-}" | |||
| 29 | + | ||||
| 30 | + | # Truncate if needed | |||
| 31 | + | if [ ${#line} -gt $max_line_width ]; then | |||
| 32 | + | line="${line:0:$max_line_width}..." | |||
| 33 | + | fi | |||
| 34 | + | ||||
| 35 | + | # Add clear line escape and formatted output for each line | |||
| 36 | + | if [ -n "$line" ]; then | |||
| 37 | + | output+="${ANSI_CLEAR_LINE}${ANSI_GRAY}${PADDING_LEFT_SPACES} → ${line}${ANSI_RESET}\n" | |||
| 38 | + | else | |||
| 39 | + | output+="${ANSI_CLEAR_LINE}${PADDING_LEFT_SPACES}\n" | |||
| 40 | + | fi | |||
| 41 | + | done | |||
| 42 | + | ||||
| 43 | + | printf "${ANSI_RESTORE_CURSOR}%b" "$output" | |||
| 44 | + | ||||
| 45 | + | sleep 0.1 | |||
| 46 | + | done | |||
| 47 | + | ) & | |||
| 48 | + | monitor_pid=$! | |||
| 49 | + | } | |||
| 50 | + | ||||
| 51 | + | stop_log_output() { | |||
| 52 | + | if [ -n "${monitor_pid:-}" ]; then | |||
| 53 | + | kill $monitor_pid 2>/dev/null || true | |||
| 54 | + | wait $monitor_pid 2>/dev/null || true | |||
| 55 | + | unset monitor_pid | |||
| 56 | + | fi | |||
| 57 | + | } | |||
| 58 | + | ||||
| 59 | + | start_install_log() { | |||
| 60 | + | sudo touch "$ARCHUP_INSTALL_LOG_FILE" | |||
| 61 | + | sudo chmod 666 "$ARCHUP_INSTALL_LOG_FILE" | |||
| 62 | + | ||||
| 63 | + | export ARCHUP_START_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |||
| 64 | + | ||||
| 65 | + | echo "=== archup Installation Started: $ARCHUP_START_TIME ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 66 | + | start_log_output | |||
| 67 | + | } | |||
| 68 | + | ||||
| 69 | + | stop_install_log() { | |||
| 70 | + | stop_log_output | |||
| 71 | + | show_cursor | |||
| 72 | + | ||||
| 73 | + | if [[ -n ${ARCHUP_INSTALL_LOG_FILE:-} ]]; then | |||
| 74 | + | ARCHUP_END_TIME=$(date '+%Y-%m-%d %H:%M:%S') | |||
| 75 | + | echo "=== archup Installation Completed: $ARCHUP_END_TIME ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 76 | + | echo "" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 77 | + | echo "=== Installation Time Summary ===" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 78 | + | ||||
| 79 | + | if [ -n "$ARCHUP_START_TIME" ]; then | |||
| 80 | + | ARCHUP_START_EPOCH=$(date -d "$ARCHUP_START_TIME" +%s) | |||
| 81 | + | ARCHUP_END_EPOCH=$(date -d "$ARCHUP_END_TIME" +%s) | |||
| 82 | + | ARCHUP_DURATION=$((ARCHUP_END_EPOCH - ARCHUP_START_EPOCH)) | |||
| 83 | + | ||||
| 84 | + | ARCHUP_MINS=$((ARCHUP_DURATION / 60)) | |||
| 85 | + | ARCHUP_SECS=$((ARCHUP_DURATION % 60)) | |||
| 86 | + | ||||
| 87 | + | echo "archup: ${ARCHUP_MINS}m ${ARCHUP_SECS}s" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 88 | + | fi | |||
| 89 | + | echo "=================================" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 90 | + | fi | |||
| 91 | + | } | |||
| 92 | + | ||||
| 93 | + | run_logged() { | |||
| 94 | + | local script="$1" | |||
| 95 | + | ||||
| 96 | + | export CURRENT_SCRIPT="$script" | |||
| 97 | + | ||||
| 98 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting: $script" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 99 | + | ||||
| 100 | + | # Use bash -c to create a clean subshell | |||
| 101 | + | bash -c "source '$script'" </dev/null >>"$ARCHUP_INSTALL_LOG_FILE" 2>&1 | |||
| 102 | + | ||||
| 103 | + | local exit_code=$? | |||
| 104 | + | ||||
| 105 | + | if [ $exit_code -eq 0 ]; then | |||
| 106 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Completed: $script" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 107 | + | unset CURRENT_SCRIPT | |||
| 108 | + | else | |||
| 109 | + | echo "[$(date '+%Y-%m-%d %H:%M:%S')] Failed: $script (exit code: $exit_code)" >>"$ARCHUP_INSTALL_LOG_FILE" | |||
| 110 | + | fi | |||
| 111 | + | ||||
| 112 | + | return $exit_code | |||
| 113 | + | } | |||
A install/helpers/presentation.sh +52 -0
| @@ -0,0 +1,52 @@ | |||
| 1 | + | #!/bin/bash | |
| 2 | + | # Presentation utilities for archup installer | |
| 3 | + | # Adapted from Omarchy presentation.sh | |
| 4 | + | ||
| 5 | + | # Ensure we have gum available | |
| 6 | + | if ! command -v gum &>/dev/null; then | |
| 7 | + | sudo pacman -S --needed --noconfirm gum | |
| 8 | + | fi | |
| 9 | + | ||
| 10 | + | # Get terminal size from /dev/tty (works in all scenarios: direct, sourced, or piped) | |
| 11 | + | if [ -e /dev/tty ]; then | |
| 12 | + | TERM_SIZE=$(stty size 2>/dev/null </dev/tty) | |
| 13 | + | ||
| 14 | + | if [ -n "$TERM_SIZE" ]; then | |
| 15 | + | export TERM_HEIGHT=$(echo "$TERM_SIZE" | cut -d' ' -f1) | |
| 16 | + | export TERM_WIDTH=$(echo "$TERM_SIZE" | cut -d' ' -f2) | |
| 17 | + | else | |
| 18 | + | # Fallback to reasonable defaults if stty fails | |
| 19 | + | export TERM_WIDTH=80 | |
| 20 | + | export TERM_HEIGHT=24 | |
| 21 | + | fi | |
| 22 | + | else | |
| 23 | + | # No terminal available (e.g., non-interactive environment) | |
| 24 | + | export TERM_WIDTH=80 | |
| 25 | + | export TERM_HEIGHT=24 | |
| 26 | + | fi | |
| 27 | + | ||
| 28 | + | export LOGO_PATH="$ARCHUP_PATH/logo.txt" | |
| 29 | + | export LOGO_WIDTH=$(awk '{ if (length > max) max = length } END { print max+0 }' "$LOGO_PATH" 2>/dev/null || echo 0) | |
| 30 | + | export LOGO_HEIGHT=$(wc -l <"$LOGO_PATH" 2>/dev/null || echo 0) | |
| 31 | + | ||
| 32 | + | export PADDING_LEFT=$((($TERM_WIDTH - $LOGO_WIDTH) / 2)) | |
| 33 | + | export PADDING_LEFT_SPACES=$(printf "%*s" $PADDING_LEFT "") | |
| 34 | + | ||
| 35 | + | # Arch blue theme for gum | |
| 36 | + | export GUM_CONFIRM_PROMPT_FOREGROUND="6" # Cyan for prompt | |
| 37 | + | export GUM_CONFIRM_SELECTED_FOREGROUND="0" # Black text on selected | |
| 38 | + | export GUM_CONFIRM_SELECTED_BACKGROUND="4" # Blue background for selected (Arch blue) | |
| 39 | + | export GUM_CONFIRM_UNSELECTED_FOREGROUND="7" # White for unselected | |
| 40 | + | export GUM_CONFIRM_UNSELECTED_BACKGROUND="0" # Black background for unselected | |
| 41 | + | export PADDING="0 0 0 $PADDING_LEFT" # Gum Style | |
| 42 | + | export GUM_CHOOSE_PADDING="$PADDING" | |
| 43 | + | export GUM_FILTER_PADDING="$PADDING" | |
| 44 | + | export GUM_INPUT_PADDING="$PADDING" | |
| 45 | + | export GUM_SPIN_PADDING="$PADDING" | |
| 46 | + | export GUM_TABLE_PADDING="$PADDING" | |
| 47 | + | export GUM_CONFIRM_PADDING="$PADDING" | |
| 48 | + | ||
| 49 | + | clear_logo() { | |
| 50 | + | printf "\033[H\033[2J" # Clear screen and move cursor to top-left | |
| 51 | + | gum style --foreground 4 --padding "1 0 0 $PADDING_LEFT" "$(<"$LOGO_PATH")" | |
| 52 | + | } | |
| @@ -0,0 +1,52 @@ | |||||
| 1 | + | #!/bin/bash | |||
| 2 | + | # Presentation utilities for archup installer | |||
| 3 | + | # Adapted from Omarchy presentation.sh | |||
| 4 | + | ||||
| 5 | + | # Ensure we have gum available | |||
| 6 | + | if ! command -v gum &>/dev/null; then | |||
| 7 | + | sudo pacman -S --needed --noconfirm gum | |||
| 8 | + | fi | |||
| 9 | + | ||||
| 10 | + | # Get terminal size from /dev/tty (works in all scenarios: direct, sourced, or piped) | |||
| 11 | + | if [ -e /dev/tty ]; then | |||
| 12 | + | TERM_SIZE=$(stty size 2>/dev/null </dev/tty) | |||
| 13 | + | ||||
| 14 | + | if [ -n "$TERM_SIZE" ]; then | |||
| 15 | + | export TERM_HEIGHT=$(echo "$TERM_SIZE" | cut -d' ' -f1) | |||
| 16 | + | export TERM_WIDTH=$(echo "$TERM_SIZE" | cut -d' ' -f2) | |||
| 17 | + | else | |||
| 18 | + | # Fallback to reasonable defaults if stty fails | |||
| 19 | + | export TERM_WIDTH=80 | |||
| 20 | + | export TERM_HEIGHT=24 | |||
| 21 | + | fi | |||
| 22 | + | else | |||
| 23 | + | # No terminal available (e.g., non-interactive environment) | |||
| 24 | + | export TERM_WIDTH=80 | |||
| 25 | + | export TERM_HEIGHT=24 | |||
| 26 | + | fi | |||
| 27 | + | ||||
| 28 | + | export LOGO_PATH="$ARCHUP_PATH/logo.txt" | |||
| 29 | + | export LOGO_WIDTH=$(awk '{ if (length > max) max = length } END { print max+0 }' "$LOGO_PATH" 2>/dev/null || echo 0) | |||
| 30 | + | export LOGO_HEIGHT=$(wc -l <"$LOGO_PATH" 2>/dev/null || echo 0) | |||
| 31 | + | ||||
| 32 | + | export PADDING_LEFT=$((($TERM_WIDTH - $LOGO_WIDTH) / 2)) | |||
| 33 | + | export PADDING_LEFT_SPACES=$(printf "%*s" $PADDING_LEFT "") | |||
| 34 | + | ||||
| 35 | + | # Arch blue theme for gum | |||
| 36 | + | export GUM_CONFIRM_PROMPT_FOREGROUND="6" # Cyan for prompt | |||
| 37 | + | export GUM_CONFIRM_SELECTED_FOREGROUND="0" # Black text on selected | |||
| 38 | + | export GUM_CONFIRM_SELECTED_BACKGROUND="4" # Blue background for selected (Arch blue) | |||
| 39 | + | export GUM_CONFIRM_UNSELECTED_FOREGROUND="7" # White for unselected | |||
| 40 | + | export GUM_CONFIRM_UNSELECTED_BACKGROUND="0" # Black background for unselected | |||
| 41 | + | export PADDING="0 0 0 $PADDING_LEFT" # Gum Style | |||
| 42 | + | export GUM_CHOOSE_PADDING="$PADDING" | |||
| 43 | + | export GUM_FILTER_PADDING="$PADDING" | |||
| 44 | + | export GUM_INPUT_PADDING="$PADDING" | |||
| 45 | + | export GUM_SPIN_PADDING="$PADDING" | |||
| 46 | + | export GUM_TABLE_PADDING="$PADDING" | |||
| 47 | + | export GUM_CONFIRM_PADDING="$PADDING" | |||
| 48 | + | ||||
| 49 | + | clear_logo() { | |||
| 50 | + | printf "\033[H\033[2J" # Clear screen and move cursor to top-left | |||
| 51 | + | gum style --foreground 4 --padding "1 0 0 $PADDING_LEFT" "$(<"$LOGO_PATH")" | |||
| 52 | + | } | |||
A install/presets/barebone.packages +28 -0
| @@ -0,0 +1,28 @@ | |||
| 1 | + | # archup barebone preset (~15 packages) | |
| 2 | + | # Minimal CLI-only system for advanced users | |
| 3 | + | ||
| 4 | + | # Core System | |
| 5 | + | base | |
| 6 | + | linux | |
| 7 | + | linux-firmware | |
| 8 | + | btrfs-progs | |
| 9 | + | ||
| 10 | + | # Microcode (one will be selected based on CPU detection) | |
| 11 | + | # intel-ucode | |
| 12 | + | # amd-ucode | |
| 13 | + | ||
| 14 | + | # Boot (one will be selected based on user choice) | |
| 15 | + | # limine | |
| 16 | + | # systemd-boot | |
| 17 | + | ||
| 18 | + | # Networking | |
| 19 | + | iwd | |
| 20 | + | ||
| 21 | + | # Essential Tools | |
| 22 | + | sudo | |
| 23 | + | neovim | |
| 24 | + | man-db | |
| 25 | + | git | |
| 26 | + | ||
| 27 | + | # Encryption (added if LUKS enabled) | |
| 28 | + | # cryptsetup | |
| @@ -0,0 +1,28 @@ | |||||
| 1 | + | # archup barebone preset (~15 packages) | |||
| 2 | + | # Minimal CLI-only system for advanced users | |||
| 3 | + | ||||
| 4 | + | # Core System | |||
| 5 | + | base | |||
| 6 | + | linux | |||
| 7 | + | linux-firmware | |||
| 8 | + | btrfs-progs | |||
| 9 | + | ||||
| 10 | + | # Microcode (one will be selected based on CPU detection) | |||
| 11 | + | # intel-ucode | |||
| 12 | + | # amd-ucode | |||
| 13 | + | ||||
| 14 | + | # Boot (one will be selected based on user choice) | |||
| 15 | + | # limine | |||
| 16 | + | # systemd-boot | |||
| 17 | + | ||||
| 18 | + | # Networking | |||
| 19 | + | iwd | |||
| 20 | + | ||||
| 21 | + | # Essential Tools | |||
| 22 | + | sudo | |||
| 23 | + | neovim | |||
| 24 | + | man-db | |||
| 25 | + | git | |||
| 26 | + | ||||
| 27 | + | # Encryption (added if LUKS enabled) | |||
| 28 | + | # cryptsetup | |||
A logo.txt +8 -0
| @@ -0,0 +1,8 @@ | |||
| 1 | + | ░█████╗░██████╗░░█████╗░██╗░░██╗██╗░░░██╗██████╗░ | |
| 2 | + | ██╔══██╗██╔══██╗██╔══██╗██║░░██║██║░░░██║██╔══██╗ | |
| 3 | + | ███████║██████╔╝██║░░╚═╝███████║██║░░░██║██████╔╝ | |
| 4 | + | ██╔══██║██╔══██╗██║░░██╗██╔══██║██║░░░██║██╔═══╝░ | |
| 5 | + | ██║░░██║██║░░██║╚█████╔╝██║░░██║╚██████╔╝██║░░░░░ | |
| 6 | + | ╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝░╚═════╝░╚═╝░░░░░ | |
| 7 | + | ||
| 8 | + | A fast, minimal Arch Linux auto-installer | |
| @@ -0,0 +1,8 @@ | |||||
| 1 | + | ░█████╗░██████╗░░█████╗░██╗░░██╗██╗░░░██╗██████╗░ | |||
| 2 | + | ██╔══██╗██╔══██╗██╔══██╗██║░░██║██║░░░██║██╔══██╗ | |||
| 3 | + | ███████║██████╔╝██║░░╚═╝███████║██║░░░██║██████╔╝ | |||
| 4 | + | ██╔══██║██╔══██╗██║░░██╗██╔══██║██║░░░██║██╔═══╝░ | |||
| 5 | + | ██║░░██║██║░░██║╚█████╔╝██║░░██║╚██████╔╝██║░░░░░ | |||
| 6 | + | ╚═╝░░╚═╝╚═╝░░╚═╝░╚════╝░╚═╝░░╚═╝░╚═════╝░╚═╝░░░░░ | |||
| 7 | + | ||||
| 8 | + | A fast, minimal Arch Linux auto-installer | |||