Zdůvodnění
Repozitář, který jmenuje stroj, na němž vznikl, je repozitář, který se nikde jinde nečte stejně. Tento za to zaplatil dvakrát během jednoho odpoledne, dvěma různými způsoby, a ten druhý je poučný.
První byl psaný dokument. Zdůvodnění I0908 — úkolu, jehož vlastním deklarovaným účelem je, že „v image neexistuje nikde absolutní cesta vývojáře“ — pojmenovalo domovský adresář v textu. Dostalo se to do plan.json, na web a v okamžiku publikace to zbarvilo nasazení masteru do červena, čímž to zasáhlo toho, kdo nasazoval, a ne toho, kdo to napsal.
Druhý byl generovaný artefakt. share/allow/*.txt a share/sections/*.txt byly commitnuty s odkazem na zdrojové schéma absolutní cestou worktree, v níž generátor naposledy běžel. Příčinou byl pomocník pro cesty, jehož fallback byl vypsat absolutní cestu:
path.strip_prefix(root).unwrap_or_else(|_| path.display().to_string())
Share::open kanonizuje adresář pro sdílení; kořen repozitáře přichází tak, jak byl objeven. Když se oba zápisy liší — stačí jedna symlinkovaná nebo firmlinkovaná složka a dočasný adresář macOS je přesně takový — strip_prefix selže a fallback zapíše umístění samotného generátoru do souboru, který se pak commituje.
Přežít jí umožnily dvě věci. Pomocná funkce existovala dvakrát, jako generate::relative_to a jako metadata::rel_or_abs, takže oprava jedné nechala druhou zapisovat stejný únik — opakovaná sémantická definice napříč projekcemi, což tento repozitář už nazývá designovou vadou (ADR 0004). A derive-check je strukturálně slepá k této třídě: regeneruje ve stejném checkoutu a dostane stejnou odpověď zpět, takže strom vypadá aktuálně. Banner se liší až pro dalšího člověka, v jiném worktree, kde se projeví jako nevysvětlený drift v souboru, který nikdo needitoval.
Požadované chování
- Žádný sledovaný soubor neobsahuje absolutní cestu pojmenovávající domovský adresář nebo checkout vývojáře. Pište, co cesta znamená — „pracovní adresář vývojáře“ — ne příklad takové cesty.
- Pravidlo je jedna kontrola nad celým sledovaným stromem, ne seznam adresářů. Nejprve byly vyzkoušeny dva seznamy povolených pathspec a
site/content/— generované, commitnuté, publikované — nepokryl ani jeden. - Cesta, kterou zaznamenává generovaný artefakt, je relativní vůči repozitáři, kdykoli je soubor, který jmenuje, uvnitř repozitáře. Share adresář skutečně mimo repozitář, zadaný přes
--shareneboMAJORDOMUS_SHARE, si ponechá absolutní cestu: to je jediná poctivá odpověď, když relativní neexistuje. - Funkce, která počítá cestu relativní k repozitáři, je v cratu definována jednou. Druhá kopie je druhý fallback a druhý fallback je to, co uniklo poté, co byl opraven první.
Dvě výjimky, obě úzké a obě nutné. Fixtures pod test/ takovou cestu pojmenovávají záměrně, protože kontrola, o které nelze ukázat, že selže, je dekorace. A samotný vzor je zapsán jednou, protože něco musí: apps/majordomus-cli/src/quality/leak-patterns.tsv, které čtou scripts/ci/no-machine-paths, scripts/site-check i majordomus quality rustdoc, takže žádná kontrola nedrží jeho kopii, jež by se mohla rozejít s ostatními.
Chování při selhání
scripts/ci/no-machine-paths skončí s kódem 1 a vypíše každou shodu jako file:line:text, pod zprávou, která jmenuje obě vady a jejich odlišné opravy: psaný dokument je problém formulace, generovaný artefakt je problém generátoru a to druhé se nikdy neopraví úpravou souboru. scripts/ci/core-check ho spouští jako blokující krok, takže shodí commit, push i CI.
scripts/site-check si drží vlastní kontrolu private nad sestaveným webem. Ta zůstává: je to poslední linie, zachytí cokoli, co se k publikaci dostane cestou, kterou nikdo nečekal, a stojí jeden grep.
Ověření
test/cases/58_home_path_gate.sh spouští scripts/ci/no-machine-paths samo, místo aby znovu implementovalo jeho grep, a dokazuje každou polovinu nad fixture repozitářem: autorský dokument nesoucí domovský adresář selže a jeho přeformulovaná podoba projde; generovaný banner jmenující své schéma absolutní cestou selže a jeho podoba relativní k repozitáři projde; a soubor pod site/content/ selže, což je případ, který dva povolené seznamy pathspec minuly. Také ověřuje, že kontrola je zapojena do scripts/ci/core-check.
apps/majordomus-cli/src/generate.rs drží jediného pomocníka a jeho dva jednotkové testy: jeden řeší share uvnitř repozitáře dosažený jinak zapsaným kořenem a selže na předchozí implementaci s absolutní dočasnou cestou tam, kde se čekala cesta relativní k repozitáři; druhý drží případ externího share, takže oprava nemůže potichu udělat z poctivé absolutní cesty relativní.