aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xarchsetup101
-rw-r--r--archsetup.conf.example16
2 files changed, 84 insertions, 33 deletions
diff --git a/archsetup b/archsetup
index 6f828f5..156af27 100755
--- a/archsetup
+++ b/archsetup
@@ -118,6 +118,9 @@ load_config() {
[[ -n "$SLOCK_REPO" ]] && slock_repo="$SLOCK_REPO"
[[ -n "$DOTEMACS_REPO" ]] && dotemacs_repo="$DOTEMACS_REPO"
[[ -n "$ARCHSETUP_REPO" ]] && archsetup_repo="$ARCHSETUP_REPO"
+ [[ -n "$DOTFILES_REPO" ]] && dotfiles_repo="$DOTFILES_REPO"
+ [[ -n "$DOTFILES_BRANCH" ]] && dotfiles_branch="$DOTFILES_BRANCH"
+ [[ -n "$DOTFILES_DIR" ]] && dotfiles_dir="$DOTFILES_DIR"
[[ -n "$LOCALE" ]] && locale="$LOCALE"
[[ -n "$DESKTOP_ENV" ]] && desktop_env="$DESKTOP_ENV"
}
@@ -180,7 +183,7 @@ validate_config() {
# leading dash, which git would parse as an option -- plus whitespace and
# control characters.
local repo
- for repo in "$dwm_repo" "$dmenu_repo" "$st_repo" "$slock_repo" "$dotemacs_repo" "$archsetup_repo"; do
+ for repo in "$dwm_repo" "$dmenu_repo" "$st_repo" "$slock_repo" "$dotemacs_repo" "$archsetup_repo" "$dotfiles_repo"; do
[[ -z "$repo" ]] && continue
if [[ "$repo" == -* || "$repo" =~ [[:space:][:cntrl:]] ]]; then
echo "ERROR: Repository spec must not start with '-' or contain whitespace/control characters: '$repo'" >&2
@@ -203,9 +206,6 @@ password="${password:-}" # prompted if not set
locale="${locale:-}" # set via prompt if not configured
desktop_env="${desktop_env:-hyprland}" # options: dwm, hyprland, none
-archsetup_dir="$(dirname "$(readlink -f "$0")")"
-dotfiles_dir="$archsetup_dir/dotfiles"
-
# Git repositories for suckless tools and dotfiles
# Override these in config file to use your own forks
dwm_repo="${dwm_repo:-https://git.cjennings.net/dwm.git}"
@@ -215,6 +215,12 @@ slock_repo="${slock_repo:-https://git.cjennings.net/slock.git}"
dotemacs_repo="${dotemacs_repo:-https://git.cjennings.net/dotemacs.git}"
archsetup_repo="${archsetup_repo:-https://git.cjennings.net/archsetup.git}"
+# Dotfiles live in their own repo, cloned to $dotfiles_dir and stowed at install
+# time. $dotfiles_dir defaults to the user's ~/.dotfiles, set once $username is
+# known (see user_customizations).
+dotfiles_repo="${dotfiles_repo:-https://git.cjennings.net/dotfiles.git}"
+dotfiles_branch="${dotfiles_branch:-main}"
+
logfile="/var/log/archsetup-$(date +'%Y-%m-%d-%H-%M-%S').log"
source_dir="" # set in preflight_checks after username is known
packages_before="/var/log/archsetup-preexisting-package-list.txt"
@@ -954,29 +960,54 @@ user_customizations() {
chown -R "$username": "/home/$username/code") \
>> "$logfile" 2>&1 || error_warn "$action" "$?"
- # Update dotfiles_dir to point to user-accessible location
- dotfiles_dir="$user_archsetup_dir/dotfiles"
-
- action="linking dotfiles into place" && display "task" "$action"
- (cd "$dotfiles_dir" && stow --target="/home/$username" --no-folding --adopt common \
- >> "$logfile" 2>&1 ) || error_warn "$action" "$?"
+ # Clone the dotfiles repo (separate from archsetup) and stow from it.
+ # Defaults to ~/.dotfiles; override via DOTFILES_DIR.
+ dotfiles_dir="${dotfiles_dir:-/home/$username/.dotfiles}"
+ action="cloning dotfiles repo" && display "task" "$action"
+ # Clone as root, then hand the tree to the user. useradd -m skips the home-dir
+ # chown when /home/$username already exists (pre-seeded images, re-runs), which
+ # leaves /home/$username root-owned — so a clone running as the user fails with
+ # "Permission denied" creating ~/.dotfiles. Cloning as root sidesteps that, and
+ # chown -R gives the user the working tree. Mirrors the archsetup clone above.
+ (git clone --depth 1 --branch "$dotfiles_branch" "$dotfiles_repo" "$dotfiles_dir" \
+ && chown -R "$username": "$dotfiles_dir") >> "$logfile" 2>&1 || error_warn "$action" "$?"
+
+ # Q5: the --adopt/restore conflict handling below needs a real git checkout.
+ # Refuse to continue if the clone didn't produce one (bad URL, network, a
+ # tarball drop) rather than silently skipping the restore step.
+ [[ -d "$dotfiles_dir/.git" ]] || error_fatal "dotfiles dir is not a git checkout: $dotfiles_dir" 1
+
+ # root runs stow/restore against the user-owned clone; mark it safe.
+ git config --global --add safe.directory "$dotfiles_dir" >> "$logfile" 2>&1 || true
+
+ # Stow the universal layer plus the per-environment layer. Headless installs
+ # (none) get the standalone minimal/ tree instead of common/.
+ case "$desktop_env" in
+ dwm|hyprland)
+ action="linking common dotfiles" && display "task" "$action"
+ (cd "$dotfiles_dir" && stow --target="/home/$username" --no-folding --adopt common \
+ >> "$logfile" 2>&1) || error_warn "$action" "$?"
+ action="linking $desktop_env dotfiles" && display "task" "$action"
+ (cd "$dotfiles_dir" && stow --target="/home/$username" --no-folding --adopt "$desktop_env" \
+ >> "$logfile" 2>&1) || error_warn "$action" "$?"
+ ;;
+ none)
+ action="linking minimal dotfiles" && display "task" "$action"
+ (cd "$dotfiles_dir" && stow --target="/home/$username" --no-folding --adopt minimal \
+ >> "$logfile" 2>&1) || error_warn "$action" "$?"
+ ;;
+ esac
- # Stow desktop-environment-specific dotfiles
- if [[ "$desktop_env" == "hyprland" ]]; then
- action="linking hyprland dotfiles" && display "task" "$action"
- (cd "$dotfiles_dir" && stow --target="/home/$username" --no-folding --adopt hyprland \
- >> "$logfile" 2>&1 ) || error_warn "$action" "$?"
-
- # Remove battery module from waybar config on desktops (no battery)
- if ! ls /sys/class/power_supply/BAT* &>/dev/null; then
- action="removing waybar battery module (no battery detected)" && display "task" "$action"
- waybar_config="/home/$username/.config/waybar/config"
- # Remove "battery" from sysmonitor modules array and fix trailing comma
- sed -i '/"battery"$/d' "$waybar_config"
- sed -i 's/"custom\/disk",/"custom\/disk"/' "$waybar_config"
- # Remove the battery config block
- sed -i '/"battery": {/,/^ },$/d' "$waybar_config"
- fi
+ # Remove battery module from waybar config on desktops with no battery
+ # (hyprland only — waybar isn't part of the dwm or minimal trees).
+ if [[ "$desktop_env" == "hyprland" ]] && ! ls /sys/class/power_supply/BAT* &>/dev/null; then
+ action="removing waybar battery module (no battery detected)" && display "task" "$action"
+ waybar_config="/home/$username/.config/waybar/config"
+ # Remove "battery" from sysmonitor modules array and fix trailing comma
+ sed -i '/"battery"$/d' "$waybar_config"
+ sed -i 's/"custom\/disk",/"custom\/disk"/' "$waybar_config"
+ # Remove the battery config block
+ sed -i '/"battery": {/,/^ },$/d' "$waybar_config"
fi
# install fontconfig before refreshing cache (provides fc-cache)
@@ -1022,13 +1053,17 @@ EOF
dconf update
) >> "$logfile" 2>&1 || error_warn "$action" "$?"
- action="marking dotfile dir as safe.directory" && display "task" "$action"
- if git config --global --add safe.directory "$user_archsetup_dir" >> "$logfile" 2>&1; then
- action="restoring dotfile versions" && display "task" "$action"
- git -C "$dotfiles_dir" restore . >> "$logfile" 2>&1 || error_warn "$action" "$?"
- else
- error_warn "marking dotfile dir as safe.directory" "$?"
- fi
+ action="marking archsetup dir as safe.directory" && display "task" "$action"
+ git config --global --add safe.directory "$user_archsetup_dir" >> "$logfile" 2>&1 \
+ || error_warn "$action" "$?"
+
+ # Revert what stow --adopt pulled into the dotfiles working tree, so the
+ # symlinks resolve to the repo's versions rather than any pre-existing files
+ # (e.g. the /etc/skel .bashrc/.bash_profile a fresh user starts with). Runs
+ # for every desktop_env, including none — minimal/ ships those skel-colliding
+ # files too, so its --adopt needs the same restore.
+ action="restoring dotfile versions" && display "task" "$action"
+ git -C "$dotfiles_dir" restore . >> "$logfile" 2>&1 || error_warn "$action" "$?"
action="creating common directories" && display "task" "$action"
# Create default directories and grant permissions
diff --git a/archsetup.conf.example b/archsetup.conf.example
index fe8cd26..f866134 100644
--- a/archsetup.conf.example
+++ b/archsetup.conf.example
@@ -55,3 +55,19 @@
#SLOCK_REPO=https://github.com/yourusername/slock.git
#DOTEMACS_REPO=https://github.com/yourusername/dotemacs.git
#ARCHSETUP_REPO=https://github.com/yourusername/archsetup.git
+
+#############################
+# Dotfiles
+#############################
+# Dotfiles live in their own repo, cloned to DOTFILES_DIR and stowed at install
+# time. The repo must contain a common/ subdir plus dwm/, hyprland/, and/or
+# minimal/ subdirs that stow cleanly to ~. DESKTOP_ENV picks which:
+# dwm -> common/ + dwm/
+# hyprland -> common/ + hyprland/
+# none -> minimal/ only
+#DOTFILES_REPO=https://git.cjennings.net/dotfiles.git
+#DOTFILES_BRANCH=main
+# DOTFILES_DIR: leave unset to use the target user's ~/.dotfiles (recommended).
+# If you set it, use a literal absolute path under the user's home — this file is
+# sourced as root, so $HOME here is /root, not the user's home.
+#DOTFILES_DIR=/home/youruser/.dotfiles