From c91d7e04509f81d87f5ef5922dd107ed613eb198 Mon Sep 17 00:00:00 2001 From: Alexander Hess Date: Fri, 14 Aug 2026 16:37:54 +0200 Subject: [PATCH] Add `update-dotfiles` utility --- .config/shell/env | 4 +- .local/bin/update-dotfiles | 83 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+), 2 deletions(-) create mode 100755 .local/bin/update-dotfiles diff --git a/.config/shell/env b/.config/shell/env index ea9ba92..f514151 100644 --- a/.config/shell/env +++ b/.config/shell/env @@ -8,7 +8,7 @@ export XDG_CACHE_HOME="$HOME/.cache" export XDG_CONFIG_HOME="$HOME/.config" -export XDG_DATA_HOME="$HOME/.local/share" # also set in ~/.local/bin/{generate-shell-completions,install-dotfiles} +export XDG_DATA_HOME="$HOME/.local/share" # also set in ~/.local/bin/{generate-shell-completions,install-dotfiles,update-dotfiles} export XDG_STATE_HOME="$HOME/.local/state" # also set in ~/.local/bin/generate-shell-completions # Make up a XDG directory for binaries (that does not exist in the standard) @@ -17,7 +17,7 @@ export XDG_BIN_HOME="$HOME/.local/bin" # also set in ~/.local/bin/install-dotfi # Convenient names for various places in the system -export DOTFILES_DIR="$XDG_DATA_HOME/dotfiles" # also set in ~/.local/bin/install-dotfiles +export DOTFILES_DIR="$XDG_DATA_HOME/dotfiles" # also set in ~/.local/bin/{install-dotfiles,update-dotfiles} # Generic shell configs diff --git a/.local/bin/update-dotfiles b/.local/bin/update-dotfiles new file mode 100755 index 0000000..f56e46d --- /dev/null +++ b/.local/bin/update-dotfiles @@ -0,0 +1,83 @@ +#!/bin/sh + +# Replace the local `dotfiles` repository with a fresh install +# by downloading and re-running the latest `install-dotfiles` +# +# Refuses to run if there are uncommitted or unpushed changes, +# unless called with `--force` + +set -eu + + +XDG_DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}" # also set in ~/.config/shell/env + +DOTFILES_DIR="$XDG_DATA_HOME/dotfiles" # also set in ~/.config/shell/env + +INSTALLER_URL="https://code.webartifex.de/alexander/dotfiles/raw/branch/main/.local/bin/install-dotfiles" + + +force=0 +[ "${1:-}" = "--force" ] && force=1 + + +_git() { + git --git-dir="$DOTFILES_DIR" --work-tree="$HOME" "$@" +} + + +branch="main" + + +if [ -d "$DOTFILES_DIR" ]; then + + # Keep the machine on its current branch (e.g., "desktop") + branch=$(_git symbolic-ref --short HEAD) + + if [ "$force" -ne 1 ]; then + + if [ -n "$(_git status --porcelain)" ]; then + echo "" + echo "There are uncommitted changes!" >&2 + echo "" >&2 + _git --no-pager diff HEAD --stat >&2 + echo "" >&2 + echo "=> Commit and push them, or re-run with --force" >&2 + echo "" + exit 1 + fi + + if _git rev-parse --verify --quiet "origin/$branch" >/dev/null \ + && [ -n "$(_git log --oneline "origin/$branch..$branch")" ]; then + echo "" + echo "There are unpushed commits!" >&2 + echo "" >&2 + _git --no-pager log --oneline "origin/$branch..$branch" >&2 + echo "" >&2 + echo "=> Push them, or re-run with --force" >&2 + echo "" + exit 1 + fi + + fi + +fi + + +installer=$(mktemp) +trap 'rm -f "$installer"' EXIT + + +if command -v curl >/dev/null 2>&1; then + curl -fsSL "$INSTALLER_URL" -o "$installer" +elif command -v wget >/dev/null 2>&1; then + wget -q "$INSTALLER_URL" -O "$installer" +else + echo "" + echo "Neither curl nor wget are installed!" >&2 + echo "=> Install one of them" >&2 + echo "" + exit 1 +fi + + +DOTFILES_BRANCH="$branch" FORCE_INSTALL=1 sh "$installer"