COLITUR := colitur PREFIX ?= $(HOME)/.local BINDIR := $(PREFIX)/bin MANDIR := $(PREFIX)/share/man/man1 # The binary locates its calendar data relative to its own path # (/share/colitur/ef), so `dune install` -- not a hand-rolled copy -- # is what places the four .sexp files where a running colitur will look for # them. See bin/main.ml's own [data_dir] for the full resolution order. # # dune needs the project-local opam switch on PATH. Every recipe that invokes # dune goes through this, so `make` works from a plain shell with no # `eval $(opam env)` first -- which is the whole point of having a Makefile # over documenting the dune commands. DUNE := opam exec -- .PHONY: help build test check install uninstall reinstall clean fmt man doc release help: ## show this help @grep -hE '^[a-z-]+:.*##' $(MAKEFILE_LIST) | sed -E 's/:.*## /\t/' | sort build: ## build the binary $(DUNE) dune build test: ## fast suite (~5s): properties sample 200 years $(DUNE) dune test check: ## full gate (~2min): every year 1583-9999, not a sample COLITUR_EXHAUSTIVE_SWEEP=1 $(DUNE) dune test --force install: build ## install binary, calendar data and man page into PREFIX (default ~/.local) $(DUNE) dune install --prefix $(PREFIX) @mkdir -p $(MANDIR) install -m 644 man/colitur.1 $(MANDIR)/colitur.1 @echo "installed $(BINDIR)/$(COLITUR), data in $(PREFIX)/share/colitur/ef, man page in $(MANDIR)" @command -v $(COLITUR) >/dev/null 2>&1 || \ echo "note: $(BINDIR) is not on PATH -- add it, or run $(BINDIR)/$(COLITUR) directly" uninstall: ## remove everything install put into PREFIX -$(DUNE) dune uninstall --prefix $(PREFIX) rm -f $(MANDIR)/colitur.1 @echo "removed $(COLITUR) from $(PREFIX)" reinstall: uninstall install ## uninstall then install (the installed copy is a snapshot, not a link) man: ## preview the man page man -l man/colitur.1 doc: ## lint the man page (groff warnings; silence means clean) groff -man -Tutf8 -ww -z man/colitur.1 fmt: ## format the OCaml sources $(DUNE) dune build @fmt --auto-promote clean: ## remove build artifacts $(DUNE) dune clean # Mirrors lectio's own release target, including its refusals: no release from # a dirty tree, no release without a CHANGELOG line, and no release whose # version bump silently failed to apply. The version lives in TWO places # (dune-project, which feeds colitur.opam, and bin/main.ml's own constant, # which is what --version prints), so both are rewritten and both are # re-checked -- a release that bumped one and not the other would ship a # binary disagreeing with its own package metadata. release: ## cut a release: make release VERSION=0.1.0 (add its CHANGELOG line first) @test -n "$(VERSION)" || { echo "set VERSION=X.Y.Z" >&2; exit 2; } @echo "$(VERSION)" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$$' || { echo "VERSION must be X.Y.Z" >&2; exit 2; } @test -z "$$(git status --porcelain)" || { echo "working tree not clean; commit or stash first" >&2; exit 2; } @grep -q '## \[$(VERSION)\]' CHANGELOG.md || { echo "add a one-line CHANGELOG.md entry under '## [$(VERSION)]' first" >&2; exit 2; } @sed -i 's/^(version .*)$$/(version $(VERSION))/' dune-project @sed -i 's/^let version = ".*"/let version = "$(VERSION)"/' bin/main.ml @grep -q '^(version $(VERSION))$$' dune-project || { echo "dune-project version bump failed" >&2; exit 2; } @grep -q '^let version = "$(VERSION)"' bin/main.ml || { echo "bin/main.ml version bump failed" >&2; exit 2; } $(MAKE) check @test "$$($(DUNE) dune exec --no-build colitur -- --version)" = "$(VERSION)" || \ { echo "the built binary does not report $(VERSION)" >&2; exit 2; } git add dune-project colitur.opam bin/main.ml CHANGELOG.md git commit -m "release: v$(VERSION)" git tag -a "v$(VERSION)" -m "colitur $(VERSION)" @echo "tagged v$(VERSION). publish with: git push origin main v$(VERSION)"