#!/bin/bash set -e # --- Helpers --- info() { printf "\033[1;34m%s\033[0m\n" "$*"; } warn() { printf "\033[1;33m%s\033[0m\n" "$*"; } error() { printf "\033[1;31m%s\033[0m\n" "$*"; } arch() { case "$(uname -m)" in x86_64) echo "x86_64" ;; aarch64) echo "aarch64" ;; armv7l) echo "armhf" ;; *) echo "unknown" ;; esac } # --- Check --- check_all() { local missing=() for cmd in git curl jq fzf starship eza bat delta fastfetch dotstate; do command -v "$cmd" &>/dev/null || missing+=("$cmd") done echo "${missing[@]}" } # --- Update --- update() { dotstate activate &>/dev/null || true sed -i.bak 's/^repo_mode\s*=\s*".*"/repo_mode = "Local"/' ~/.config/dotstate/config.toml &>/dev/null || echo 'repo_mode = "Local"' >> ~/.config/dotstate/config.toml &>/dev/null dotstate doctor --fix &>/dev/null || true dotstate activate &>/dev/null || true } # --- Install --- install_pkgs() { if command -v pacman &>/dev/null; then sudo pacman -S --noconfirm "$@" elif command -v dnf &>/dev/null; then sudo dnf install -y "$@" elif command -v apt &>/dev/null; then sudo apt update -qq && sudo apt install -y "$@" elif command -v zypper &>/dev/null; then sudo zypper install -y "$@" elif command -v apk &>/dev/null; then sudo apk add "$@" else return 1 fi } install_binary() { local name="$1" local arch arch=$(arch) mkdir -p $HOME/.config/zsh case "$name" in starship) info "installing starship" curl -sS https://starship.rs/install.sh | sh -s -- -y ;; eza) info "installing eza" local url="https://github.com/eza-community/eza/releases/latest/download/eza-${arch}-unknown-linux-musl.tar.gz" curl -sSfL "$url" | sudo tar xz -C /usr/local/bin ;; bat) info "installing bat" local url="https://github.com/sharkdp/bat/releases/latest/download/bat-${arch}-unknown-linux-musl.tar.gz" curl -sSfL "$url" | sudo tar xz --strip-components=1 -C /usr/local/bin "bat-${arch}-unknown-linux-musl/bat" ;; delta) info "installing delta" local url="https://github.com/dandavison/delta/releases/latest/download/delta-${arch}-unknown-linux-musl.tar.gz" curl -sSfL "$url" | sudo tar xz --strip-components=1 -C /usr/local/bin "delta-${arch}-unknown-linux-musl/delta" ;; fastfetch) info "installing fastfetch" local url="https://github.com/fastfetch-cli/fastfetch/releases/latest/download/fastfetch-linux-${arch}.tar.gz" curl -sSfL "$url" | sudo tar xz --strip-components=2 -C /usr/local/bin ;; jq) info "installing jq" local url="https://github.com/jqlang/jq/releases/latest/download/jq-linux-${arch}" curl -sSfL "$url" -o /usr/local/bin/jq sudo chmod +x /usr/local/bin/jq ;; dotstate) info "installing dotstate" curl -fsSL https://dotstate.serkan.dev/install.sh | bash ;; esac } install_missing() { local missing=("$@") [[ ${#missing[@]} -eq 0 ]] && return 0 declare -A PKG_NAMES=( [git]="git" [curl]="curl" [jq]="jq" [fzf]="fzf" [eza]="eza" [bat]="bat" [delta]="git-delta" [fastfetch]="fastfetch" ) local sys_pkgs=() local bin_pkgs=() for tool in "${missing[@]}"; do if [[ "$tool" == "starship" || "$tool" == "dotstate" ]]; then bin_pkgs+=("$tool") continue fi sys_pkgs+=("${PKG_NAMES[$tool]:-$tool}") done if [[ ${#sys_pkgs[@]} -gt 0 ]]; then info "installing from system repos: ${sys_pkgs[*]}" install_pkgs "${sys_pkgs[@]}" &>/dev/null || { warn "system install failed, falling back to binaries" bin_pkgs+=("${sys_pkgs[@]}") } fi for tool in "${bin_pkgs[@]}"; do install_binary "$tool" done } # --- Repo --- update_repo() { local REPO_URL="https://git.jeremymcclure.com/jeremy/dotstate-storage.git" local TARGET_DIR="$HOME/.config/dotstate/storage" if [[ -d "$TARGET_DIR/.git" ]]; then local remote_sha local_sha remote_sha=$(git ls-remote "$REPO_URL" HEAD | awk '{print $1}') local_sha=$(git -C "$TARGET_DIR" rev-parse HEAD) if [[ "$remote_sha" == "$local_sha" ]]; then info "Repository up to date" return 0 fi info "Repository out of date. Pulling updates..." git -C "$TARGET_DIR" pull &>/dev/null else info "Repository not found. Cloning..." git clone --depth=1 "$REPO_URL" "$TARGET_DIR" &>/dev/null fi } # --- Main --- MISSING=($(check_all)) if [[ ${#MISSING[@]} -eq 0 ]]; then info "all tools present" update else install_missing "${MISSING[@]}" fi update_repo info "Done"