# Makefile for the tp library.
#
# Usage:
#   make test                 # run all ERT test suites
#   make test-shuffled        # run the suite in a random order (SHUFFLE_SEED=n reproduces)
#   make test-m0a             # run current TP completion characterization
#   make test-m1a             # run additive transaction contract + fault gates
#   make test-v1              # run every legacy suite with v2 artifacts disabled
#   make doctest              # execute README examples against the code
#   make benchmark            # run reproducible correctness-first benchmarks
#   make compile              # byte-compile the library modules
#   make compile-all          # byte-compile modules + tests + dev scripts
#   make checkdoc             # validate source docstrings
#   make package-lint         # validate package metadata and public surface
#   make diff-check           # validate whitespace in the current diff
#   make clean                # remove compiled files
#
# WERROR=t turns byte-compile warnings into errors (used in CI).
# LOAD_EXTRA can add optional development-tool load paths such as package-lint.

EMACS ?= emacs
LOAD_EXTRA ?=
WERROR ?= nil
TEST_DIR = tests
LOADPATH = -L . -L $(TEST_DIR) -L examples $(LOAD_EXTRA)

SRC = tp-core.el tp-style.el tp-transaction.el tp-reactive.el tp-surface.el tp-layer.el tp-ops.el tp-search.el \
      tp-query.el tp-palette.el tp-builtins.el tp.el
TESTS = $(wildcard $(TEST_DIR)/*-tests.el)
V1_TESTS = $(filter-out $(TEST_DIR)/tp-transaction-tests.el,$(TESTS))
TEST_SUPPORT = $(TEST_DIR)/tp-doctest.el $(TEST_DIR)/tp-run-shuffled.el
EXAMPLES = $(wildcard examples/*.el)
DEV = $(TEST_SUPPORT) $(EXAMPLES) tp-benchmark.el

.PHONY: test test-m0a test-m1a test-v1 test-shuffled doctest benchmark compile compile-all checkdoc package-lint diff-check clean

test:
	$(EMACS) -Q --batch $(LOADPATH) -l tp.el $(patsubst %,-l %,$(TESTS)) \
	  -f ert-run-tests-batch-and-exit

test-m0a:
	$(EMACS) -Q --batch $(LOADPATH) -l tp.el \
	  -l $(TEST_DIR)/tp-binding-tests.el \
	  -l $(TEST_DIR)/tp-surface-tests.el \
	  -l $(TEST_DIR)/tp-m0a-characterization-tests.el \
	  --eval '(ert-run-tests-batch-and-exit "tp-m0a-characterization-test-\\|tp-binding-test-signal-commit-journal-rolls-back-every-write\\|tp-binding-test-rollback-preserves-primary-and-runs-all-phases\\|tp-surface-test-global-signal-update-is-multi-surface-atomic\\|tp-surface-test-full-and-scoped-precommit-stages-roll-back\\|tp-surface-test-full-and-scoped-final-accept-roll-back")'

test-m1a:
	$(EMACS) -Q --batch $(LOADPATH) -l tp.el \
	  -l $(TEST_DIR)/tp-binding-tests.el \
	  -l $(TEST_DIR)/tp-surface-tests.el \
	  -l $(TEST_DIR)/tp-m0a-characterization-tests.el \
	  -l $(TEST_DIR)/tp-transaction-tests.el \
	  --eval '(ert-run-tests-batch-and-exit "tp-transaction-test-\\|tp-m0a-characterization-test-\\|tp-binding-test-signal-commit-journal-rolls-back-every-write\\|tp-binding-test-rollback-preserves-primary-and-runs-all-phases\\|tp-surface-test-global-signal-update-is-multi-surface-atomic\\|tp-surface-test-full-and-scoped-precommit-stages-roll-back\\|tp-surface-test-full-and-scoped-final-accept-roll-back")'

test-v1:
	$(EMACS) -Q --batch $(LOADPATH) -l tp.el \
	  --eval '(setq tp--transaction-artifact-mode (quote v1))' \
	  $(patsubst %,-l %,$(V1_TESTS)) -f ert-run-tests-batch-and-exit

test-shuffled:
	$(EMACS) -Q --batch $(LOADPATH) -l tp.el $(patsubst %,-l %,$(TESTS)) \
	  -l tp-run-shuffled.el

doctest:
	$(EMACS) -Q --batch $(LOADPATH) -l tp-doctest.el

benchmark:
	$(EMACS) -Q --batch $(LOADPATH) -l tp-benchmark.el -f tp-benchmark-run

compile: clean
	$(EMACS) -Q --batch $(LOADPATH) \
	  --eval "(setq byte-compile-error-on-warn $(WERROR))" \
	  -f batch-byte-compile $(SRC)

compile-all: clean
	$(EMACS) -Q --batch $(LOADPATH) \
	  --eval "(setq byte-compile-error-on-warn $(WERROR))" \
	  -f batch-byte-compile $(SRC) $(TESTS) $(DEV)

checkdoc:
	$(EMACS) -Q --batch $(LOADPATH) --eval '(progn (require (quote cl-lib)) (require (quote checkdoc)) (let (warnings) (cl-letf (((symbol-function (quote display-warning)) (lambda (type message &optional _level _buffer-name) (push (format "%s: %s" type message) warnings)))) (dolist (directory (list "." "examples")) (dolist (file (directory-files directory t "\\.el$$")) (checkdoc-file file)))) (when warnings (dolist (warning (nreverse warnings)) (princ warning) (terpri)) (kill-emacs 1))))'

package-lint:
	$(EMACS) -Q --batch $(LOADPATH) --eval '(progn (require (quote package-lint)) (let ((package-lint-main-file (expand-file-name "tp.el")) (command-line-args-left (mapcar (lambda (file) (expand-file-name (symbol-name file))) (quote ($(SRC)))))) (package-lint-batch-and-exit)))'

diff-check:
	git diff --check

clean:
	rm -f *.elc $(TEST_DIR)/*.elc examples/*.elc
