From 89666e74853eb257b2103370e5481cbbe0e005d4 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Tue, 30 Jun 2026 03:36:22 -0400 Subject: [PATCH] Add update command & podman host to bash --- bin/panama | 227 ++++++++++++++++++++++++++++++++++++++++++++++ config/bash/shell | 3 + 2 files changed, 230 insertions(+) create mode 100755 bin/panama diff --git a/bin/panama b/bin/panama new file mode 100755 index 0000000..fd6f164 --- /dev/null +++ b/bin/panama @@ -0,0 +1,227 @@ +#!/usr/bin/env bash +# +# panama – Helper for managing the Panama dotfiles/repo +# Version 1.0 +# Author: Gabriel Brown +# +# Commands: +# update Commit & sync local changes (or just pull if clean) +# edit Open the Panama repo in Neovim +# help Show this help +# +# Designed to grow: add new subcommands as cmd_ functions and +# register them in the dispatcher / usage block below. + +set -euo pipefail + +PROGRAM=$(basename "$0") +VERSION="1.0" + +# ---------------------------------------------------------------------------- +# Locate the Panama repo (this script lives in /bin/panama) +# ---------------------------------------------------------------------------- +SCRIPT_PATH=$(readlink -f "${BASH_SOURCE[0]}") +PANAMA_DIR=$(cd "$(dirname "$SCRIPT_PATH")/.." && pwd) + +# ---------------------------------------------------------------------------- +# Pretty output +# ---------------------------------------------------------------------------- +if [[ -t 1 ]] && command -v tput >/dev/null 2>&1 && [[ $(tput colors 2>/dev/null || echo 0) -ge 8 ]]; then + BOLD=$(tput bold); RESET=$(tput sgr0) + RED=$(tput setaf 1); GREEN=$(tput setaf 2); YELLOW=$(tput setaf 3) + BLUE=$(tput setaf 4); MAGENTA=$(tput setaf 5); CYAN=$(tput setaf 6) +else + BOLD=""; RESET=""; RED=""; GREEN=""; YELLOW=""; BLUE=""; MAGENTA=""; CYAN="" +fi + +info() { printf '%s==>%s %s\n' "${BLUE}${BOLD}" "$RESET" "$*"; } +ok() { printf '%s✓%s %s\n' "${GREEN}${BOLD}" "$RESET" "$*"; } +warn() { printf '%s!%s %s\n' "${YELLOW}${BOLD}" "$RESET" "$*"; } +err() { printf '%s✗%s %s\n' "${RED}${BOLD}" "$RESET" "$*" >&2; } +header(){ printf '\n%s%s%s\n' "${MAGENTA}${BOLD}" "$*" "$RESET"; } + +# Ask a yes/no question. Returns 0 for yes, 1 for no. Default = no. +confirm() { + local prompt="$1" reply + printf '%s?%s %s %s[y/N]%s ' "${CYAN}${BOLD}" "$RESET" "$prompt" "$BOLD" "$RESET" + read -r reply || true + [[ "$reply" =~ ^[Yy]([Ee][Ss])?$ ]] +} + +# ---------------------------------------------------------------------------- +# Usage +# ---------------------------------------------------------------------------- +usage() { + cat < [options] + +${BOLD}Commands:${RESET} + ${GREEN}update${RESET} Review, commit & sync local changes. If the working tree is + clean it simply runs 'git pull'. + ${GREEN}edit${RESET} Open the Panama repo in Neovim. + ${GREEN}help${RESET} Show this help (also -h, --help). + +${BOLD}Options:${RESET} + -h, --help Show this help and exit + --version Show version and exit + +${BOLD}Examples:${RESET} + $PROGRAM update + $PROGRAM edit +EOF +} + +# ---------------------------------------------------------------------------- +# Guard: make sure we're in a git repo +# ---------------------------------------------------------------------------- +require_git_repo() { + if ! git -C "$PANAMA_DIR" rev-parse --git-dir >/dev/null 2>&1; then + err "'$PANAMA_DIR' is not a git repository." + exit 1 + fi +} + +# ---------------------------------------------------------------------------- +# Command: update +# ---------------------------------------------------------------------------- +cmd_update() { + require_git_repo + cd "$PANAMA_DIR" + + info "Panama repo: ${BOLD}${PANAMA_DIR}${RESET}" + + # Any changes in the working tree? (modified, staged, or untracked) + if [[ -z "$(git status --porcelain)" ]]; then + info "Working tree is clean — pulling latest changes." + if git pull --ff-only; then + ok "Already in sync." + else + err "git pull failed." + exit 1 + fi + return + fi + + # Show what changed + header "Changed files" + git -c color.status=always status --short + + header "Diff" + # Tracked changes (staged + unstaged) relative to the last commit. + git --no-pager -c color.diff=always diff HEAD + + # Untracked files won't appear in 'git diff', so show them as new files. + local untracked + untracked=$(git ls-files --others --exclude-standard) + if [[ -n "$untracked" ]]; then + while IFS= read -r f; do + [[ -z "$f" ]] && continue + git --no-pager -c color.diff=always diff --no-index -- /dev/null "$f" || true + done <<< "$untracked" + fi + + echo + if ! confirm "Commit these changes?"; then + warn "Aborted — no changes committed." + return + fi + + # Commit message + local msg + printf '%s?%s Commit message: ' "${CYAN}${BOLD}" "$RESET" + read -r msg || true + if [[ -z "${msg// }" ]]; then + msg="Update $(date '+%Y-%m-%d %H:%M:%S')" + warn "No message given — using: ${BOLD}${msg}${RESET}" + fi + + # Is the local branch up to date with its upstream? + info "Checking whether the repo is up to date..." + if git rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then + git fetch --quiet + local local_rev remote_rev base_rev + local_rev=$(git rev-parse @) + remote_rev=$(git rev-parse '@{u}') + base_rev=$(git merge-base @ '@{u}') + + if [[ "$local_rev" == "$remote_rev" ]]; then + ok "Repo is up to date." + elif [[ "$local_rev" == "$base_rev" ]]; then + warn "Repo is behind upstream — stashing, pulling, then re-applying." + info "Stashing local changes..." + git stash push --include-untracked -m "panama-update-$(date +%s)" >/dev/null + + if ! git pull --ff-only; then + err "git pull failed — restoring your changes." + git stash pop || true + exit 1 + fi + + info "Re-applying stashed changes..." + if ! git stash pop; then + err "Conflict while re-applying changes. Resolve it, then commit manually." + exit 1 + fi + else + warn "Local branch has diverged from upstream — committing locally only." + fi + else + warn "No upstream configured for this branch — committing locally only." + fi + + # Commit everything + info "Committing changes..." + git add -A + git commit -m "$msg" + ok "Committed: ${BOLD}${msg}${RESET}" + + echo + if confirm "Push the changes now?"; then + info "Pushing..." + if git push; then + ok "Pushed to remote." + else + err "git push failed." + exit 1 + fi + else + info "Done — changes committed locally but not pushed." + fi +} + +# ---------------------------------------------------------------------------- +# Command: edit +# ---------------------------------------------------------------------------- +cmd_edit() { + if ! command -v nvim >/dev/null 2>&1; then + err "Neovim (nvim) is not installed or not on PATH." + exit 1 + fi + info "Opening ${BOLD}${PANAMA_DIR}${RESET} in Neovim." + cd "$PANAMA_DIR" + exec nvim . +} + +# ---------------------------------------------------------------------------- +# Dispatcher +# ---------------------------------------------------------------------------- +main() { + local cmd="${1:-}" + case "$cmd" in + update) shift; cmd_update "$@" ;; + edit) shift; cmd_edit "$@" ;; + help|-h|--help|"") usage ;; + --version) printf '%s %s\n' "$PROGRAM" "$VERSION" ;; + *) + err "Unknown command: '$cmd'" + echo + usage + exit 1 + ;; + esac +} + +main "$@" diff --git a/config/bash/shell b/config/bash/shell index 2e81960..04cf7f0 100644 --- a/config/bash/shell +++ b/config/bash/shell @@ -16,6 +16,9 @@ export ANDROID_SDK_HOME="$HOME/.local/share/Android" export GOPATH="$HOME/.local/share/go" export DOTNETPATH="$HOME/.dotnet/tools" +# Podman +export DOCKER_HOST=unix:///run/user/1000/podman/podman.sock + # Set complete path export PATH="$HOME/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PANAMA_PATH/bin:$BUN_INSTALL/bin:$CARGO_PATH/bin:$PNPM_HOME/bin:$PYENV_ROOT/bin:$HOME/.rbenv/bin:/usr/lib/ccache/bin/:$GOPATH/bin:$DOTNETPATH"