| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
config.ml and lang.ml both parse the INI format through the same reader,
Colitur_kernel.Overlay_ini.parse_sections, but resolved a repeated
[section] header oppositely: lang.ml folds over every section sharing
a name, while config.ml used List.find_opt and silently discarded every
[defaults] block after the first. Two modules parsing one file format
must not disagree about what a duplicate section header means.
of_string now folds a single accumulator across every section named
[defaults], in file order, matching lang.ml's of_string shape. A
scalar key (lang/template/format) repeated across two blocks resolves
to the later value, consistent with the existing within-section
last-wins rule; overlay keeps accumulating across every block, not
only the first; and unknown_sections still excludes every [defaults]
block, merged or not, since merging it is the point.
config.mli's lang doc comment is extended to say the last-wins rule
holds across block boundaries too, cross-referencing lang.ml's own
duplicate-section policy so the two do not drift again unnoticed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
F1: test_unknown_key_is_reported_not_fatal never asserted unknown_keys
itself, only that parsing survives -- a no-op accumulator passed it.
Now asserts the key is actually collected.
F2: a misspelled section name, e.g. [deafults], was silently discarded --
Ok empty, lang and everything else gone, nothing reported. That is the
highest-value typo this feature exists to catch. Any section other than
[defaults] is now collected into a new Config.unknown_sections, kept
separate from unknown_keys so the CLI can word the two warnings
differently. Still non-fatal: a newer colitur's added section must not
break an older binary.
F3: overlays and unknown_keys accumulated with '@ [v]' per line, O(n^2)
over the field count. Cons during the fold, List.rev once at the end.
F4: documented that lang/template/format are last-wins on a repeated
key, the opposite direction from Overlay_ini.get's first-wins over the
same section type.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
F1 (review round 1): of_string's find took only the FIRST section of a
given name (List.find_opt), so a second [celebration] block anywhere in
the file was silently dropped in its entirety -- reproduced with two
blocks (a in the first, b in the second): b resolved to the slug
fallback "b", not its real value.
This is a data-loss footgun aimed squarely at what happens next: Tasks
3/4 write a 595-entry, hand-edited la.ini, and appending a second
[celebration] block is the natural way to paste in a new batch of names.
Worse, the failure surfaces nowhere near its cause -- a coverage check
reports the dropped slugs as missing a Latin name, with nothing pointing
at the parser.
find now folds over every section sharing the name, in file order, so
all blocks merge. This also settles which value wins when the same key
appears in two different blocks: later in the file wins, consistent with
the existing within-one-block behaviour (unchanged, still last SM.add
wins) and with what a reader expects when appending to an INI file.
lang.mli now documents both duplicate policies explicitly, and notes
they run OPPOSITE to Overlay_ini.get's first-match (List.assoc_opt) over
the same section.fields shape -- undocumented before, and a latent trap
since the two modules read the same section type but resolve a
duplicate key in opposite directions.
Three tests added: two [celebration] blocks both resolve (the F1
regression), a key repeated across two blocks resolves to the later
block, and a key repeated within one block still resolves to the later
line (confirms unchanged behaviour). Confirmed the regression test fails
against the pre-fix code (b resolves to "b", the slug fallback) and
passes after.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Owns precedence and provenance and nothing else, and never reads the
filesystem, so it is as testable as the language table.
resolve returns the value AND its source, because a setting that silently
comes from a file the user forgot about is worse than no setting at all --
config --show can then say where each effective value came from.
overlay accumulates rather than last-wins: a user has more than one.
An unknown key is reported, never fatal. A config written for a newer
colitur must still work on an older one, but silently dropping a line the
user wrote is how a typo becomes invisible.
|
|
|
Maps strings to strings and nothing else -- no calendars, no dates, no
filesystem. That is what lets every command use it without the kernel
learning about presentation.
Every lookup is total, and a miss returns THE KEY rather than the empty
string. A partial translation is therefore usable from its first line,
and the fully-degraded case is exactly today's output (bare slugs) rather
than a blank page.
--raw is a real identity table, not a special case threaded through every
call site: one value the whole program passes around.
Reuses Overlay_ini's INI reader rather than growing a second one that
would drift in its comment, quoting and trimming rules; parse_sections is
exposed in the .mli for that, with no behaviour change.
Fixes one defect found while running the brief's own tests rather than
transcribing them blind: weekday's internal lookup key is an English
day-name word (month's is already the numeral string), so on a miss it
echoed that word instead of the documented numeral, breaking both the
0=Sunday convention and Lang.raw's own identity contract for weekday.
weekday/month now fall back to string_of_int n directly on a miss
instead of through get's generic echo-the-search-key path; month is
byte-identical since its key already equals string_of_int n.
|