.POSIX: .SUFFIXES: COLOR_BLUE:=\033[36m COLOR_AUTO:=\033[0m SRC=.config/aliasrc .config/inputrc .gitconfig .*profile TGT=$(addprefix $$HOME/, $(SRC)) .PHONY: help ## Show this help menu. help: @printf 'make \n\nsubcommand:\n' @awk -F '(: | ## )' '/^\.PHONY:.*?## .*$$/ {\ printf("\t$(COLOR_BLUE)%s\t\t$(COLOR_AUTO)%s\n",$$2, $$3)\ }' $(MAKEFILE_LIST) .PHONY: installcheck ## Check if the dotfiles are properly linked to home. installcheck: # Assert link sources match link destinations. for link in $(SRC); do \ dst_link=$$(stat -c "%N" ~/"$$link" | cut -d ' ' -f 3); \ src_link="$$PWD/$$link"; \ if [ ! "$$dst_link" = \'"$$src_link"\' ]; then \ printf 'Destination link matches not the source link!\n'; \ fi; \ done # RFE: Use the single suffix inference rule to enhance iteration semantics # to actual Makefile semantics. This could probably be done by suffixing source # links with .ln. .PHONY: install ## Actually symlink the dotfiles to home. install: $(SRC) mkdir -p $(dir $(TGT)) for file in $(SRC); do $(RM) -r ~/$$file; ln -s $$PWD/$$file ~/$$file; done .PHONY: uninstallcheck ## Check if dotfiles' symlinks were properly removed. uninstallcheck: # Assert destination links were removed. for link in $(TGT); do \ [ ! -e ~/"$$link" ] || \ printf '%s%s\n' "$$link" "survived teardown!"; \ done .PHONY: uninstall ## Remove the symlinks to dotfiles. uninstall: $(RM) -r $(TGT) for file in $(TGT); do if [ -e "$$file~" ]; then mv "$$file~" "$$file"; fi; done .PHONY: clean ## Purge cruft (not the dotfiles payload). clean: -docker rm check_dotfiles -docker rmi dotfiles # ---------------------------------------------------------------------------- # Make is not really a good system for this. # It works with files, but this works with containers. # Write a deployment for the test container? .PHONY: all ## lint -> build -> check all: lint build check .PHONY: lint ## Lint the source repository. lint: docker run --rm \ -u "$(shell id -u):$(shell id -g)" \ -v "$(shell pwd):/mnt" \ -w /mnt \ mvdan/shfmt:latest -d -sr -i 4 .config/aliasrc .*profile docker run --rm \ -u "$(shell id -u):$(shell id -g)" \ -v "$(shell pwd):/mnt" \ -w /mnt \ koalaman/shellcheck -x .config/aliasrc .*profile .PHONY: build ## Build a container to system-test the dotfiles. build: docker build --target test --tag dotfiles . .PHONY: check ## Check if (un)install works in the test container. check: build docker run --name="check_dotfiles" --tty -d --entrypoint sh dotfiles docker exec check_dotfiles make install docker exec check_dotfiles make installcheck docker exec check_dotfiles make uninstall docker exec check_dotfiles make uninstallcheck docker stop check_dotfiles # ----------------------------------------------------------------------------