#!/bin/bash # Strata Framework - Local Installation Script # Usage: ./scripts/install.sh [options] # --global Install globally to /usr/local # --local Install locally only (default) # --skip-deps Skip dependency checks # --no-shell Skip shell configuration # --help Show this help message set -e # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color BOLD='\033[1m' # Installation directories STRATA_HOME="${STRATA_HOME:-$HOME/.strata}" STRATA_BIN="$STRATA_HOME/bin" STRATA_COMPLETIONS="$STRATA_HOME/completions" STRATA_CONFIG="$STRATA_HOME/config" LOCAL_BIN="/usr/local/bin" # Script directory (where strata repo is) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_DIR="$(dirname "$SCRIPT_DIR")" # Default options INSTALL_GLOBAL=false SKIP_DEPS=false SKIP_SHELL=false # Parse arguments while [[ $# -gt 0 ]]; do case $1 in --global) INSTALL_GLOBAL=true shift ;; --local) INSTALL_GLOBAL=false shift ;; --skip-deps) SKIP_DEPS=true shift ;; --no-shell) SKIP_SHELL=true shift ;; --help|-h) echo "Strata Framework - Installation Script" echo "" echo "Usage: ./scripts/install.sh [options]" echo "" echo "Options:" echo " --global Install globally to /usr/local/bin (requires sudo)" echo " --local Install locally to ~/.strata (default)" echo " --skip-deps Skip dependency version checks" echo " --no-shell Skip shell configuration (PATH, completions)" echo " --help Show this help message" echo "" echo "Environment Variables:" echo " STRATA_HOME Installation directory (default: ~/.strata)" exit 0 ;; *) echo -e "${RED}Unknown option: $1${NC}" exit 1 ;; esac done # Print banner print_banner() { echo "" echo -e "${CYAN}" echo " ╔═══════════════════════════════════════════════════════╗" echo " ║ ║" echo " ║ ███████╗████████╗██████╗ █████╗ ████████╗ █████╗ ║" echo " ║ ██╔════╝╚══██╔══╝██╔══██╗██╔══██╗╚══██╔══╝██╔══██╗ ║" echo " ║ ███████╗ ██║ ██████╔╝███████║ ██║ ███████║ ║" echo " ║ ╚════██║ ██║ ██╔══██╗██╔══██║ ██║ ██╔══██║ ║" echo " ║ ███████║ ██║ ██║ ██║██║ ██║ ██║ ██║ ██║ ║" echo " ║ ╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ║" echo " ║ ║" echo " ║ Static Template Rendering Architecture ║" echo " ╚═══════════════════════════════════════════════════════╝" echo -e "${NC}" echo "" } # Print step print_step() { echo -e "${BLUE}▶${NC} $1" } # Print success print_success() { echo -e "${GREEN}✓${NC} $1" } # Print warning print_warning() { echo -e "${YELLOW}⚠${NC} $1" } # Print error print_error() { echo -e "${RED}✗${NC} $1" } # Check if command exists command_exists() { command -v "$1" &> /dev/null } # Get version number from version string get_version() { echo "$1" | grep -oE '[0-9]+\.[0-9]+' | head -1 } # Compare versions (returns 0 if $1 >= $2) version_gte() { [ "$(printf '%s\n' "$2" "$1" | sort -V | head -n1)" = "$2" ] } # Check system requirements check_requirements() { print_step "Checking system requirements..." echo "" local requirements_met=true # Check Go if command_exists go; then GO_VERSION=$(go version | grep -oE 'go[0-9]+\.[0-9]+' | sed 's/go//') if version_gte "$GO_VERSION" "1.21"; then print_success "Go $GO_VERSION (required: >= 1.21)" else print_warning "Go $GO_VERSION found, but >= 1.21 is recommended" fi else print_error "Go is not installed" echo " Install from: https://go.dev/dl/" echo " Or use: brew install go (macOS)" echo " sudo apt install golang-go (Ubuntu/Debian)" requirements_met=false fi # Check Node.js if command_exists node; then NODE_VERSION=$(node -v | sed 's/v//') NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1) if [ "$NODE_MAJOR" -ge 18 ]; then print_success "Node.js $NODE_VERSION (required: >= 18.0)" else print_warning "Node.js $NODE_VERSION found, but >= 18.0 is required" requirements_met=false fi else print_error "Node.js is not installed" echo " Install from: https://nodejs.org/" echo " Or use: brew install node (macOS)" echo " nvm install 20 (using nvm)" requirements_met=false fi # Check npm if command_exists npm; then NPM_VERSION=$(npm -v) print_success "npm $NPM_VERSION" else print_error "npm is not installed" requirements_met=false fi # Check git if command_exists git; then GIT_VERSION=$(git --version | grep -oE '[0-9]+\.[0-9]+\.[0-9]+') print_success "Git $GIT_VERSION" else print_warning "Git is not installed (optional, but recommended)" fi echo "" if [ "$requirements_met" = false ] && [ "$SKIP_DEPS" = false ]; then print_error "Some requirements are not met. Install missing dependencies and try again." echo " Or run with --skip-deps to continue anyway (not recommended)." exit 1 fi } # Create directory structure create_directories() { print_step "Creating Strata directories..." mkdir -p "$STRATA_HOME" mkdir -p "$STRATA_BIN" mkdir -p "$STRATA_COMPLETIONS" mkdir -p "$STRATA_CONFIG" mkdir -p "$REPO_DIR/bin" print_success "Created $STRATA_HOME" } # Build Go compiler build_compiler() { print_step "Building Strata compiler..." cd "$REPO_DIR/compiler" # Download Go dependencies echo " Downloading Go dependencies..." go mod tidy go mod download # Build the compiler echo " Compiling..." go build -ldflags="-s -w" -o "$REPO_DIR/bin/strata-compile" ./cmd/strata # Copy to strata home cp "$REPO_DIR/bin/strata-compile" "$STRATA_BIN/strata-compile" chmod +x "$STRATA_BIN/strata-compile" # Copy create-strata-compile CLI if [ -f "$REPO_DIR/bin/create-strata-compile" ]; then cp "$REPO_DIR/bin/create-strata-compile" "$STRATA_BIN/create-strata-compile" chmod +x "$STRATA_BIN/create-strata-compile" fi cd "$REPO_DIR" print_success "Compiler built successfully" } # Install npm dependencies install_npm_deps() { print_step "Installing npm dependencies..." cd "$REPO_DIR" npm install --silent print_success "npm dependencies installed" } # Install globally install_global() { if [ "$INSTALL_GLOBAL" = true ]; then print_step "Installing globally to $LOCAL_BIN..." if [ -w "$LOCAL_BIN" ]; then ln -sf "$STRATA_BIN/strata-compile" "$LOCAL_BIN/strata-compile" print_success "Linked strata-compile to $LOCAL_BIN/strata-compile" else echo " Requires sudo to write to $LOCAL_BIN" sudo ln -sf "$STRATA_BIN/strata-compile" "$LOCAL_BIN/strata-compile" print_success "Linked strata-compile to $LOCAL_BIN/strata-compile (with sudo)" fi fi } # Detect shell (use $SHELL env var which reflects user's login shell) detect_shell() { basename "${SHELL:-/bin/bash}" } # Get shell config file get_shell_config() { local shell_type="$1" case "$shell_type" in zsh) echo "$HOME/.zshrc" ;; bash) if [ -f "$HOME/.bash_profile" ]; then echo "$HOME/.bash_profile" else echo "$HOME/.bashrc" fi ;; fish) echo "$HOME/.config/fish/config.fish" ;; *) echo "$HOME/.profile" ;; esac } # Configure shell configure_shell() { if [ "$SKIP_SHELL" = true ]; then return fi print_step "Configuring shell..." local shell_type=$(detect_shell) local shell_config=$(get_shell_config "$shell_type") local strata_marker="# Strata Framework" # Check if already configured if [ -f "$shell_config" ] && grep -q "$strata_marker" "$shell_config"; then print_success "Shell already configured in $shell_config" return fi # Create backup if [ -f "$shell_config" ]; then cp "$shell_config" "${shell_config}.backup.$(date +%Y%m%d%H%M%S)" fi # Add Strata configuration cat >> "$shell_config" << 'SHELL_CONFIG' # Strata Framework export STRATA_HOME="$HOME/.strata" export PATH="$STRATA_HOME/bin:$PATH" # Strata aliases alias st='strata-compile' alias stdev='strata-compile dev' alias stbuild='strata-compile build' alias stgen='strata-compile generate' alias stnew='create-strata-compile' # Strata completions SHELL_CONFIG # Add shell-specific completion loading case "$shell_type" in zsh) cat >> "$shell_config" << 'ZSH_COMPLETION' if [ -f "$STRATA_HOME/completions/_strata" ]; then fpath=($STRATA_HOME/completions $fpath) autoload -Uz compinit && compinit fi ZSH_COMPLETION ;; bash) cat >> "$shell_config" << 'BASH_COMPLETION' if [ -f "$STRATA_HOME/completions/strata.bash" ]; then source "$STRATA_HOME/completions/strata.bash" fi BASH_COMPLETION ;; fish) cat >> "$shell_config" << 'FISH_COMPLETION' if test -f "$STRATA_HOME/completions/strata.fish" source "$STRATA_HOME/completions/strata.fish" end FISH_COMPLETION ;; esac print_success "Added Strata configuration to $shell_config" } # Generate and install completions install_completions() { if [ "$SKIP_SHELL" = true ]; then return fi print_step "Installing shell completions..." # Generate bash completion cat > "$STRATA_COMPLETIONS/strata.bash" << 'BASH_COMP' # Strata bash completion _strata_completions() { local cur prev opts COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" prev="${COMP_WORDS[COMP_CWORD-1]}" # Main commands local commands="dev build preview generate init help version" # Generate subcommands local generate_types="component page store layout middleware" case "$prev" in strata-compile|st) COMPREPLY=( $(compgen -W "$commands" -- "$cur") ) return 0 ;; generate|g) COMPREPLY=( $(compgen -W "$generate_types" -- "$cur") ) return 0 ;; dev) COMPREPLY=( $(compgen -W "--port --open --host" -- "$cur") ) return 0 ;; build) COMPREPLY=( $(compgen -W "--analyze --watch --minify --sourcemap" -- "$cur") ) return 0 ;; preview) COMPREPLY=( $(compgen -W "--port --host" -- "$cur") ) return 0 ;; --port) COMPREPLY=( $(compgen -W "3000 3001 4000 5000 8080" -- "$cur") ) return 0 ;; esac # Default: show all commands if [[ "$cur" == -* ]]; then COMPREPLY=( $(compgen -W "--help --version" -- "$cur") ) else COMPREPLY=( $(compgen -W "$commands" -- "$cur") ) fi } complete -F _strata_completions strata-compile complete -F _strata_completions st BASH_COMP # Generate zsh completion cat > "$STRATA_COMPLETIONS/_strata" << 'ZSH_COMP' #compdef strata-compile st # Strata zsh completion _strata() { local -a commands local -a generate_types commands=( 'dev:Start development server with hot reload' 'build:Build for production' 'preview:Preview production build' 'generate:Generate component, page, or store' 'init:Initialize new Strata project' 'help:Show help information' 'version:Show version information' ) generate_types=( 'component:Generate a new component' 'page:Generate a new page' 'store:Generate a new store' 'layout:Generate a new layout' 'middleware:Generate a new middleware' ) _arguments -C \ '1: :->command' \ '*: :->args' case "$state" in command) _describe -t commands 'strata-compile commands' commands ;; args) case "$words[2]" in generate|g) if [[ $CURRENT -eq 3 ]]; then _describe -t generate_types 'generate types' generate_types else _files fi ;; dev) _arguments \ '--port[Port number]:port:(3000 3001 4000 5000 8080)' \ '--open[Open browser automatically]' \ '--host[Host to bind]:host:(localhost 0.0.0.0)' ;; build) _arguments \ '--analyze[Analyze bundle size]' \ '--watch[Watch for changes]' \ '--minify[Minify output]' \ '--sourcemap[Generate sourcemaps]' ;; preview) _arguments \ '--port[Port number]:port:(4000 5000 8080)' \ '--host[Host to bind]:host:(localhost 0.0.0.0)' ;; *) _files ;; esac ;; esac } _strata "$@" ZSH_COMP # Generate fish completion cat > "$STRATA_COMPLETIONS/strata.fish" << 'FISH_COMP' # Strata fish completion # Main commands complete -c strata-compile -f -n "__fish_use_subcommand" -a "dev" -d "Start development server" complete -c strata-compile -f -n "__fish_use_subcommand" -a "build" -d "Build for production" complete -c strata-compile -f -n "__fish_use_subcommand" -a "preview" -d "Preview production build" complete -c strata-compile -f -n "__fish_use_subcommand" -a "generate" -d "Generate component/page/store" complete -c strata-compile -f -n "__fish_use_subcommand" -a "init" -d "Initialize new project" complete -c strata-compile -f -n "__fish_use_subcommand" -a "help" -d "Show help" complete -c strata-compile -f -n "__fish_use_subcommand" -a "version" -d "Show version" # Generate subcommands complete -c strata-compile -f -n "__fish_seen_subcommand_from generate" -a "component" -d "Generate component" complete -c strata-compile -f -n "__fish_seen_subcommand_from generate" -a "page" -d "Generate page" complete -c strata-compile -f -n "__fish_seen_subcommand_from generate" -a "store" -d "Generate store" complete -c strata-compile -f -n "__fish_seen_subcommand_from generate" -a "layout" -d "Generate layout" # Dev options complete -c strata-compile -f -n "__fish_seen_subcommand_from dev" -l port -d "Port number" complete -c strata-compile -f -n "__fish_seen_subcommand_from dev" -l open -d "Open browser" complete -c strata-compile -f -n "__fish_seen_subcommand_from dev" -l host -d "Host to bind" # Build options complete -c strata-compile -f -n "__fish_seen_subcommand_from build" -l analyze -d "Analyze bundle" complete -c strata-compile -f -n "__fish_seen_subcommand_from build" -l watch -d "Watch mode" complete -c strata-compile -f -n "__fish_seen_subcommand_from build" -l minify -d "Minify output" complete -c strata-compile -f -n "__fish_seen_subcommand_from build" -l sourcemap -d "Generate sourcemaps" # Alias complete -c st -w strata-compile FISH_COMP print_success "Shell completions installed" } # Create config file create_config() { print_step "Creating configuration..." # Create global strata config cat > "$STRATA_CONFIG/strata.json" << CONFIG { "version": "0.1.0", "installPath": "$STRATA_HOME", "repoPath": "$REPO_DIR", "installedAt": "$(date -u +"%Y-%m-%dT%H:%M:%SZ")", "shell": { "configured": $([ "$SKIP_SHELL" = true ] && echo "false" || echo "true"), "completions": $([ "$SKIP_SHELL" = true ] && echo "false" || echo "true") }, "global": $INSTALL_GLOBAL } CONFIG print_success "Configuration created at $STRATA_CONFIG/strata.json" } # Print success message print_final() { echo "" echo -e "${GREEN}════════════════════════════════════════════════════════${NC}" echo -e "${GREEN} Installation Complete! ${NC}" echo -e "${GREEN}════════════════════════════════════════════════════════${NC}" echo "" echo -e " ${BOLD}Strata has been installed to:${NC} $STRATA_HOME" echo "" echo -e " ${BOLD}Quick Start:${NC}" echo "" echo " 1. Restart your terminal or run:" echo -e " ${CYAN}source $(get_shell_config $(detect_shell))${NC}" echo "" echo " 2. Create a new project:" echo -e " ${CYAN}npx create-strata-compile my-app${NC}" echo -e " ${CYAN}cd my-app${NC}" echo -e " ${CYAN}npm install${NC}" echo -e " ${CYAN}strata-compile dev${NC}" echo "" echo " Or try the example app:" echo -e " ${CYAN}cd $REPO_DIR/examples/basic-app${NC}" echo -e " ${CYAN}strata-compile dev${NC}" echo "" echo -e " ${BOLD}Available Commands:${NC}" echo "" echo " strata-compile dev Start dev server with hot reload" echo " strata-compile build Build for production" echo " strata-compile preview Preview production build" echo " strata-compile generate Generate component/page/store" echo "" echo -e " ${BOLD}Aliases:${NC}" echo "" echo " st → strata-compile" echo " stdev → strata-compile dev" echo " stbuild → strata-compile build" echo " stgen → strata-compile generate" echo " stnew → npx create-strata-compile" echo "" echo -e " ${BOLD}Documentation:${NC} https://stratajs.dev/docs" echo -e " ${BOLD}GitHub:${NC} https://github.com/CarGDev/strata-compile" echo "" } # Main installation main() { print_banner check_requirements create_directories build_compiler install_npm_deps install_global configure_shell install_completions create_config print_final } # Run main main