aboutsummaryrefslogtreecommitdiff
path: root/Makefile
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-05-05 03:28:49 -0500
committerCraig Jennings <c@cjennings.net>2026-05-05 03:28:49 -0500
commit88da84f2ce342f006e8cfb3ec302cc9e32af0591 (patch)
tree5b7ca6c3085214a5574e5144f91479f6bf94c711 /Makefile
parentcbd2334ee3a589bb9335e1bd2a26f3e906180c38 (diff)
downloadorg-drill-88da84f2ce342f006e8cfb3ec302cc9e32af0591.tar.gz
org-drill-88da84f2ce342f006e8cfb3ec302cc9e32af0591.zip
build: add lint, compile, validate-parens, and :slow tag filter
I want a stronger maintainer-discipline baseline as I take over more of this project, so I added four targets that are common in Emacs-Lisp packages. `make lint` runs `checkdoc`, `package-lint`, and `elisp-lint` over `org-drill.el`. It's informational for now and doesn't fail on findings, because the existing source has known docstring and style debt to clear. I'll re-tighten to a hard gate after the docstring pass is done. `make compile` byte-compiles the source with `byte-compile-error-on-warn nil`, matching the existing `build` target's leniency. `make validate-parens` is a fast structural check that surfaces the line of the offending paren without needing a full byte-compile pass. I also added a `:slow` tag filter to the default ERT runners. `test-unit`, `test-integration`, `test-file`, and `coverage` now run with `'(not (tag :slow))`. Tests tagged `:slow` get skipped on the fast feedback path. `test-name` is left alone, since a pattern argument means the user wants those tests run whether or not they're tagged slow. Cask gets `package-lint` and `elisp-lint` as development deps. `.gitignore` gets `*-autoloads.el` so the Cask build artifact stays out.
Diffstat (limited to 'Makefile')
-rw-r--r--Makefile74
1 files changed, 71 insertions, 3 deletions
diff --git a/Makefile b/Makefile
index 9f506b4..ef7ea60 100644
--- a/Makefile
+++ b/Makefile
@@ -42,10 +42,21 @@ DOCKER_TAG=26
COVERAGE_DIR = .coverage
COVERAGE_FILE = $(COVERAGE_DIR)/simplecov.json
+# Source file (single-file package)
+SOURCE_FILE = org-drill.el
+
+# ERT selector that excludes tests tagged :slow. Applied to the
+# default `make test-*' and `make coverage' loops so a slow integration
+# suite doesn't dominate the fast feedback path. `make test-name' is
+# left alone — if the user named a pattern, run it whether or not
+# anything matches is tagged slow.
+ERT_FAST_SELECTOR = (ert-run-tests-batch-and-exit '(not (tag :slow)))
+
.PHONY: help test test-all test-unit test-integration test-file test-name setup build clean clean-elc
.PHONY: robot robot-all robot-basic robot-leitner robot-all-card robot-spanish robot-explainer
.PHONY: docker-test test-cp test-git
.PHONY: coverage coverage-clean
+.PHONY: lint compile validate-parens
# Default target
help:
@@ -67,6 +78,11 @@ help:
@echo " make coverage - Generate simplecov JSON at $(COVERAGE_FILE)"
@echo " make coverage-clean - Delete the coverage report file"
@echo ""
+ @echo "Validation & Lint:"
+ @echo " make compile - Byte-compile $(SOURCE_FILE)"
+ @echo " make validate-parens - Check $(SOURCE_FILE) for unbalanced parens"
+ @echo " make lint - Run checkdoc + package-lint + elisp-lint"
+ @echo ""
@echo "Advanced Targets:"
@echo " make setup - Install dependencies via Cask"
@echo " make build - Build package via Cask"
@@ -123,7 +139,7 @@ test-unit: setup
-l assess \
-l org-drill.el \
-l $$test \
- -f ert-run-tests-batch-and-exit || failed=$$((failed + 1)); \
+ --eval "$(ERT_FAST_SELECTOR)" || failed=$$((failed + 1)); \
done; \
if [ $$failed -eq 0 ]; then \
echo "[✓] All unit tests passed"; \
@@ -170,7 +186,7 @@ endif
-l assess \
-l org-drill.el \
-l $(TEST_DIR)/$(FILE) \
- -f ert-run-tests-batch-and-exit
+ --eval "$(ERT_FAST_SELECTOR)"
@echo "[✓] Tests in $(FILE) complete"
# Run specific test by name/pattern
@@ -214,7 +230,7 @@ coverage: coverage-clean setup $(COVERAGE_DIR)
-l $(TEST_DIR)/run-coverage-file.el \
-l org-drill.el \
-l $$test \
- -f ert-run-tests-batch-and-exit || failed=$$((failed + 1)); \
+ --eval "$(ERT_FAST_SELECTOR)" || failed=$$((failed + 1)); \
done; \
if [ $$failed -gt 0 ]; then \
echo "[!] $$failed test file(s) failed during coverage run"; \
@@ -234,6 +250,58 @@ $(COVERAGE_DIR):
@mkdir -p $(COVERAGE_DIR)
#
+# Validation & Lint
+#
+
+# Byte-compile the source file. byte-compile-error-on-warn is left
+# nil so existing warnings don't fail the target — match `make build'
+# behavior. Tighten when the warning backlog is cleared.
+compile: setup
+ @echo "[i] Byte-compiling $(SOURCE_FILE)..."
+ @$(EMACS_ENV) $(CASK) emacs --batch -q \
+ --eval "(progn \
+ (setq byte-compile-error-on-warn nil) \
+ (batch-byte-compile))" $(SOURCE_FILE)
+ @echo "[✓] Compilation complete"
+
+# Fast structural check — `check-parens' surfaces the line of the
+# offending paren without needing a full byte-compile pass.
+validate-parens:
+ @echo "[i] Checking $(SOURCE_FILE) for unbalanced parentheses..."
+ @$(EMACS_BATCH) --eval "(condition-case err \
+ (progn \
+ (find-file \"$(SOURCE_FILE)\") \
+ (check-parens) \
+ (kill-emacs 0)) \
+ (error (progn \
+ (message \"ERROR: %s\" err) \
+ (kill-emacs 1))))"
+ @echo "[✓] $(SOURCE_FILE) parens balance"
+
+# Run all three linters. Informational — does not exit non-zero on
+# findings, since the existing source has known docstring and style
+# debt to clear. Re-tighten to a hard gate after the docstring pass
+# in todo.org is done.
+lint: setup
+ @echo "[i] Running checkdoc + package-lint + elisp-lint on $(SOURCE_FILE)..."
+ @$(EMACS_ENV) $(CASK) emacs --batch -q \
+ --eval "(progn \
+ (require 'checkdoc) \
+ (require 'package-lint nil t) \
+ (require 'elisp-lint nil t) \
+ (find-file \"$(SOURCE_FILE)\") \
+ (when (featurep 'checkdoc) \
+ (message \"-- checkdoc --\") \
+ (checkdoc-current-buffer t)) \
+ (when (featurep 'package-lint) \
+ (message \"-- package-lint --\") \
+ (package-lint-current-buffer)) \
+ (when (featurep 'elisp-lint) \
+ (message \"-- elisp-lint --\") \
+ (elisp-lint-file \"$(SOURCE_FILE)\")))" || true
+ @echo "[i] Lint complete (informational — no hard failure)"
+
+#
# Robot Tests (Automated UI Tests)
#