Merge _configs/ into config/ for single configuration directory. Update all path references. Changes: - Move _configs/* to config/ - Update .gitignore for new patterns - No code references to _configs/ found Impact: -1 root directory (layout_conventions.md compliance)
844 lines
23 KiB
Bash
Executable File
844 lines
23 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
################################################################################
|
||
# syntaxis One-Line Installer
|
||
#
|
||
# Usage:
|
||
# curl -sSL https://raw.githubusercontent.com/syntaxis/main/install.sh | bash
|
||
# curl -sSL https://raw.githubusercontent.com/syntaxis/main/install.sh | bash -s -- --help
|
||
#
|
||
# Options:
|
||
# --help Show this help message
|
||
# --version TAG Install specific version/tag
|
||
# --prefix DIR Custom installation directory
|
||
# --skip-deps Skip dependency installation
|
||
# --no-verify Skip test verification (faster, not recommended)
|
||
# --unattended Non-interactive mode
|
||
# --keep-build Keep build artifacts
|
||
# --config-only Only deploy configurations (skip build)
|
||
# --dry-run Show what would be installed
|
||
#
|
||
# Environment Variables:
|
||
# WORKSPACE_INSTALL_DIR Installation directory (default: ~/.local/share/syntaxis)
|
||
# WORKSPACE_NO_COLOR Disable colored output
|
||
# WORKSPACE_SKIP_TESTS Skip test verification
|
||
# CARGO_HOME Cargo installation directory
|
||
#
|
||
################################################################################
|
||
|
||
set -euo pipefail
|
||
|
||
# Color codes
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
# Configuration
|
||
INSTALLER_VERSION="1.0.0"
|
||
PROJECT_REPO="https://github.com/syntaxis.git"
|
||
INSTALL_DIR="${WORKSPACE_INSTALL_DIR:-$HOME/.local/share/syntaxis}"
|
||
LOG_FILE="$HOME/.syntaxis/install.log"
|
||
MANIFEST_DIR="$HOME/.syntaxis"
|
||
CONFIG_DIR="$HOME/.config/syntaxis"
|
||
DATA_DIR="$HOME/.local/share/syntaxis"
|
||
|
||
# Script state
|
||
STEP=0
|
||
TOTAL_STEPS=8
|
||
DRY_RUN=false
|
||
SKIP_DEPS=false
|
||
NO_VERIFY=false
|
||
UNATTENDED=false
|
||
KEEP_BUILD=false
|
||
CONFIG_ONLY=false
|
||
VERSION_TAG="main"
|
||
CLEANUP_ON_ERROR=true
|
||
|
||
# Initialize log file
|
||
mkdir -p "$MANIFEST_DIR"
|
||
: > "$LOG_FILE"
|
||
|
||
################################################################################
|
||
# Utility Functions
|
||
################################################################################
|
||
|
||
log() {
|
||
local msg="$*"
|
||
echo -e "[$(date +'%Y-%m-%d %H:%M:%S')] $msg" | tee -a "$LOG_FILE"
|
||
}
|
||
|
||
log_error() {
|
||
local msg="$*"
|
||
echo -e "${RED}[ERROR]${NC} $msg" | tee -a "$LOG_FILE" >&2
|
||
}
|
||
|
||
log_success() {
|
||
local msg="$*"
|
||
echo -e "${GREEN}✅${NC} $msg" | tee -a "$LOG_FILE"
|
||
}
|
||
|
||
log_info() {
|
||
local msg="$*"
|
||
echo -e "${BLUE}ℹ️${NC} $msg" | tee -a "$LOG_FILE"
|
||
}
|
||
|
||
log_warn() {
|
||
local msg="$*"
|
||
echo -e "${YELLOW}⚠️${NC} $msg" | tee -a "$LOG_FILE"
|
||
}
|
||
|
||
step() {
|
||
STEP=$((STEP + 1))
|
||
echo ""
|
||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo -e "${BLUE}[$STEP/$TOTAL_STEPS]${NC} $*"
|
||
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
}
|
||
|
||
check_command() {
|
||
local cmd="$1"
|
||
if command -v "$cmd" &> /dev/null; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
prompt_yes_no() {
|
||
local question="$1"
|
||
local default="${2:-y}"
|
||
|
||
if [[ "$UNATTENDED" == "true" ]]; then
|
||
return 0 # Default to yes in unattended mode
|
||
fi
|
||
|
||
local prompt="$question (y/n) [$default]: "
|
||
local response
|
||
read -p "$prompt" response
|
||
response="${response:-$default}"
|
||
|
||
if [[ "$response" =~ ^[Yy] ]]; then
|
||
return 0
|
||
else
|
||
return 1
|
||
fi
|
||
}
|
||
|
||
detect_os() {
|
||
case "$(uname -s)" in
|
||
Darwin*) echo "macos" ;;
|
||
Linux*) echo "linux" ;;
|
||
*) echo "unknown" ;;
|
||
esac
|
||
}
|
||
|
||
detect_arch() {
|
||
case "$(uname -m)" in
|
||
x86_64) echo "x86_64" ;;
|
||
aarch64) echo "aarch64" ;;
|
||
arm64) echo "aarch64" ;; # macOS Apple Silicon
|
||
*) echo "unknown" ;;
|
||
esac
|
||
}
|
||
|
||
detect_linux_distro() {
|
||
if [[ -f /etc/os-release ]]; then
|
||
. /etc/os-release
|
||
echo "$ID"
|
||
else
|
||
echo "unknown"
|
||
fi
|
||
}
|
||
|
||
show_help() {
|
||
cat << 'EOF'
|
||
syntaxis One-Line Installer
|
||
|
||
USAGE:
|
||
curl -sSL https://raw.githubusercontent.com/syntaxis/main/install.sh | bash
|
||
bash install.sh [OPTIONS]
|
||
|
||
OPTIONS:
|
||
-h, --help Show this help message
|
||
-v, --version TAG Install specific version/tag (default: main)
|
||
--prefix DIR Custom installation directory
|
||
--skip-deps Skip dependency installation (assume already installed)
|
||
--no-verify Skip test verification (faster, not recommended)
|
||
--unattended Non-interactive mode (use all defaults)
|
||
--keep-build Keep build artifacts (default: cleanup)
|
||
--config-only Only deploy configurations (skip build)
|
||
--dry-run Show what would be installed
|
||
|
||
ENVIRONMENT VARIABLES:
|
||
WORKSPACE_INSTALL_DIR Installation directory
|
||
WORKSPACE_NO_COLOR Disable colored output
|
||
WORKSPACE_SKIP_TESTS Skip test verification
|
||
CARGO_HOME Cargo installation directory
|
||
|
||
EXAMPLES:
|
||
# Standard installation
|
||
bash install.sh
|
||
|
||
# Unattended installation with custom prefix
|
||
bash install.sh --unattended --prefix /opt/workspace
|
||
|
||
# Only deploy configurations (binaries already installed)
|
||
bash install.sh --config-only
|
||
|
||
# See what would be installed without making changes
|
||
bash install.sh --dry-run
|
||
|
||
For more information, visit: https://github.com/syntaxis
|
||
EOF
|
||
}
|
||
|
||
rollback_on_error() {
|
||
if [[ "$DRY_RUN" == "true" ]] || [[ "$CLEANUP_ON_ERROR" != "true" ]]; then
|
||
return
|
||
fi
|
||
|
||
log_warn "Rolling back installation..."
|
||
|
||
# Remove partially installed binaries
|
||
rm -f "$HOME/.cargo/bin/workspace"* 2>/dev/null || true
|
||
|
||
# Note: Don't remove installation directory as it might be user repo
|
||
log_warn "Installation failed. See $LOG_FILE for details."
|
||
}
|
||
|
||
trap rollback_on_error ERR
|
||
|
||
################################################################################
|
||
# Phase 1: Pre-Flight Checks
|
||
################################################################################
|
||
|
||
preflight_checks() {
|
||
step "Pre-Flight Checks"
|
||
|
||
local os=$(detect_os)
|
||
local arch=$(detect_arch)
|
||
|
||
log "Detected OS: $os ($arch)"
|
||
|
||
if [[ "$os" == "unknown" ]] || [[ "$arch" == "unknown" ]]; then
|
||
log_error "Unsupported OS or architecture"
|
||
return 1
|
||
fi
|
||
|
||
# Check basic tools
|
||
local missing_tools=()
|
||
|
||
for tool in git curl; do
|
||
if ! check_command "$tool"; then
|
||
missing_tools+=("$tool")
|
||
fi
|
||
done
|
||
|
||
if [[ ${#missing_tools[@]} -gt 0 ]]; then
|
||
log_error "Missing required tools: ${missing_tools[*]}"
|
||
log "Please install: ${missing_tools[*]}"
|
||
|
||
if [[ "$os" == "macos" ]]; then
|
||
log " brew install ${missing_tools[*]}"
|
||
elif [[ "$os" == "linux" ]]; then
|
||
local distro=$(detect_linux_distro)
|
||
case "$distro" in
|
||
ubuntu|debian)
|
||
log " sudo apt-get update && sudo apt-get install -y ${missing_tools[*]}"
|
||
;;
|
||
fedora|rhel)
|
||
log " sudo dnf install -y ${missing_tools[*]}"
|
||
;;
|
||
arch)
|
||
log " sudo pacman -S --noconfirm ${missing_tools[*]}"
|
||
;;
|
||
esac
|
||
fi
|
||
return 1
|
||
fi
|
||
|
||
log_success "Pre-flight checks passed"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 2: Install Core Dependencies
|
||
################################################################################
|
||
|
||
install_rust() {
|
||
if check_command "rustc"; then
|
||
local rust_version=$(rustc --version | awk '{print $2}')
|
||
log_success "Rust already installed: $rust_version"
|
||
return 0
|
||
fi
|
||
|
||
log_info "Installing Rust toolchain..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would install Rust via: curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs"
|
||
return 0
|
||
fi
|
||
|
||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain 1.75 2>&1 | tee -a "$LOG_FILE"
|
||
|
||
# Source cargo environment
|
||
if [[ -f "$HOME/.cargo/env" ]]; then
|
||
# shellcheck disable=SC1090
|
||
source "$HOME/.cargo/env"
|
||
fi
|
||
|
||
if ! check_command "rustc"; then
|
||
log_error "Rust installation failed"
|
||
return 1
|
||
fi
|
||
|
||
log_success "Rust installed: $(rustc --version)"
|
||
}
|
||
|
||
install_nushell() {
|
||
if check_command "nu"; then
|
||
local nu_version=$(nu --version 2>&1 | head -1)
|
||
log_success "NuShell already installed: $nu_version"
|
||
return 0
|
||
fi
|
||
|
||
log_info "Installing NuShell..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would install NuShell via: cargo install nu"
|
||
return 0
|
||
fi
|
||
|
||
# Try system package manager first
|
||
local os=$(detect_os)
|
||
|
||
if [[ "$os" == "macos" ]] && check_command "brew"; then
|
||
log_info "Installing NuShell via Homebrew..."
|
||
brew install nushell 2>&1 | tee -a "$LOG_FILE" || true
|
||
fi
|
||
|
||
# Fallback to cargo
|
||
if ! check_command "nu"; then
|
||
log_info "Installing NuShell via cargo..."
|
||
cargo install nu --locked 2>&1 | tee -a "$LOG_FILE"
|
||
fi
|
||
|
||
if ! check_command "nu"; then
|
||
log_error "NuShell installation failed"
|
||
return 1
|
||
fi
|
||
|
||
log_success "NuShell installed: $(nu --version 2>&1 | head -1)"
|
||
}
|
||
|
||
install_just() {
|
||
if check_command "just"; then
|
||
local just_version=$(just --version)
|
||
log_success "Just already installed: $just_version"
|
||
return 0
|
||
fi
|
||
|
||
log_info "Installing Just task runner..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would install Just via: cargo install just"
|
||
return 0
|
||
fi
|
||
|
||
cargo install just 2>&1 | tee -a "$LOG_FILE"
|
||
|
||
if ! check_command "just"; then
|
||
log_error "Just installation failed"
|
||
return 1
|
||
fi
|
||
|
||
log_success "Just installed: $(just --version)"
|
||
}
|
||
|
||
install_system_deps() {
|
||
local os=$(detect_os)
|
||
|
||
log_info "Checking system dependencies..."
|
||
|
||
case "$os" in
|
||
macos)
|
||
if ! check_command "cc"; then
|
||
log_info "Installing Xcode Command Line Tools..."
|
||
if [[ "$DRY_RUN" != "true" ]]; then
|
||
xcode-select --install 2>&1 | tee -a "$LOG_FILE" || true
|
||
# Wait for installation
|
||
sudo xcode-select --switch /Library/Developer/CommandLineTools 2>/dev/null || true
|
||
fi
|
||
fi
|
||
log_success "System dependencies ready"
|
||
;;
|
||
|
||
linux)
|
||
local distro=$(detect_linux_distro)
|
||
local deps=()
|
||
|
||
# Check for required tools
|
||
check_command "gcc" || deps+=("gcc")
|
||
check_command "make" || deps+=("make")
|
||
check_command "pkg-config" || deps+=("pkg-config")
|
||
|
||
# Check for sqlite development headers
|
||
if ! pkg-config --exists sqlite3 2>/dev/null; then
|
||
case "$distro" in
|
||
ubuntu|debian) deps+=("libsqlite3-dev") ;;
|
||
fedora|rhel) deps+=("sqlite-devel") ;;
|
||
arch) deps+=("sqlite") ;;
|
||
esac
|
||
fi
|
||
|
||
if [[ ${#deps[@]} -gt 0 ]]; then
|
||
log_info "Installing dependencies: ${deps[*]}"
|
||
|
||
if [[ "$DRY_RUN" != "true" ]]; then
|
||
case "$distro" in
|
||
ubuntu|debian)
|
||
sudo apt-get update && sudo apt-get install -y build-essential pkg-config libsqlite3-dev 2>&1 | tee -a "$LOG_FILE"
|
||
;;
|
||
fedora|rhel)
|
||
sudo dnf install -y gcc gcc-c++ make pkg-config sqlite-devel 2>&1 | tee -a "$LOG_FILE"
|
||
;;
|
||
arch)
|
||
sudo pacman -S --noconfirm base-devel pkg-config sqlite 2>&1 | tee -a "$LOG_FILE"
|
||
;;
|
||
*)
|
||
log_warn "Unknown Linux distribution. Install build essentials manually."
|
||
;;
|
||
esac
|
||
fi
|
||
fi
|
||
|
||
log_success "System dependencies ready"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
install_dependencies() {
|
||
if [[ "$SKIP_DEPS" == "true" ]]; then
|
||
log_warn "Skipping dependency installation (--skip-deps)"
|
||
return 0
|
||
fi
|
||
|
||
step "Install Core Dependencies"
|
||
|
||
install_rust
|
||
install_nushell
|
||
install_just
|
||
install_system_deps
|
||
|
||
log_success "All dependencies installed"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 3: Clone/Verify Repository
|
||
################################################################################
|
||
|
||
clone_or_verify_repo() {
|
||
step "Clone/Verify Repository"
|
||
|
||
# Check if already in a git repository
|
||
if git rev-parse --git-dir &> /dev/null; then
|
||
log_success "Already in a git repository"
|
||
INSTALL_DIR="$(pwd)"
|
||
cd "$INSTALL_DIR"
|
||
else
|
||
log_info "Cloning syntaxis repository..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would clone: $PROJECT_REPO to $INSTALL_DIR"
|
||
return 0
|
||
fi
|
||
|
||
if [[ -d "$INSTALL_DIR" ]]; then
|
||
if [[ -d "$INSTALL_DIR/.git" ]]; then
|
||
log_info "Repository already exists, updating..."
|
||
cd "$INSTALL_DIR"
|
||
git pull origin "$VERSION_TAG" 2>&1 | tee -a "$LOG_FILE"
|
||
else
|
||
log_error "Directory exists but is not a git repository: $INSTALL_DIR"
|
||
return 1
|
||
fi
|
||
else
|
||
mkdir -p "$(dirname "$INSTALL_DIR")"
|
||
git clone -b "$VERSION_TAG" "$PROJECT_REPO" "$INSTALL_DIR" 2>&1 | tee -a "$LOG_FILE"
|
||
cd "$INSTALL_DIR"
|
||
fi
|
||
fi
|
||
|
||
# Verify repository structure
|
||
local required_files=("Cargo.toml" "workspace-manager/Cargo.toml" "Justfile")
|
||
for file in "${required_files[@]}"; do
|
||
if [[ ! -f "$file" ]]; then
|
||
log_error "Missing required file: $file"
|
||
return 1
|
||
fi
|
||
done
|
||
|
||
log_success "Repository verified: $INSTALL_DIR"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 4: Build Workspace
|
||
################################################################################
|
||
|
||
build_workspace() {
|
||
if [[ "$CONFIG_ONLY" == "true" ]]; then
|
||
log_warn "Skipping build (--config-only)"
|
||
return 0
|
||
fi
|
||
|
||
step "Build Workspace"
|
||
|
||
log_info "Building workspace binaries (this may take 10-20 minutes)..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would run: cargo build --release --workspace (excluding workspace-api, workspace-vapora)"
|
||
return 0
|
||
fi
|
||
|
||
# Build release binaries
|
||
RUST_BACKTRACE=1 cargo build --release --workspace \
|
||
--exclude workspace-api \
|
||
--exclude workspace-vapora \
|
||
2>&1 | tee -a "$LOG_FILE"
|
||
|
||
if [[ $? -ne 0 ]]; then
|
||
log_error "Build failed"
|
||
return 1
|
||
fi
|
||
|
||
# Run tests
|
||
if [[ "$NO_VERIFY" != "true" ]]; then
|
||
log_info "Running tests..."
|
||
cargo test --release --workspace --lib \
|
||
--exclude workspace-api \
|
||
--exclude workspace-vapora \
|
||
2>&1 | tee -a "$LOG_FILE"
|
||
|
||
if [[ $? -ne 0 ]]; then
|
||
log_warn "Some tests failed, continuing anyway..."
|
||
fi
|
||
fi
|
||
|
||
log_success "Build completed"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 5: Install Binaries
|
||
################################################################################
|
||
|
||
install_binaries() {
|
||
if [[ "$CONFIG_ONLY" == "true" ]]; then
|
||
log_warn "Skipping binary installation (--config-only)"
|
||
return 0
|
||
fi
|
||
|
||
step "Install Binaries"
|
||
|
||
log_info "Installing binaries to ~/.cargo/bin..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would install: workspace, workspace-tui, workspace-dashboard"
|
||
return 0
|
||
fi
|
||
|
||
local binaries=("workspace-cli" "workspace-tui" "workspace-dashboard")
|
||
|
||
for binary in "${binaries[@]}"; do
|
||
log_info "Installing $binary..."
|
||
|
||
if ! cargo install --path "workspace-manager/crates/$binary" 2>&1 | tee -a "$LOG_FILE"; then
|
||
log_error "Failed to install $binary"
|
||
return 1
|
||
fi
|
||
done
|
||
|
||
# Verify installations
|
||
for binary in "workspace" "workspace-tui" "workspace-dashboard"; do
|
||
if ! check_command "$binary"; then
|
||
log_error "Binary not found in PATH: $binary"
|
||
return 1
|
||
fi
|
||
done
|
||
|
||
log_success "All binaries installed: workspace, workspace-tui, workspace-dashboard"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 6: Deploy Configurations
|
||
################################################################################
|
||
|
||
deploy_configurations() {
|
||
step "Deploy Configurations"
|
||
|
||
log_info "Deploying configuration files..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would deploy configurations to $CONFIG_DIR"
|
||
return 0
|
||
fi
|
||
|
||
# Create directories
|
||
mkdir -p "$CONFIG_DIR/features"
|
||
mkdir -p "$DATA_DIR"
|
||
mkdir -p "$MANIFEST_DIR"
|
||
|
||
# Deploy main config
|
||
if [[ -f "workspace-manager/workspace-api-config.template.toml" ]]; then
|
||
cp "workspace-manager/workspace-api-config.template.toml" "$CONFIG_DIR/workspace-api.toml"
|
||
log_success "Deployed: workspace-api.toml"
|
||
else
|
||
log_warn "Main config template not found"
|
||
fi
|
||
|
||
# Deploy feature configs
|
||
if [[ -d "workspace-manager/configs/features" ]]; then
|
||
for template in workspace-manager/configs/features/*.template; do
|
||
if [[ -f "$template" ]]; then
|
||
local filename=$(basename "$template" .template)
|
||
cp "$template" "$CONFIG_DIR/features/$filename"
|
||
fi
|
||
done
|
||
local count=$(find "$CONFIG_DIR/features" -type f | wc -l)
|
||
log_success "Deployed: $count feature configurations"
|
||
else
|
||
log_warn "Feature configs directory not found"
|
||
fi
|
||
|
||
log_success "Configurations deployed to: $CONFIG_DIR"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 7: Setup Environment
|
||
################################################################################
|
||
|
||
setup_environment() {
|
||
step "Setup Environment"
|
||
|
||
log_info "Setting up environment variables and PATH..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would update shell configuration files"
|
||
return 0
|
||
fi
|
||
|
||
# Detect shell
|
||
local shell_name=$(basename "$SHELL")
|
||
local shell_rc=""
|
||
|
||
case "$shell_name" in
|
||
bash)
|
||
shell_rc="$HOME/.bashrc"
|
||
;;
|
||
zsh)
|
||
shell_rc="$HOME/.zshrc"
|
||
;;
|
||
fish)
|
||
shell_rc="$HOME/.config/fish/config.fish"
|
||
;;
|
||
*)
|
||
log_warn "Unknown shell: $shell_name"
|
||
shell_rc="$HOME/.bashrc"
|
||
;;
|
||
esac
|
||
|
||
# Add cargo bin to PATH if not already present
|
||
if [[ -n "$shell_rc" ]] && [[ -f "$shell_rc" ]]; then
|
||
if ! grep -q '.cargo/bin' "$shell_rc"; then
|
||
echo "" >> "$shell_rc"
|
||
echo "# syntaxis" >> "$shell_rc"
|
||
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> "$shell_rc"
|
||
log_success "Updated $shell_rc"
|
||
fi
|
||
fi
|
||
|
||
# Export environment variables for current session
|
||
export PATH="$HOME/.cargo/bin:$PATH"
|
||
export WORKSPACE_CONFIG_DIR="$CONFIG_DIR"
|
||
export WORKSPACE_DATA_DIR="$DATA_DIR"
|
||
|
||
log_success "Environment configured"
|
||
}
|
||
|
||
################################################################################
|
||
# Phase 8: Verification & Summary
|
||
################################################################################
|
||
|
||
verify_installation() {
|
||
step "Verify Installation"
|
||
|
||
log_info "Verifying installation..."
|
||
|
||
if [[ "$DRY_RUN" == "true" ]]; then
|
||
log "[DRY RUN] Would verify binaries and configurations"
|
||
return 0
|
||
fi
|
||
|
||
local verification_ok=true
|
||
|
||
# Check binaries
|
||
for binary in workspace workspace-tui workspace-dashboard; do
|
||
if check_command "$binary"; then
|
||
log_success "Found: $binary"
|
||
else
|
||
log_warn "Not found: $binary"
|
||
verification_ok=false
|
||
fi
|
||
done
|
||
|
||
# Check configurations
|
||
if [[ -f "$CONFIG_DIR/workspace-api.toml" ]]; then
|
||
log_success "Found: workspace-api.toml"
|
||
else
|
||
log_warn "Not found: workspace-api.toml"
|
||
verification_ok=false
|
||
fi
|
||
|
||
local feature_count=$(find "$CONFIG_DIR/features" -type f 2>/dev/null | wc -l)
|
||
if [[ $feature_count -gt 0 ]]; then
|
||
log_success "Found: $feature_count feature configurations"
|
||
else
|
||
log_warn "No feature configurations found"
|
||
fi
|
||
|
||
if [[ "$verification_ok" == "true" ]]; then
|
||
log_success "Installation verified successfully"
|
||
return 0
|
||
else
|
||
log_warn "Some components missing, but installation may still be functional"
|
||
return 0 # Don't fail on partial verification
|
||
fi
|
||
}
|
||
|
||
show_summary() {
|
||
echo ""
|
||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo -e "${GREEN}✨ Installation Complete!${NC}"
|
||
echo -e "${GREEN}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
|
||
echo ""
|
||
echo "Installation Details:"
|
||
echo " Version: 0.1.0"
|
||
echo " Installation: $INSTALL_DIR"
|
||
echo " Binaries: workspace, workspace-tui, workspace-dashboard"
|
||
echo " Config: $CONFIG_DIR"
|
||
echo " Data: $DATA_DIR"
|
||
echo " Log: $LOG_FILE"
|
||
echo ""
|
||
echo "Quick Start:"
|
||
echo " workspace --help # CLI documentation"
|
||
echo " workspace-tui # Launch TUI"
|
||
echo " cd $INSTALL_DIR && just run-dashboard # Start web dashboard (port 3000)"
|
||
echo ""
|
||
echo "Next Steps:"
|
||
echo " 1. Customize config: nano $CONFIG_DIR/workspace-api.toml"
|
||
echo " 2. Create a project: workspace project create my-project"
|
||
echo " 3. Read docs: https://github.com/syntaxis"
|
||
echo ""
|
||
|
||
# Remind to reload shell
|
||
if [[ -n "$SHELL" ]]; then
|
||
echo -e "${YELLOW}⚠️${NC} Reload your shell for PATH changes to take effect:"
|
||
echo " source ~/$( basename "$SHELL" )rc"
|
||
fi
|
||
|
||
echo ""
|
||
log_success "Thank you for installing syntaxis!"
|
||
}
|
||
|
||
################################################################################
|
||
# Main Installation Flow
|
||
################################################################################
|
||
|
||
main() {
|
||
# Parse arguments
|
||
while [[ $# -gt 0 ]]; do
|
||
case "$1" in
|
||
-h|--help)
|
||
show_help
|
||
exit 0
|
||
;;
|
||
-v|--version)
|
||
VERSION_TAG="$2"
|
||
shift 2
|
||
;;
|
||
--prefix)
|
||
INSTALL_DIR="$2"
|
||
shift 2
|
||
;;
|
||
--skip-deps)
|
||
SKIP_DEPS=true
|
||
shift
|
||
;;
|
||
--no-verify)
|
||
NO_VERIFY=true
|
||
shift
|
||
;;
|
||
--unattended)
|
||
UNATTENDED=true
|
||
shift
|
||
;;
|
||
--keep-build)
|
||
KEEP_BUILD=true
|
||
shift
|
||
;;
|
||
--config-only)
|
||
CONFIG_ONLY=true
|
||
shift
|
||
;;
|
||
--dry-run)
|
||
DRY_RUN=true
|
||
shift
|
||
;;
|
||
*)
|
||
log_error "Unknown option: $1"
|
||
show_help
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Show welcome message
|
||
echo -e "${BLUE}"
|
||
echo "╔════════════════════════════════════════════════════════╗"
|
||
echo "║ syntaxis Installer v$INSTALLER_VERSION ║"
|
||
echo "║ One-Command Installation for Project Management ║"
|
||
echo "╚════════════════════════════════════════════════════════╝"
|
||
echo -e "${NC}"
|
||
|
||
log "Starting installation..."
|
||
log "Installation directory: $INSTALL_DIR"
|
||
log "Log file: $LOG_FILE"
|
||
|
||
# Execute installation phases
|
||
preflight_checks || exit 1
|
||
install_dependencies || exit 1
|
||
clone_or_verify_repo || exit 1
|
||
build_workspace || exit 1
|
||
install_binaries || exit 1
|
||
deploy_configurations || exit 1
|
||
setup_environment || exit 1
|
||
verify_installation || exit 1
|
||
|
||
# Show summary
|
||
show_summary
|
||
|
||
# Cleanup build artifacts if requested
|
||
if [[ "$KEEP_BUILD" != "true" ]] && [[ "$DRY_RUN" != "true" ]]; then
|
||
log_info "Cleaning up build artifacts..."
|
||
cd "$INSTALL_DIR"
|
||
rm -rf target 2>/dev/null || true
|
||
log_success "Cleanup complete"
|
||
fi
|
||
|
||
log_success "Installation successful"
|
||
exit 0
|
||
}
|
||
|
||
# Run main function
|
||
main "$@"
|