Zdůvodnění
Řazení bylo poslední, o čem v tomto repozitáři rozhodoval každý povrch sám. Crate nesl osmdesát komparátorů a ty, na kterých záleželo, se rozcházely: tytéž nálezy byly v why a product řazeny od nejhoršího a v web::validate od nejlepšího, protože dva enumy Severity byly deklarovány opačným směrem, a tak musel být tentýž záměr psán jako opačný kód — čtenář, který je sjednocoval, by jednu zprávu obrátil. Týž dokument měření výkonu řadilo p50 na webu a p95, bez rozřazení shod, v příkazové řádce. Tabulka tras Cockpitu byla řazena podle HTML vlastních řádků, takže přejmenování třídy CSS ji přeuspořádalo. Jeden komparátor nezávislý na velikosti písmen existoval, v navigaci Cockpitu, a každý jiný povrch vedle něj porovnával surové bajty.
Nic z toho nebyla nedeterminističnost v obvyklém smyslu. Zjišťování je zde jednovláknové, index je řazen podle URI, registr je BTreeMap a crate drží přesně jeden HashMap — cache executoru, kterou nic neprojektuje. Vada byla horší než race: šest povrchů, které se shodovaly na faktech a rozcházely v pořadí, takže člověk, který je porovnával, usoudil, že repozitář nesouhlasí sám se sebou.
Pořadí je projekce a project.interfaces-are-projections už říká, že projekce nenese žádnou vlastní definici. Toto pravidlo je tatáž věta aplikovaná na posloupnost.
Požadované chování
- Jeden vlastník.
apps/majordomus-cli/src/order.rsdefinuje pořadí: typ implementujeOrdered, odpovídáOrderKeyskupiny, pořadí, popisku a identity a volající volajícanonical(). Kolekce seřazená jakkoli jinak je seřazena názorem. - Klíč končí identitou. Poslední část každého klíče je v rámci kolekce jedinečná, takže pořadí je úplné: dvě položky se stejným popiskem si nesmějí vyměnit místa proto, že byla přidána nesouvisející položka, byl použit jiný iterátor nebo jiný stroj vyjmenoval jinak.
- Řaďte hodnoty, ne vykreslení. Klíč řazení jsou data. Řazení vykresleného markupu dělá z názvu třídy, escapování a rozhodnutí o bílých znacích součást pořadí.
- Porovnávejte kódové jednotky, nikdy locale.
LC_ALL=C sortv shellu,<a>v JavaScriptu,Ordv Rustu. Porovnání, které řadí podle locale čtenáře, řadí publikovaný výstup podle toho, čí stroj ho vytvořil. - Závažnost je větší, když je horší. Obě enumerace závažnosti jsou deklarovány od nejmenší, takže komparátor, který dává nejhorší první, čte
b.cmp(a)všude, kde se objeví. - Konzument znovu neřadí. Cockpit, šablony webu, generované indexy a JavaScript běžící v publikované stránce vykreslují posloupnost, kterou jim registr předal. Explicitní řazení, o které člověk požádal, je jiná věc a zůstává.
Chování při selhání
scripts/ci/order-check je kontrola. Tři její testy jsou absolutní, protože je strom splňuje a nové porušení je vždy omyl: komparátor bez ohledu na velikost písmen mimo order.rs, klíč řazení volající render() a .localeCompare( pod scripts/, share/ nebo site/. Čtvrtý je rohatka nad dluhem předcházejícím pravidlu — počet míst řazení v crate mimo order.rs a počet shellových volání sort nepřipnutých pomocí LC_ALL=C — držená v .ai/repo/order-baseline.txt, která smí klesat a nesmí růst. Počet v crate se týká kódu, který se dodává: řazení uvnitř čehokoli, co zavádí #[cfg(test)] — modul, funkce nebo celý soubor, který hlídá deklarace #[cfg(test)] mod — nebo uvnitř doc komentáře řadí fixturu či příklad, je z binárky vykompilováno a není druhým názorem, který by kterýkoli čtenář viděl. Počítání těch by chtělo kanonické pořadí v testu, jehož celým účelem je pořadí tvrdit, a kontrola, která křičí vlk, je kontrola, kterou někdo vypne. scripts/ci/order-check --sites vyjmenovává přesně to, co každá rohatka počítá, takže čtenář čísla nemusí rekonstruovat, z jakých míst se skládá. Počet v shellu se týká sort(1) a ničeho jiného: soubor .jq drží program jq, ne shell, a sort uvnitř oblasti v jednoduchých uvozovkách je argument, z něhož shell nikdy nestaví pipeline — v obou případech je to slovo vlastního filtru jq, který řadí hodnoty JSON v pořadí, jež definuje jazyk a které žádná proměnná prostředí neovlivní, takže není locale k připnutí a LC_ALL=C před ním by byl nesmysl. Commit, který přijme kanonické pořadí, snižuje baseline pomocí scripts/ci/order-check --update a kontrola odmítne baseline, který už strom neodpovídá v obou směrech, takže dluh nelze potichu přepsat ani jedním směrem.
Kontrola běží v jobu structure pro změny crate, skriptů, shell nástroje a webu.
Ověření
test/cases/99_canonical_order.sh pouští kontrolu proti fixture stromům, ne proti tomuto checkoutu — případ tvrdící vlastní počty repozitáře by byl kopií základu — a zapisuje každé porušení, aby viděl jeho odmítnutí: složený komparátor, klíč řazení, který se vykresluje, porovnání podle locale, počet, který vzrostl, počet, který klesl, a strom bez základu vůbec. Také ověřuje, že slovo v textu není voláním v kódu, protože kontrola poprvé selhala na dokumentaci tohoto pravidla.
scripts/ci/order-check na tomto stromě. Samotné pořadí se dokazuje tam, kde je deklarováno: apps/majordomus-cli/src/order.rs seřadí každou z 5040 permutací sedmiprvkové fixture stejně a zkontroluje komparátor na antisymetrii a tranzitivitu přes každý pár a trojici — komparátor, který selže v jednom z toho, může způsobit, že sort odpoví jinak pro jiné pořadí vstupu, což je selhání, kterému toto pravidlo předchází. Příklady v dokumentaci běží pod cargo test --doc.