# Makefile for archsetup dotfiles # GNU Stow operations for managing dotfiles STOW := stow --target=$(HOME) --no-folding DOTFILES := $(shell pwd)/dotfiles # Extract DE from command line (e.g., 'make stow dwm' -> DE=dwm) DE := $(filter dwm hyprland,$(MAKECMDGOALS)) # Extract DEST from command line for import (e.g., 'make import common' -> DEST=common) DEST := $(filter common dwm hyprland,$(MAKECMDGOALS)) .PHONY: help stow restow reset unstow import common dwm hyprland # Default target - show help help: @echo "Dotfiles Management (GNU Stow)" @echo "" @echo "Usage: make " @echo "" @echo "Desktop Environments / Destinations:" @echo " common Shared configs (all setups)" @echo " dwm X11/DWM specific" @echo " hyprland Wayland/Hyprland specific" @echo "" @echo "Targets:" @echo " stow Create symlinks (fresh install) - requires DE" @echo " restow Refresh symlinks (unlink + relink) - requires DE" @echo " reset Resolve conflicts, keep repo version - requires DE" @echo " unstow Remove all symlinks - requires DE" @echo " import Import new app configs into repo (fzf) - requires dest" @echo "" @echo "Examples:" @echo " make stow dwm # Fresh DWM install (common + dwm)" @echo " make stow hyprland # Fresh Hyprland install (common + hyprland)" @echo " make restow dwm # Refresh DWM links after git pull" @echo " make reset hyprland # Resolve conflicts, keep repo version" @echo " make import common # Import configs to common/" @echo " make import hyprland # Import configs to hyprland/" @echo "" # Prevent 'common', 'dwm' and 'hyprland' from being treated as file targets common dwm hyprland: @: # Validate DE was provided (for stow/restow/reset/unstow) check-de: ifeq ($(DE),) @echo "Error: Desktop environment required (dwm or hyprland)." @echo "" @$(MAKE) --no-print-directory help @exit 1 endif # Validate DEST was provided (for import) check-dest: ifeq ($(DEST),) @echo "Error: Destination required (common, dwm, or hyprland)." @echo "" @$(MAKE) --no-print-directory help @exit 1 endif # Stow - create symlinks stow: check-de @echo "Stowing common + $(DE)..." @cd $(DOTFILES) && $(STOW) common @cd $(DOTFILES) && $(STOW) $(DE) @echo "Done." # Restow - refresh symlinks (unlink + relink) restow: check-de @echo "Restowing common + $(DE)..." @cd $(DOTFILES) && $(STOW) --restow common @cd $(DOTFILES) && $(STOW) --restow $(DE) @echo "Done." # Reset - resolve conflicts by adopting then reverting to repo version reset: check-de @echo "Resetting common + $(DE)..." @cd $(DOTFILES) && $(STOW) --adopt common @cd $(DOTFILES) && $(STOW) --adopt $(DE) @echo "Reverting adopted files to repo version..." @git checkout -- dotfiles/ @echo "Done. Symlinks created, repo unchanged." # Unstow - remove symlinks unstow: check-de @echo "Unstowing common + $(DE)..." @cd $(DOTFILES) && $(STOW) --delete common @cd $(DOTFILES) && $(STOW) --delete $(DE) @echo "Done." # Import - select and import new app configs into repo import: check-dest @echo "Select directories to import (Tab to multi-select, Enter to confirm):" @echo "" @selections=$$({ \ find $(HOME) -maxdepth 1 -mindepth 1 -name '.*' -type d 2>/dev/null | grep -v '\.cache\|\.local\|\.config' | sed 's|$(HOME)/||'; \ find $(HOME)/.config -maxdepth 1 -mindepth 1 -type d 2>/dev/null | sed 's|$(HOME)/||'; \ find $(HOME)/.local -maxdepth 2 -mindepth 1 -type d 2>/dev/null | sed 's|$(HOME)/||'; \ } | sort -u | fzf --multi --prompt="Import to $(DEST)> " --header="Select configs to import into dotfiles/$(DEST)/"); \ if [ -z "$$selections" ]; then \ echo "No selections made."; \ exit 0; \ fi; \ echo ""; \ for dir in $$selections; do \ src="$(HOME)/$$dir"; \ dest="$(DOTFILES)/$(DEST)/$$dir"; \ if [ -d "$$dest" ]; then \ echo "Skipping $$dir (already exists in dotfiles/$(DEST))"; \ else \ echo "Importing $$dir to $(DEST)..."; \ mkdir -p "$$(dirname $$dest)"; \ mv "$$src" "$$dest"; \ fi; \ done; \ echo ""; \ echo "Restowing $(DEST)..."; \ cd $(DOTFILES) && $(STOW) --restow $(DEST); \ echo ""; \ echo "Done. Don't forget to: git add -A && git commit"