From 64bf2e281e6ddfb2f5fbe8eed01509e40c3be951 Mon Sep 17 00:00:00 2001 From: Snider Date: Wed, 28 Jan 2026 14:57:30 +0000 Subject: [PATCH] feat: add installation scripts for cross-platform setup - Add Makefile for make-based workflow - Add setup.sh / setup.bat for one-command bootstrap - Add scripts/install-deps.sh for macOS/Linux dependencies - Add scripts/install-deps.ps1 for Windows (Chocolatey) - Add scripts/install-core.sh to build/download core CLI - Add scripts/install-core.ps1 for Windows - Update README with installation instructions Developers can now run: macOS/Linux: ./setup.sh (or make setup) Windows: .\setup.bat (as Admin) Co-Authored-By: Claude Opus 4.5 --- Makefile | 50 ++++++++++ README.md | 26 +++++- scripts/install-core.ps1 | 98 ++++++++++++++++++++ scripts/install-core.sh | 139 ++++++++++++++++++++++++++++ scripts/install-deps.ps1 | 82 +++++++++++++++++ scripts/install-deps.sh | 191 +++++++++++++++++++++++++++++++++++++++ setup.bat | 51 +++++++++++ setup.sh | 28 ++++++ 8 files changed, 660 insertions(+), 5 deletions(-) create mode 100644 Makefile create mode 100644 scripts/install-core.ps1 create mode 100755 scripts/install-core.sh create mode 100644 scripts/install-deps.ps1 create mode 100755 scripts/install-deps.sh create mode 100644 setup.bat create mode 100755 setup.sh diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..69e232f --- /dev/null +++ b/Makefile @@ -0,0 +1,50 @@ +# Host UK Developer Workspace +# Run `make setup` to bootstrap your environment + +CORE_REPO := github.com/Snider/Core +CORE_VERSION := latest +INSTALL_DIR := $(HOME)/.local/bin + +.PHONY: all setup install-deps install-go install-core doctor clean help + +all: help + +help: + @echo "Host UK Developer Workspace" + @echo "" + @echo "Usage:" + @echo " make setup Full setup (deps + core + clone repos)" + @echo " make install-deps Install system dependencies (go, gh, etc)" + @echo " make install-core Build and install core CLI" + @echo " make doctor Check environment health" + @echo " make clone Clone all repos into packages/" + @echo " make clean Remove built artifacts" + @echo "" + @echo "Quick start:" + @echo " make setup" + +setup: install-deps install-core doctor clone + @echo "" + @echo "Setup complete! Run 'core health' to verify." + +install-deps: + @echo "Installing dependencies..." + @./scripts/install-deps.sh + +install-go: + @echo "Installing Go..." + @./scripts/install-go.sh + +install-core: + @echo "Installing core CLI..." + @./scripts/install-core.sh + +doctor: + @core doctor || echo "Run 'make install-core' first if core is not found" + +clone: + @core setup || echo "Run 'make install-core' first if core is not found" + +clean: + @rm -rf ./build + @echo "Cleaned build artifacts" diff --git a/README.md b/README.md index 6b04f36..1ace982 100644 --- a/README.md +++ b/README.md @@ -4,22 +4,38 @@ This repository bootstraps a complete Host UK development environment. ## Quick Start +### One-liner (macOS/Linux) +```bash +git clone git@github.com:host-uk/core-devops.git && cd core-devops && make setup +``` + +### Step by step ```bash # 1. Clone this repo git clone git@github.com:host-uk/core-devops.git cd core-devops -# 2. Check your environment -core doctor +# 2. Install dependencies and core CLI +make setup -# 3. Clone all packages -core setup +# Or manually: +./scripts/install-deps.sh # Install go, gh, php, node, etc. +./scripts/install-core.sh # Build and install core CLI -# 4. Start developing +# 3. Start developing cd packages/core-php composer install ``` +### Windows (PowerShell as Admin) +```powershell +git clone git@github.com:host-uk/core-devops.git +cd core-devops +.\scripts\install-deps.ps1 # Install via Chocolatey +.\scripts\install-core.ps1 # Build and install core CLI +core setup # Clone all repos +``` + ## Prerequisites Run `core doctor` to check your environment. You'll need: diff --git a/scripts/install-core.ps1 b/scripts/install-core.ps1 new file mode 100644 index 0000000..950835b --- /dev/null +++ b/scripts/install-core.ps1 @@ -0,0 +1,98 @@ +# Install the Core CLI (Windows) +# Run: .\scripts\install-core.ps1 + +$ErrorActionPreference = "Stop" + +$Repo = "Snider/Core" +$InstallDir = "$env:LOCALAPPDATA\Programs\core" + +function Write-Info { Write-Host "[INFO] $args" -ForegroundColor Green } +function Write-Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow } +function Write-Err { Write-Host "[ERROR] $args" -ForegroundColor Red; exit 1 } + +function Test-Command($cmd) { + return [bool](Get-Command $cmd -ErrorAction SilentlyContinue) +} + +# Download pre-built binary +function Download-Binary { + $arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } + $url = "https://github.com/$Repo/releases/latest/download/core-windows-$arch.exe" + + Write-Info "Attempting to download pre-built binary..." + Write-Info "URL: $url" + + try { + New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null + Invoke-WebRequest -Uri $url -OutFile "$InstallDir\core.exe" -UseBasicParsing + Write-Info "Downloaded to $InstallDir\core.exe" + return $true + } catch { + Write-Warn "No pre-built binary available, will build from source" + return $false + } +} + +# Build from source +function Build-FromSource { + if (-not (Test-Command go)) { + Write-Err "Go is required to build from source. Run '.\scripts\install-deps.ps1' first" + } + + $tmpdir = New-TemporaryFile | ForEach-Object { Remove-Item $_; New-Item -ItemType Directory -Path $_ } + + Write-Info "Cloning $Repo..." + git clone --depth 1 "https://github.com/$Repo.git" "$tmpdir\Core" + + Write-Info "Building core CLI..." + Push-Location "$tmpdir\Core" + go build -o core.exe ./cmd/core + Pop-Location + + New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null + Move-Item "$tmpdir\Core\core.exe" "$InstallDir\core.exe" -Force + + Remove-Item -Recurse -Force $tmpdir + Write-Info "Built and installed to $InstallDir\core.exe" +} + +# Add to PATH +function Setup-Path { + $userPath = [Environment]::GetEnvironmentVariable("PATH", "User") + if ($userPath -notlike "*$InstallDir*") { + Write-Info "Adding $InstallDir to PATH..." + [Environment]::SetEnvironmentVariable("PATH", "$userPath;$InstallDir", "User") + $env:PATH = "$env:PATH;$InstallDir" + } +} + +# Verify installation +function Verify { + Setup-Path + + if (Test-Command core) { + Write-Info "Verifying installation..." + & core --help | Select-Object -First 5 + Write-Host "" + Write-Info "core CLI installed successfully!" + } elseif (Test-Path "$InstallDir\core.exe") { + Write-Info "core CLI installed to $InstallDir\core.exe" + Write-Info "Restart your terminal to use 'core' command" + } else { + Write-Err "Installation failed" + } +} + +# Main +function Main { + Write-Info "Installing Core CLI..." + + # Try download first, fallback to build + if (-not (Download-Binary)) { + Build-FromSource + } + + Verify +} + +Main diff --git a/scripts/install-core.sh b/scripts/install-core.sh new file mode 100755 index 0000000..841f6d5 --- /dev/null +++ b/scripts/install-core.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +set -e + +# Install the Core CLI +# Either downloads a pre-built binary or builds from source + +REPO="Snider/Core" +INSTALL_DIR="${INSTALL_DIR:-$HOME/.local/bin}" +BUILD_FROM_SOURCE="${BUILD_FROM_SOURCE:-auto}" + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +info() { echo -e "${GREEN}[INFO]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } + +has() { + command -v "$1" &> /dev/null +} + +detect_arch() { + case "$(uname -m)" in + x86_64|amd64) echo "amd64" ;; + arm64|aarch64) echo "arm64" ;; + *) echo "unknown" ;; + esac +} + +detect_os() { + case "$(uname -s)" in + Darwin*) echo "darwin" ;; + Linux*) echo "linux" ;; + MINGW*|MSYS*|CYGWIN*) echo "windows" ;; + *) echo "unknown" ;; + esac +} + +# Try to download pre-built binary +download_binary() { + local os=$(detect_os) + local arch=$(detect_arch) + local url="https://github.com/$REPO/releases/latest/download/core-${os}-${arch}" + + if [[ "$os" == "windows" ]]; then + url="${url}.exe" + fi + + info "Attempting to download pre-built binary..." + info "URL: $url" + + if curl -fsSL -o /tmp/core "$url" 2>/dev/null; then + chmod +x /tmp/core + mkdir -p "$INSTALL_DIR" + mv /tmp/core "$INSTALL_DIR/core" + info "Downloaded to $INSTALL_DIR/core" + return 0 + else + warn "No pre-built binary available, will build from source" + return 1 + fi +} + +# Build from source +build_from_source() { + if ! has go; then + error "Go is required to build from source. Run './scripts/install-deps.sh' first" + fi + + local tmpdir=$(mktemp -d) + info "Cloning $REPO..." + git clone --depth 1 "https://github.com/$REPO.git" "$tmpdir/Core" + + info "Building core CLI..." + cd "$tmpdir/Core" + go build -o core ./cmd/core + + mkdir -p "$INSTALL_DIR" + mv core "$INSTALL_DIR/core" + + rm -rf "$tmpdir" + info "Built and installed to $INSTALL_DIR/core" +} + +# Add to PATH if needed +setup_path() { + if [[ ":$PATH:" != *":$INSTALL_DIR:"* ]]; then + warn "$INSTALL_DIR is not in your PATH" + echo "" + echo "Add this to your shell profile (~/.bashrc, ~/.zshrc, etc.):" + echo "" + echo " export PATH=\"\$PATH:$INSTALL_DIR\"" + echo "" + + # Try to add to current session + export PATH="$PATH:$INSTALL_DIR" + fi +} + +# Verify installation +verify() { + if has core; then + info "Verifying installation..." + core --help | head -5 + echo "" + info "core CLI installed successfully!" + else + setup_path + if [[ -f "$INSTALL_DIR/core" ]]; then + info "core CLI installed to $INSTALL_DIR/core" + info "Restart your shell or run: export PATH=\"\$PATH:$INSTALL_DIR\"" + else + error "Installation failed" + fi + fi +} + +main() { + info "Installing Core CLI..." + + mkdir -p "$INSTALL_DIR" + + # Try download first, fallback to build + if [[ "$BUILD_FROM_SOURCE" == "true" ]]; then + build_from_source + elif [[ "$BUILD_FROM_SOURCE" == "false" ]]; then + download_binary || error "Download failed and BUILD_FROM_SOURCE=false" + else + # auto: try download, fallback to build + download_binary || build_from_source + fi + + setup_path + verify +} + +main "$@" diff --git a/scripts/install-deps.ps1 b/scripts/install-deps.ps1 new file mode 100644 index 0000000..f3ec533 --- /dev/null +++ b/scripts/install-deps.ps1 @@ -0,0 +1,82 @@ +# Install system dependencies for Host UK development (Windows) +# Run: .\scripts\install-deps.ps1 + +$ErrorActionPreference = "Stop" + +function Write-Info { Write-Host "[INFO] $args" -ForegroundColor Green } +function Write-Warn { Write-Host "[WARN] $args" -ForegroundColor Yellow } +function Write-Err { Write-Host "[ERROR] $args" -ForegroundColor Red; exit 1 } + +function Test-Command($cmd) { + return [bool](Get-Command $cmd -ErrorAction SilentlyContinue) +} + +# Install Chocolatey if not present +function Install-Chocolatey { + if (Test-Command choco) { + Write-Info "Chocolatey already installed" + return + } + + Write-Info "Installing Chocolatey..." + Set-ExecutionPolicy Bypass -Scope Process -Force + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072 + Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')) + + # Refresh PATH + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User") +} + +# Install a package via Chocolatey +function Install-ChocoPackage($pkg, $cmd = $pkg) { + if (Test-Command $cmd) { + Write-Info "$pkg already installed" + } else { + Write-Info "Installing $pkg..." + choco install $pkg -y + # Refresh PATH + $env:PATH = [System.Environment]::GetEnvironmentVariable("PATH", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("PATH", "User") + } +} + +# Main setup +function Main { + Write-Info "Setting up Windows development environment..." + + # Check if running as admin + $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) + if (-not $isAdmin) { + Write-Err "Please run this script as Administrator" + } + + Install-Chocolatey + + # Core tools + Install-ChocoPackage "git" + Install-ChocoPackage "gh" + Install-ChocoPackage "golang" "go" + + # PHP development + Install-ChocoPackage "php" + Install-ChocoPackage "composer" + + # Node development + Install-ChocoPackage "nodejs" "node" + + # pnpm via npm + if (-not (Test-Command pnpm)) { + Write-Info "Installing pnpm..." + npm install -g pnpm + } + + # Optional: Docker Desktop + if (-not (Test-Command docker)) { + Write-Warn "Docker not installed. Install Docker Desktop manually if needed." + } + + Write-Info "Dependencies installed!" + Write-Host "" + Write-Host "Next: Run '.\scripts\install-core.ps1' to install the core CLI" +} + +Main diff --git a/scripts/install-deps.sh b/scripts/install-deps.sh new file mode 100755 index 0000000..572e7ac --- /dev/null +++ b/scripts/install-deps.sh @@ -0,0 +1,191 @@ +#!/usr/bin/env bash +set -e + +# Install system dependencies for Host UK development +# Supports: macOS (brew), Linux (apt/dnf), Windows (choco via WSL) + +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' + +info() { echo -e "${GREEN}[INFO]${NC} $1"; } +warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } +error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } + +# Detect OS +detect_os() { + case "$(uname -s)" in + Darwin*) echo "macos" ;; + Linux*) echo "linux" ;; + MINGW*|MSYS*|CYGWIN*) echo "windows" ;; + *) echo "unknown" ;; + esac +} + +# Check if command exists +has() { + command -v "$1" &> /dev/null +} + +# Install Homebrew (macOS/Linux) +install_brew() { + if has brew; then + info "Homebrew already installed" + return + fi + + info "Installing Homebrew..." + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + # Add to PATH for this session + if [[ -f /opt/homebrew/bin/brew ]]; then + eval "$(/opt/homebrew/bin/brew shellenv)" + elif [[ -f /home/linuxbrew/.linuxbrew/bin/brew ]]; then + eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + fi +} + +# Install packages via brew +brew_install() { + local pkg=$1 + if has "$pkg"; then + info "$pkg already installed" + else + info "Installing $pkg..." + brew install "$pkg" + fi +} + +# Install packages via apt +apt_install() { + local pkg=$1 + if has "$pkg"; then + info "$pkg already installed" + else + info "Installing $pkg..." + sudo apt-get update -qq + sudo apt-get install -y "$pkg" + fi +} + +# macOS setup +setup_macos() { + info "Setting up macOS environment..." + + install_brew + + brew_install git + brew_install gh + brew_install go + brew_install php + brew_install composer + brew_install node + brew_install pnpm + + # Optional + if ! has docker; then + warn "Docker not installed. Install Docker Desktop manually if needed." + fi +} + +# Linux setup +setup_linux() { + info "Setting up Linux environment..." + + # Detect package manager + if has apt-get; then + setup_linux_apt + elif has dnf; then + setup_linux_dnf + elif has brew; then + setup_linux_brew + else + warn "Unknown package manager. Installing Homebrew..." + install_brew + setup_linux_brew + fi +} + +setup_linux_apt() { + apt_install git + apt_install gh || warn "GitHub CLI may need manual install: https://cli.github.com" + + # Go + if ! has go; then + info "Installing Go..." + sudo apt-get install -y golang-go || { + # Fallback to manual install for newer version + curl -LO https://go.dev/dl/go1.22.0.linux-amd64.tar.gz + sudo rm -rf /usr/local/go + sudo tar -C /usr/local -xzf go1.22.0.linux-amd64.tar.gz + rm go1.22.0.linux-amd64.tar.gz + export PATH=$PATH:/usr/local/go/bin + } + fi + + # PHP + apt_install php + + # Composer + if ! has composer; then + info "Installing Composer..." + curl -sS https://getcomposer.org/installer | php + sudo mv composer.phar /usr/local/bin/composer + fi + + # Node + if ! has node; then + info "Installing Node.js..." + curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash - + sudo apt-get install -y nodejs + fi + + # pnpm + if ! has pnpm; then + info "Installing pnpm..." + npm install -g pnpm + fi +} + +setup_linux_dnf() { + sudo dnf install -y git gh golang php composer nodejs + npm install -g pnpm +} + +setup_linux_brew() { + install_brew + brew_install git + brew_install gh + brew_install go + brew_install php + brew_install composer + brew_install node + brew_install pnpm +} + +# Windows setup (via chocolatey in PowerShell or WSL) +setup_windows() { + warn "Windows detected. Please run scripts/install-deps.ps1 in PowerShell" + warn "Or use WSL with: wsl ./scripts/install-deps.sh" + exit 1 +} + +# Main +main() { + local os=$(detect_os) + info "Detected OS: $os" + + case "$os" in + macos) setup_macos ;; + linux) setup_linux ;; + windows) setup_windows ;; + *) error "Unsupported OS: $os" ;; + esac + + info "Dependencies installed!" + echo "" + echo "Next: Run './scripts/install-core.sh' to install the core CLI" +} + +main "$@" diff --git a/setup.bat b/setup.bat new file mode 100644 index 0000000..d728f71 --- /dev/null +++ b/setup.bat @@ -0,0 +1,51 @@ +@echo off +REM Quick setup script for Windows +REM Run as Administrator: .\setup.bat + +echo === Host UK Developer Workspace Setup === +echo. + +REM Check for admin rights +net session >nul 2>&1 +if %errorlevel% neq 0 ( + echo ERROR: Please run this script as Administrator + echo Right-click and select "Run as administrator" + pause + exit /b 1 +) + +REM Install dependencies +echo Installing dependencies... +powershell -ExecutionPolicy Bypass -File "%~dp0scripts\install-deps.ps1" +if %errorlevel% neq 0 goto :error + +REM Install core CLI +echo. +echo Installing core CLI... +powershell -ExecutionPolicy Bypass -File "%~dp0scripts\install-core.ps1" +if %errorlevel% neq 0 goto :error + +REM Refresh PATH +set "PATH=%PATH%;%LOCALAPPDATA%\Programs\core" + +REM Run doctor +echo. +echo === Verifying environment === +core doctor + +REM Clone repos +echo. +echo === Cloning repositories === +core setup + +echo. +echo === Setup complete! === +echo Run 'core health' to check status +pause +exit /b 0 + +:error +echo. +echo Setup failed! Check the error above. +pause +exit /b 1 diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..29f5a1d --- /dev/null +++ b/setup.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# Quick setup script - just run: ./setup.sh +set -e + +cd "$(dirname "$0")" + +echo "=== Host UK Developer Workspace Setup ===" +echo "" + +# Install dependencies +./scripts/install-deps.sh + +# Install core CLI +./scripts/install-core.sh + +# Run doctor to verify +echo "" +echo "=== Verifying environment ===" +core doctor || true + +# Clone repos +echo "" +echo "=== Cloning repositories ===" +core setup + +echo "" +echo "=== Setup complete! ===" +echo "Run 'core health' to check status"