diff --git a/modules/user/dotfiles.sh b/modules/user/dotfiles.sh new file mode 100755 index 0000000..19a5324 --- /dev/null +++ b/modules/user/dotfiles.sh @@ -0,0 +1,56 @@ +#!/bin/bash +set -uo pipefail + +HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +# shellcheck source=../../lib/common.sh +source "$HERE/../../lib/common.sh" + +if is_debug; then set +e; else set -e; fi + +DOTFILES_REPO="${DOTFILES_REPO:-https://git.ku-it.org/yuri/fedora-dots.git}" +CFG_DIR="$HOME/.cfg.git" + +step "Personal dotfiles: fedora-dots" +rule + +if [[ ! -d "$HOME/.config" ]]; then + mkdir -p "$HOME/.config" +fi + +if [[ -d "$CFG_DIR" ]]; then + ok "Dotfiles already set up ($CFG_DIR exists). Skipping." + exit 0 +fi + +# A bare repo is the storage; $HOME is the work tree. Checkout happens through +# the alias form, never a plain `git checkout` inside $HOME. +info "Cloning dotfiles (bare) into $CFG_DIR..." +# --bare is what makes ~/.cfg.git the storage; the plain clone YuKu first ran +# created a working copy instead and broke the alias (proven the hard way). +git clone --quiet --bare "$DOTFILES_REPO" "$CFG_DIR" + +cfg() { + git --git-dir="$CFG_DIR" --work-tree="$HOME" "$@" +} + +# Empty repo (no commits yet): nothing to check out, but leave everything +# configured so the first `cfg add` on this machine just works. +if ! git --git-dir="$CFG_DIR" rev-parse --verify -q HEAD >/dev/null; then + warn "Dotfiles repo has no commits yet — checkout skipped." + warn "Add folders on your main machine first; here you can start fresh." + cfg config status.showUntrackedFiles no + ok "cfg alias ready: git --git-dir=$CFG_DIR --work-tree=$HOME" + exit 0 +fi + +info "Checking dotfiles out into \$HOME..." +# -f on purpose: a fresh machine HAS stock files (e.g. .bashrc); the repo's +# versions win on first setup. Untracked files are never touched. +cfg checkout -f +cfg config status.showUntrackedFiles no + +ok "Dotfiles checked out. Tracked paths:" +git --git-dir="$CFG_DIR" ls-tree -r --name-only HEAD | cut -d/ -f1-2 | sort -u | sed 's/^/ /' + +info "Suggested shell alias for managing them:" +info " alias cfg='git --git-dir=$CFG_DIR --work-tree=\$HOME'" diff --git a/setup.sh b/setup.sh index 4250242..bf8250a 100755 --- a/setup.sh +++ b/setup.sh @@ -21,6 +21,7 @@ DE="" TWM="" SELINUX_OPT="" SNAPPER_OPT="" +DOTFILES_OPT="" usage() { cat <<'EOF' @@ -36,6 +37,7 @@ Options: --twm=NAME chadwm | hyprland | mango | niri | none --selinux=X keep | disabled (asked, default keep) --snapper=X yes | no (asked when / is btrfs, default yes) + --dotfiles=X yes | no (clone personal dotfiles, default no) -y, --yes never prompt (requires --de and --twm) -d, --debug pause after each section instead of aborting on error -h, --help show this help @@ -59,6 +61,7 @@ for arg in "$@"; do --de=*) DE="${arg#*=}" ;; --selinux=*) SELINUX_OPT="${arg#*=}" ;; --snapper=*) SNAPPER_OPT="${arg#*=}" ;; + --dotfiles=*) DOTFILES_OPT="${arg#*=}" ;; --twm=*) TWM="${arg#*=}" ;; -h|--help) usage; exit 0 ;; *) @@ -256,9 +259,23 @@ case "${SELINUX_OPT:-}" in esac case "${SNAPPER_OPT:-}" in yes) BTRFS_SNAPPER=true ;; - no|"") : ;; + no) BTRFS_SNAPPER=false ;; # explicit flag beats the interactive default + ""|keep) : ;; *) err "Unknown --snapper value: '$SNAPPER_OPT' (yes|no)"; exit 2 ;; esac + +DOTFILES=false +if [[ -z "$DOTFILES_OPT" ]]; then + printf "\n" + choice=$(ask_yes_no "Clone personal dotfiles (fedora-dots) into \$HOME?" "no") + [[ "$choice" == "yes" ]] && DOTFILES=true +else + case "$DOTFILES_OPT" in + yes) DOTFILES=true ;; + no) : ;; + *) err "Unknown --dotfiles value: '$DOTFILES_OPT' (yes|no)"; exit 2 ;; + esac +fi pause_if_debug #------------------------------------------ @@ -361,6 +378,11 @@ if [[ "$BTRFS_SNAPPER" == "true" ]]; then pause_if_debug fi +if [[ "$DOTFILES" == "true" ]]; then + run_module "$SCRIPT_DIR/modules/user/dotfiles.sh" + pause_if_debug +fi + if [[ "$DE" != "none" ]]; then run_module "$SCRIPT_DIR/modules/de/${DE}.sh" pause_if_debug @@ -378,7 +400,9 @@ step "7 Summary" rule ok "DE: $DE" ok "TWM: $TWM" -ok "SELinux: $([[ "$SELINUX_DISABLED" == "true" ]] && echo disabled || echo keeping)"; ok "Btrfs snapshots: $([[ "$BTRFS_SNAPPER" == "true" ]] && echo yes || echo skipped)" +ok "SELinux: $([[ "$SELINUX_DISABLED" == "true" ]] && echo disabled || echo keeping)" +ok "Btrfs snapshots: $([[ "$BTRFS_SNAPPER" == "true" ]] && echo yes || echo skipped)" +ok "Dotfiles: $([[ "$DOTFILES" == "true" ]] && echo clone || echo no)" DM=$(detect_display_manager) ok "Display manager: ${DM:-none}"