diff options
Diffstat (limited to 'Makefile')
| -rw-r--r-- | Makefile | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..621cf95 --- /dev/null +++ b/Makefile @@ -0,0 +1,156 @@ +# Makefile for pearl.el +# Test targets delegate to tests/Makefile. +# setup / compile / coverage operate at project root. +# Run 'make help' for available commands. + +EASK ?= eask +EMACS_BATCH = $(EASK) emacs --batch +# Coverage / test loops need default-directory = tests/ so test files' +# relative paths (../pearl.el, sibling test files) resolve as they do +# under tests/Makefile. +EMACS_BATCH_TESTS = $(EASK) emacs --batch --eval '(cd "tests/")' + +TEST_DIR = tests +SOURCE_FILE = pearl.el + +# Coverage configuration +COVERAGE_DIR = .coverage +COVERAGE_FILE = $(COVERAGE_DIR)/simplecov.json + +# Test-file list used by the coverage loop, mirroring tests/Makefile. +# Coverage runs every test file so the report represents the full suite. +ALL_TESTS = $(filter-out $(TEST_DIR)/test-bootstrap.el, \ + $(wildcard $(TEST_DIR)/test-*.el)) + +# Include local overrides if present (per-machine knobs, not committed) +-include makefile-local + +.PHONY: help test test-all test-unit test-integration test-file test-one test-name \ + count list validate lint check-deps clean \ + setup compile coverage coverage-clean + +help: + @$(MAKE) -C $(TEST_DIR) help + +# Test target delegations +test: + @$(MAKE) -C $(TEST_DIR) test + +test-all: + @$(MAKE) -C $(TEST_DIR) test-all + +test-unit: + @$(MAKE) -C $(TEST_DIR) test-unit + +test-integration: + @$(MAKE) -C $(TEST_DIR) test-integration + +test-file: + @$(MAKE) -C $(TEST_DIR) test-file FILE="$(FILE)" + +test-one: + @$(MAKE) -C $(TEST_DIR) test-one TEST="$(TEST)" + +test-name: + @$(MAKE) -C $(TEST_DIR) test-name TEST="$(TEST)" + +count: + @$(MAKE) -C $(TEST_DIR) count + +list: + @$(MAKE) -C $(TEST_DIR) list + +validate: + @$(MAKE) -C $(TEST_DIR) validate + +lint: + @$(MAKE) -C $(TEST_DIR) lint + +check-deps: + @$(MAKE) -C $(TEST_DIR) check-deps + +clean: + @$(MAKE) -C $(TEST_DIR) clean + @rm -rf $(COVERAGE_DIR) + +# +# Project-root targets — operate on pearl.el at root level +# + +# Install runtime + development dependencies via eask +setup: + @if ! command -v $(EASK) >/dev/null 2>&1; then \ + echo "[✗] eask not found on PATH"; \ + echo " Install: npm install -g @emacs-eask/cli"; \ + echo " Or: https://emacs-eask.github.io/Getting-Started/Install-Eask/"; \ + exit 1; \ + fi + @echo "[i] Installing dependencies via eask..." + @$(EASK) install-deps --dev + @echo "[i] Verifying runtime deps landed in the sandbox..." + @# eask skips a dep when an identical version sits in its GLOBAL store + @# (~/.eask/<ver>/elpa/), but `eask emacs' only activates the project + @# sandbox — so a globally-present dep is "installed" yet unloadable here. + @# Install any such skipped runtime dep straight into the sandbox. + @$(EASK) emacs --batch --eval "(progn \ + (package-initialize) \ + (dolist (pkg '(request dash s)) \ + (unless (package-installed-p pkg) \ + (message \" installing %s into sandbox...\" pkg) \ + (unless package-archive-contents (package-refresh-contents)) \ + (package-install pkg))))" + @echo "[✓] Dependencies installed in .eask/" + +# Byte-compile pearl.el — surfaces free-variable / unused-let / +# suspicious-call warnings that checkdoc and elisp-lint don't catch. +# byte-compile-error-on-warn is t so any warning fails the build. +compile: + @echo "[i] Byte-compiling $(SOURCE_FILE)..." + @$(EMACS_BATCH) \ + --eval "(progn \ + (setq byte-compile-error-on-warn t) \ + (batch-byte-compile))" $(SOURCE_FILE) + @echo "[✓] Compilation complete" + +# +# Coverage (undercover + simplecov JSON) +# +# Each test file runs in its own Emacs process (matching test-unit); +# tests/run-coverage-file.el instruments pearl.el before the source +# is loaded, and undercover merges per-file results into a single simplecov +# JSON. + +coverage: coverage-clean $(COVERAGE_DIR) + @echo "[i] Cleaning .elc files so undercover can instrument source..." + @find . -name "*.elc" -delete + @echo "[i] Running coverage across $(words $(ALL_TESTS)) test file(s)..." + @echo " (slower than 'make test' — each file runs in its own Emacs)" + @failed=0; \ + for test in $(ALL_TESTS); do \ + echo " Coverage: $$test..."; \ + testfile=$$(basename $$test); \ + $(EMACS_BATCH_TESTS) \ + -l ert \ + -l run-coverage-file.el \ + -l ../$(SOURCE_FILE) \ + -l $$testfile \ + --eval "(ert-run-tests-batch-and-exit t)" || failed=$$((failed + 1)); \ + done; \ + if [ $$failed -gt 0 ]; then \ + echo "[!] $$failed test file(s) failed during coverage run"; \ + exit 1; \ + fi + @coverage_file="$${COVERAGE_FILE_ACTUAL:-$(COVERAGE_FILE)}"; \ + [ -n "$$CI" ] && coverage_file="$(COVERAGE_DIR)/coveralls.json"; \ + if [ -f "$$coverage_file" ]; then \ + echo "[✓] Coverage report: $$coverage_file ($$(du -h $$coverage_file | cut -f1))"; \ + else \ + echo "[!] No coverage file produced; check that undercover is installed"; \ + exit 1; \ + fi + +coverage-clean: + @rm -f $(COVERAGE_FILE) + +$(COVERAGE_DIR): + @mkdir -p $(COVERAGE_DIR) |
