From c06ebb7344b7f267c325b832632f7cd4e81939e7 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 17 Aug 2026 15:45:27 +0200 Subject: feat(cli): install the runtime data, and resolve it in three ways `dune install` produced a colitur that could not run: the binary locates its data relative to its own path, nothing installed the four .sexp files anywhere, and an installed colitur exited 2 unable to read sanctoral.sexp. `dune build @install` produced an empty tree. data/dune installs the four RUNTIME files into /share/colitur/ef. Deliberately not the two allow-lists: those describe where colitur and a comparison oracle disagree, are read only by the differential and oracle tests, and are meaningless to a running colitur -- installing them would ship an assertion about lectio's and missalemeum's behaviour as though it were calendar data. No glob, on purpose: a glob would silently start shipping them again the moment one was renamed. Resolution now probes rather than computing one path and hoping. An installed prefix is tried first, the build tree second, and a candidate counts only if sanctoral.sexp is actually readable inside it -- so a failed or half-removed install falls through to a working tree instead of shadowing it and failing later with a per-file error. COLITUR_DATA_DIR overrides both and NEVER falls through. This was the one real design question and the first version got it wrong: it treated the override as just another candidate, and a deliberately bogus value produced a full, plausible, entirely un-flagged year computed off the build tree. Someone who names a directory has stated an intent, and silently calendaring off a different one is the silent substitution this project refuses everywhere else. It is now exit 2 naming the directory. Verified end to end, not inferred: installed to a scratch prefix, then ran the binary from an unrelated cwd with no build tree near it, and confirmed 2038-03-06 still resolves Perpetua and Felicitas through the Common route. All four paths exercised -- build tree, valid override, bogus override, and an empty share/ falling through. Environment reads stay confined to bin/. The kernel's contract forbids them and nothing below the CLI learns where the data came from; the loaders take a path. --- data/dune | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 data/dune (limited to 'data/dune') diff --git a/data/dune b/data/dune new file mode 100644 index 0000000..07e5307 --- /dev/null +++ b/data/dune @@ -0,0 +1,23 @@ +; The four RUNTIME data files, installed into /share/colitur/ef/ so a +; `dune install`ed / opam-installed `colitur` can find them (bin/main.ml's own +; [data_dir], which probes the installed layout before the build-tree one). +; +; Deliberately NOT the two allow-lists (expected-divergences.sexp, +; expected-divergences-missalemeum.sexp): those are test fixtures describing +; where colitur and a comparison oracle disagree, read only by +; test_differential.ml / test_oracle.ml, and are meaningless to a running +; `colitur`. Installing them would ship an assertion about lectio's and +; missalemeum's behaviour as though it were calendar data. +; +; If a new runtime data file is ever added, it must be added HERE too -- there +; is no glob, on purpose: a glob would silently start shipping the allow-lists +; the moment someone renamed one, and an omission here fails loudly at startup +; (exit 2, naming the missing file) rather than silently degrading. +(install + (section share) + (package colitur) + (files + (ef/sanctoral.sexp as ef/sanctoral.sexp) + (ef/adjustments.sexp as ef/adjustments.sexp) + (ef/lectionary.sexp as ef/lectionary.sexp) + (ef/commons.sexp as ef/commons.sexp))) -- cgit v1.3