Co to znamená
Obvyklý způsob, jak odpovědět na „k jakému rozsahu tato změna patří?“, je tabulka vzorů cest mapovaných na názvy rozsahů. V den napsání je správná. Pak se přidá nebo přejmenuje adresář nebo se podsystém rozdělí na dva a tabulka jmenuje rozsah, který historie přestala používat před měsíci — a nic si toho nevšimne, protože tabulka nemá jak se mýlit.
Tvrzení je, že tento repozitář žádnou takovou tabulku nevede. Slovník, proti kterému se commit posuzuje, se pozoruje z vlastního logu repozitáře, takže subsystém commitnutý dnes je ve slovníku dnes a ten, kterého se rok nikdo nedotkl, sám klesne.
Princip
commit.scopes přečte nejvýše 1500 commitů jedním git log --no-merges --name-only, parsuje každý předmět toutéž gramatikou, jakou používá changelog, a počítá dvě věci: jak často se každý rozsah používá a jak často se každý rozsah používá pro každý prefix adresáře do hloubky čtyř segmentů. Každý commit v historii je vypracovaný příklad toho, do kterého rozsahu patří sada cest, rozhodnutý tím, kdo změnu udělal, a zachovaný tím, kdo ji revidoval.
Čtyři segmenty jsou změřené, ne zvolené. Zdroj tohoto repozitáře leží v apps/majordomus-cli/src/<subsystem>/; tři segmenty končí o úroveň nad subsystémem, kde mají commity tucet rozsahů a žádná cesta se od jiné nedá odlišit. První verze používala tři a hlásila každou změnu zdroje jako patřící do žádného rozsahu.
suggest(paths) hlasuje o každé cestě na nejhlubším prefixu, s nímž je něco spojeno — takže změna uvnitř jednoho subsystému není přehlasována nejrušnějším adresářem repozitáře o dvě úrovně výš — a hlásí tři věci: rozsah, počet předchozích commitů, které tento rozsah s tímto adresářem spojují, a zda byl stejně spojen jiný rozsah. Remíza je nahlášena jako ambiguous, ne tiše rozhodnuta. Cesty, které historie nespojuje s žádným rozsahem, dají None, což je poctivá odpověď pro první commit nového subsystému a lepší než nejoblíbenější rozsah v repozitáři, což by dalo rozhodnutí remízy podle četnosti.
Rozsah mimo slovník je varování, nikdy zamítnutí. Odvozování nesmí odmítnout první commit podsystému, který ještě nikdy neviděl — první commit právě tohoto podsystému nesl commit.unknown_scope, což je návrh, který funguje, a ne selhává.
Jak to vidět
majordomus commit scopes # every scope, how often, about which directories
majordomus commit scopes --format json # the same, with the sample size
echo "feat(nonesuch): a thing" | majordomus commit validate
# exit 0, warning commit.unknown_scope
bash test/run.sh 274_commit_policy # the case proves the vocabulary follows the history
Zajímavější je tento případ: sestaví repozitář, commitne asi alpha a beta, ověří, že gamma je neznámé a je na to upozorněno, commitne asi gamma a ověří, že gamma je pak známé. Mezi oběma ověřeními nebylo nic konfigurováno.
Co nepokrývá
Není to zadarmo. Čtení jmen z logu stojí na této historii asi sekundu a záměrně není na žádné horké cestě: nic při vstupu do repozitáře, doplňování slova ani odpovídání na --help jej nečte. Čte se, když se commit plánuje nebo posuzuje, což je okamžik, který už zahrnuje čekání na git.
Neříká nic o tom, co rozsah znamená. Pozoruje, které slovo bylo použito o kterém adresáři, ne zda to slovo bylo dobrou volbou — repozitář, který důsledně používal špatný název rozsahu, bude důsledně slyšet, že špatný název je ten, který používá.
Proč existuje
Referenční postup, který tento subsystém nahradil, nesl doslovnou Markdown tabulku vzorů cest na rozsahy, udržovanou ručně. Každý její řádek byl fakt zapsaný na dvou místech, z nichž jedno se mění — tvar, který DYNAMICITY.md jmenuje, a ten, který tento repozitář odstraňuje nejčastěji. Repozitář odpověď už znal; byla v logu.