# DuckBrain development harness (branch-only tooling; never published to master).
#
# Workflow:
#   make test     run the unit test suite (installs dev dependencies first if needed)
#   make publish  sync develop -> master (human-only; git push origin master afterwards)

SHELL := /bin/bash

.PHONY: test publish

PHPUNIT := vendor/bin/phpunit

# --- publish configuration -------------------------------------------------
WHITELIST     := src config.php index.php autoload.php .htaccess readme.org
BLACKLIST     :=
DEVELOP_BRANCH  := develop
DEVELOP_REF     := refs/heads/$(DEVELOP_BRANCH)
MASTER_BRANCH   := master
MASTER_REF      := refs/heads/$(MASTER_BRANCH)
LAST_SYNC_TAG  := last-sync
MSG            ?= sync: $(shell date +%Y-%m-%d)

test: $(PHPUNIT)
	./$(PHPUNIT)

$(PHPUNIT): composer.json composer.lock
	composer install --no-interaction

publish:
	@if [ "$$(git branch --show-current)" != "$(DEVELOP_BRANCH)" ]; then \
		echo "ABORT: publish must be invoked from $(DEVELOP_BRANCH) (current: '$$(git branch --show-current)')"; \
		exit 1; \
	fi
	@if [ -n "$$(git status --porcelain)" ]; then \
		echo "ABORT: working tree is dirty; commit your changes on $(DEVELOP_BRANCH) before publishing:"; \
		git status --short; \
		exit 1; \
	fi
	git worktree remove --force .publish/master 2>/dev/null || true
	git worktree add --quiet .publish/master $(MASTER_BRANCH)
	@test "$$(git -C .publish/master symbolic-ref HEAD)" = "$(MASTER_REF)" || { \
		echo "ABORT: publish worktree HEAD is not attached to $(MASTER_REF)"; \
		git worktree remove --force .publish/master; exit 1; }
	@for w in $(WHITELIST); do git -C .publish/master rm -rf --ignore-unmatch --quiet -- $$w; done
	git -C .publish/master checkout $(DEVELOP_REF) -- $(WHITELIST)
	@for b in $(BLACKLIST); do git -C .publish/master rm -rf --ignore-unmatch --quiet -- $$b; done
	git -C .publish/master diff --quiet $(DEVELOP_REF) -- $(WHITELIST)
	@if git -C .publish/master diff --cached --quiet; then \
		echo "nothing to publish: master already mirrors $(DEVELOP_BRANCH)"; \
	else \
		set -e; \
		if git rev-parse -q --verify tags/$(LAST_SYNC_TAG) >/dev/null; then \
			RANGE=$(LAST_SYNC_TAG)..$(DEVELOP_REF); \
		else \
			echo "note: no $(LAST_SYNC_TAG) tag yet; summarizing full $(DEVELOP_BRANCH) history"; \
			RANGE=$(DEVELOP_REF); \
		fi; \
		BODY=$$(git log $$RANGE --oneline -- $(WHITELIST)); \
		{ printf '%s\n' "$(MSG)"; printf '\n'; printf '%s\n' "$$BODY"; } > .publish/msg.txt; \
		git -C .publish/master commit --quiet -F "$$(pwd)/.publish/msg.txt"; \
		echo "publish commit created; review/edit it (before pushing) with your git tool of choice"; \
	fi
	git tag -f $(LAST_SYNC_TAG) $(DEVELOP_REF) >/dev/null
	git worktree remove .publish/master
	@echo "root entries left behind in $(DEVELOP_BRANCH) (add to WHITELIST if they belong to the artifact):"; \
	comm -23 <(git ls-tree --name-only $(DEVELOP_REF) | sort) \
	         <(for x in $(WHITELIST) $(BLACKLIST); do echo $$x; done | sort) | sed 's/^/  - /'
