#!/bin/bash # ============================================================================== # Conan2 Development Environment Setup # # Description: Provisions system dependencies, shell configuration, and Conan2. # Designed for Debian/Ubuntu-based DevContainers or CI Runners. # Usage: CONAN_USR=x CONAN_PSW=y ./postStartCommand.sh # ============================================================================== set -euo pipefail # --- Configuration ------------------------------------------------------------ # Versions & Remote Resources TASK_VERSION="v3.45.5" GLOW_VERSION="2.1.1" CONAN_CONFIG_URL="https://package-cloud.dns.army/ros2/conan2-config.git" CONAN_REMOTE_NAME="package-cloud-ros2-conan2" # Localization TIMEZONE="Europe/Berlin" # Paths LOCAL_BIN="$HOME/.local/bin" ZSH_CUSTOM="${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}" # --- Helpers ------------------------------------------------------------------ log() { echo -e "\033[1;34m>>> [SETUP] $1\033[0m" } error() { echo -e "\033[1;31m!!! [ERROR] $1\033[0m" >&2 exit 1 } cleanup() { # Remove temp files on exit (successful or not) rm -f glow.deb install_task.sh } trap cleanup EXIT ensure_env_vars() { if [[ -z "${CONAN_USR:-}" ]] || [[ -z "${CONAN_PSW:-}" ]]; then error "CONAN_USR and CONAN_PSW environment variables are required." fi } detect_arch() { local arch arch=$(dpkg --print-architecture) case "$arch" in amd64) echo "amd64" ;; arm64) echo "arm64" ;; *) error "Unsupported architecture: $arch" ;; esac } # --- Installation Functions --------------------------------------------------- install_system_dependencies() { log "Installing system dependencies..." export DEBIAN_FRONTEND=noninteractive apt-get update -q apt-get install -y -q --no-install-recommends \ tzdata curl git zsh python3 python3-pip python3-venv \ ca-certificates gnupg pipx # Ensure pipx path is available immediately for this script export PATH="$LOCAL_BIN:$PATH" pipx ensurepath } configure_timezone() { log "Configuring timezone ($TIMEZONE)..." local tz_path="/usr/share/zoneinfo/$TIMEZONE" # Validation: Ensure the requested timezone actually exists if [ ! -f "$tz_path" ]; then error "Timezone data not found at '$tz_path'. Please check the TIMEZONE variable." fi ln -fs "$tz_path" /etc/localtime echo "$TIMEZONE" >/etc/timezone dpkg-reconfigure -f noninteractive tzdata } install_shell_tools() { log "Setting up Shell (Oh My Zsh)..." if [ ! -d "$HOME/.oh-my-zsh" ]; then sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" "" --unattended else log "Oh My Zsh already installed. Skipping." fi } install_conan() { log "Installing Conan via pipx (Isolated)..." # Config log "Installing Conan Config..." # Force allows overwriting existing configs which is usually desired in setup scripts conan config install "$CONAN_CONFIG_URL" --type git --args="--branch main" log "Authenticating Conan..." conan remote login "$CONAN_REMOTE_NAME" "$CONAN_USR" -p "$CONAN_PSW" } install_utilities() { local arch arch=$(detect_arch) # 1. Taskfile log "Installing Taskfile ($TASK_VERSION)..." curl -sL -o install_task.sh https://taskfile.dev/install.sh sh install_task.sh -d -b "$LOCAL_BIN" "$TASK_VERSION" # 2. Glow log "Installing Glow ($GLOW_VERSION for $arch)..." local glow_url="https://github.com/charmbracelet/glow/releases/download/v${GLOW_VERSION}/glow_${GLOW_VERSION}_${arch}.deb" curl -L -o glow.deb "$glow_url" dpkg -i glow.deb } configure_persistence() { log "Persisting configurations..." local zshrc="$HOME/.zshrc" touch "$zshrc" # Helper to append if missing append_if_missing() { local file="$1" local content="$2" if ! grep -Fxq "$content" "$file"; then echo "$content" >>"$file" fi } # Add Local Bin to Path local path_export='export PATH="$HOME/.local/bin:$PATH"' append_if_missing "$HOME/.bashrc" "$path_export" append_if_missing "$zshrc" "$path_export" # Shell Completions append_if_missing "$zshrc" 'eval "$(task --completion zsh)"' append_if_missing "$zshrc" 'eval "$(glow completion zsh)"' # Git Safe Directory git config --global --add safe.directory /workspaces/conan2-ros2-hesai-lidar } run_tasks() { if [ -f "Taskfile.yml" ] || [ -f "Taskfile.yaml" ]; then log "Running default Task..." "$LOCAL_BIN/task" --yes else log "No Taskfile found. Skipping 'task --yes'." fi } # --- Main Execution ----------------------------------------------------------- main() { ensure_env_vars install_system_dependencies configure_timezone install_shell_tools install_utilities # Task & Glow install_conan configure_persistence run_tasks log "Setup complete successfully." } main