summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile73
1 files changed, 73 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..2efc68e
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,73 @@
+SHELL := /bin/bash -eufo pipefail
+PREFIX ?= $(HOME)
+FIND ?= gfind
+
+.PHONY: all
+all: clean merge stow after_stow
+
+.PHONY: after_stow
+after_stow:
+ ln -nfs "$(PREFIX)/.nvim" "$(PREFIX)/.config/nvim"
+ ln -nfs "$(PREFIX)/.zls.json" "$(PREFIX)/Library/Application Support/zls.json"
+
+.PHONY: stow
+stow:
+ @# stow doesn't support __stowing?__ directories with symlinks, see:
+ @# https://github.com/aspiers/stow/issues/51
+ @# what i do here is a stow-like glue
+ @# - loop through all top level directories in merged
+ @# - for each file or directory in the top level
+ @# - create a symlink in $HOME pointing to merged
+ @# this has one important limitation: it doesn't support shared
+ @# nested directories as stow does. for example, if you have a directory
+ @# like: merged/nvim/.config/nvim, $HOME/.config would end up as a link,
+ @# which is not ideal since it contains other configs too!
+ @#
+ @# the solution is to never use shared directories and setup links after
+ @# this target with the after_stow target.
+ $(FIND) ./merged -mindepth 1 -maxdepth 1 -type d -print0 |\
+ xargs -0 -S 600 -I{} $(SHELL) -c '\
+ export package={}; \
+ echo "stowing - $${package#./merged/}"; \
+ $(FIND) "$${package}" -mindepth 1 -maxdepth 1 -print0 |\
+ xargs -0 -I{} $(SHELL) -c '\''\
+ target={}; \
+ echo "linking - $${target#./merged/}"; \
+ ln -nfs "$(PWD)/$${target#./}" \
+ "$(PREFIX)/$${target#.\/merged\/$${package#./merged/}\/}"; \
+ '\''; \
+ '
+
+.PHONY: merge
+merge: merge_check_dups
+ @# create directory structure
+ rsync -a --include '*/' --exclude '*' "private/" "merged"
+ rsync -a --include '*/' --exclude '*' "public/" "merged"
+ rm -rf merged/.git
+ @# link files to their destination
+ $(FIND) ./public -not \( -path ./public/.git -prune \) -type f -print0 |\
+ xargs -0 -S 600 -I '{}' $(SHELL) -c '\
+ file={}; \
+ ln -s "$$(realpath $$file)" "./merged/$${file#./public/}"; \
+ '
+ $(FIND) ./private -not \( -path ./private/.git -prune \) -type f -print0 |\
+ xargs -0 -S 600 -I '{}' $(SHELL) -c '\
+ file={}; \
+ ln -s "$$(realpath $$file)" "./merged/$${file#./private/}"; \
+ '
+
+.PHONY: merge_check_dups
+merge_check_dups:
+ DUPES=$$({ \
+ $(FIND) ./private -type f -printf '%P\n'; \
+ $(FIND) ./public -type f -printf '%P\n'; \
+ } | sort | uniq -d); \
+ if [ "$$(echo -n "$$DUPES" | wc -c)" -gt 0 ]; then \
+ echo "ERROR: Duplicate files found in private and public"; \
+ echo "$$DUPES"; \
+ exit 1; \
+ fi
+
+.PHONY: clean
+clean:
+ rm -rf merged