From c6d63352a08725048865d3f5f87e78a871e4747e Mon Sep 17 00:00:00 2001 From: Menno Morsink <3490488+menjoo@users.noreply.github.com> Date: Wed, 19 Aug 2026 15:50:27 +0000 Subject: [PATCH] Follow upstream drift, and stop the drift check crying wolf The scheduled upstream-drift job has failed on all three of its runs. Only one of those was news: * cucumber/gherkin dropped the trailing space from the Texas dialect's `rule` keyword ("Rule " -> "Rule"). It matters: GherkinParser matches block keywords as ":", so with the trailing space a `Rule:` line in a Texas feature was never recognised as a rule. Regenerating the dialect table fixes that. The rest was noise. Each corpus tool cloned upstream shallowly and pinned `rev-parse HEAD`, so the recorded Source line moved for any commit to those repositories -- a README typo in the monorepo re-pinned all 50+12 Gherkin fixtures -- and the drift check reported news every week the fixtures had not moved. They now pin the last commit that touched `testdata/`, which is the provenance the line was always meant to carry. That needs a path-scoped log, so the clone is blobless rather than shallow; it stays cheap (~8 MB, under three seconds for cucumber/gherkin) and the whole regeneration still runs in under ten seconds. Re-pinning to the last testdata commit moves all three Source lines once more, with byte-identical corpora underneath. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_012FHrC4wQaCMKaHLZcnFiS5 --- DEVIATIONS.md | 2 +- .../core/gherkin/GherkinDialects.kt | 2 +- .../core/expression/ExpressionCorpus.kt | 2 +- .../cucumberkmp/core/gherkin/GherkinCorpus.kt | 2 +- .../core/tag/TagExpressionCorpus.kt | 2 +- .../update-expression-corpus.cpython-311.pyc | Bin 0 -> 18330 bytes .../update-gherkin-corpus.cpython-311.pyc | Bin 0 -> 28098 bytes .../update-gherkin-dialects.cpython-311.pyc | Bin 0 -> 9471 bytes ...date-tag-expression-corpus.cpython-311.pyc | Bin 0 -> 9921 bytes tools/gherkin-languages.json | 2 +- tools/update-expression-corpus.py | 38 +++++++++++++---- tools/update-gherkin-corpus.py | 40 +++++++++++++----- tools/update-tag-expression-corpus.py | 38 +++++++++++++---- 13 files changed, 96 insertions(+), 32 deletions(-) create mode 100644 tools/__pycache__/update-expression-corpus.cpython-311.pyc create mode 100644 tools/__pycache__/update-gherkin-corpus.cpython-311.pyc create mode 100644 tools/__pycache__/update-gherkin-dialects.cpython-311.pyc create mode 100644 tools/__pycache__/update-tag-expression-corpus.cpython-311.pyc diff --git a/DEVIATIONS.md b/DEVIATIONS.md index 67d2dd7..f3cad8b 100644 --- a/DEVIATIONS.md +++ b/DEVIATIONS.md @@ -4,7 +4,7 @@ aspiration — see ARCHITECTURE.md §2. Every intentional difference belongs here, with its reason. An undocumented divergence in a port is a bug report waiting to happen. -**Ported against:** upstream `cucumber/gherkin` `main` as of 2026-07-31 (80 languages). +**Ported against:** upstream `cucumber/gherkin` `main` as of 2026-08-19 (80 languages). ## Architectural diff --git a/cucumber-kmp-core/src/commonMain/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinDialects.kt b/cucumber-kmp-core/src/commonMain/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinDialects.kt index 4335974..fb3017d 100644 --- a/cucumber-kmp-core/src/commonMain/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinDialects.kt +++ b/cucumber-kmp-core/src/commonMain/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinDialects.kt @@ -419,7 +419,7 @@ private fun gherkinDialectsChunk2(): Map = mapOf( name = "Texas", nativeName = "Texas", featureKeywords = listOf("This ain’t my first rodeo", "All gussied up"), - ruleKeywords = listOf("Rule "), + ruleKeywords = listOf("Rule"), backgroundKeywords = listOf("Lemme tell y'all a story"), scenarioKeywords = listOf("All hat and no cattle"), scenarioOutlineKeywords = listOf("Serious as a snake bite", "Busy as a hound in flea season"), diff --git a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/expression/ExpressionCorpus.kt b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/expression/ExpressionCorpus.kt index b708840..db05584 100644 --- a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/expression/ExpressionCorpus.kt +++ b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/expression/ExpressionCorpus.kt @@ -1,7 +1,7 @@ // GENERATED FILE — DO NOT EDIT BY HAND. // // Regenerate with: python3 tools/update-expression-corpus.py -// Source: https://github.com/cucumber/cucumber-expressions @ 6dbb4888abadf5d3e113f18b00e4887507ce6ca9 +// Source: https://github.com/cucumber/cucumber-expressions @ 7e7c482cbeb79a72580049c747aa23392b6fc20a // 16 tokenizer, 28 parser, 8 transformation, 65 matching, 3 regex package io.github.menjoo.cucumberkmp.core.expression diff --git a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinCorpus.kt b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinCorpus.kt index 48a237f..6d80b8f 100644 --- a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinCorpus.kt +++ b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/gherkin/GherkinCorpus.kt @@ -1,7 +1,7 @@ // GENERATED FILE — DO NOT EDIT BY HAND. // // Regenerate with: python3 tools/update-gherkin-corpus.py -// Source: https://github.com/cucumber/gherkin @ bce691b4d3ec06d3b9ce83bf6c264ec11f108540 +// Source: https://github.com/cucumber/gherkin @ 39d5a71caaa2b6e90042a043525c8e6cd8a7be09 // 50 parseable features, 12 failing features. // // Embedded as Kotlin rather than test resources because Native and Wasm cannot diff --git a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/tag/TagExpressionCorpus.kt b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/tag/TagExpressionCorpus.kt index 0f05390..fcb957e 100644 --- a/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/tag/TagExpressionCorpus.kt +++ b/cucumber-kmp-core/src/commonTest/kotlin/io/github/menjoo/cucumberkmp/core/tag/TagExpressionCorpus.kt @@ -1,7 +1,7 @@ // GENERATED FILE — DO NOT EDIT BY HAND. // // Regenerate with: python3 tools/update-tag-expression-corpus.py -// Source: https://github.com/cucumber/tag-expressions @ 3046b904a97b088855029abf5b0f2c935024d4c6 +// Source: https://github.com/cucumber/tag-expressions @ 80196942f4e16407f25a481097e954fcbe06e7fa // 23 parsing, 26 evaluation, 15 error cases. package io.github.menjoo.cucumberkmp.core.tag diff --git a/tools/__pycache__/update-expression-corpus.cpython-311.pyc b/tools/__pycache__/update-expression-corpus.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f22a53ab699367c216b5a38ca8d6ecf4f555e423 GIT binary patch literal 18330 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 literal 0 HcmV?d00001 diff --git a/tools/__pycache__/update-gherkin-corpus.cpython-311.pyc b/tools/__pycache__/update-gherkin-corpus.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ee12d9ec5654e022f75297b1d32186b527282e9c GIT binary patch literal 28098 zcmeHwYiu0Xm1Z@&`u*Um`KII&Nl9#p4@sm%y)B8PNKq1Li=G@UoGr}?~@JuT-g>}fr3 z75VeF0?u!`!g3_se#Z}i`N#ODT~TN9E%W(9{P=My;EF5xntnU)_Pa$>#KCc*nL!JK zRt9Yh+8J~(=w#5vpqs%$g69jxqVq*!u~;IOiXO2{EdRiCzF6EYR=>%gFA;Z$>+mcs z;CeW5{hOTl(hmzzF8tH3^PWV?GEw+|KVK%ciS>wIj`R(9R*3E57CbA(onkYdRpKtO z70+sajkxV9!y*BqM2)1%YZF8QU_@kENSKNJ>yVPA{gKAem+ zHGOGvB6Qgw5_WDAF1C#Mec@@ze^D5lm_%6kvM(%Ln+}DADW4Sb3saNGW&4hd@G;-S zWRu|cjb0XROoT5}3GM!yzR|D{oDNS-hlPo7NJ}gUQ&Lcz9`%P>gj4?M&_rMyv4g-m zHgS_O4G9yJBWiQm@0&tdsaleMG#v1ULc;j8Px1xAe!ty!9eMgLO@bUj!6!@wrLfT4 zEQI`i;qa->-eW`EokPQ?x?8S^!k_)&4perCaB37n4*qKs;jmv6d?Dd@FgyuLhJw=) zhzJUUP*k^oK%^2-B=#jF1OvjW0*eo*~~gszAEAL(>yr z1{BJF-7g`kPa5}!TZChvc1Z9|QfAZyz(nM{<{w3sCQwHDH6{Vuji7XuTE;&)W}gm$ z^5CSL)@P*-Uj|AsI6f8(ifEuP$k}~!3XK8^9v&P*b`mQa3PM4wML>#RU}DraDS*2E z=1aa1eUW^l{ubd3#l8k^LhDgTD3k2=B=2qx34MbD{lX>xs1M}>FG-Y}Ao?dKz|rUm zsGB%3Hs+U5D74^ZFpSU`^7|%{)dbi?8e_;O0--RqNN~&!P6|q>LxN2uuuEWiQe&jC z3IC)R^6q04V&y`6PH9X@L<{-R&%zUmRGOwM|QZ=6sB11#vRG@ zNFL`|dP|~`k)i|@J6TU{xf=eJ3FVAiItTiPy3Y>9&4)XOjt%t3Ed#?todYMk;|_f3 z8}3hp4)-7LA2`$RH6cY13~&=AIXp_0LyGAz3g}0QVBpGhAQ3toxEcuF2*gd-eUsBv zk+2juOMbL^U^F#Xp$Hg&IU~mzzNGQ`9yh~9@yxw2{}t%xifC>mgos9wf3A2Y(fnNT zETUB(5A%kt|Eb~irv`dVd3fe zXR}}2><^(|_@&K={W2x%2AJc%u)5xM-F7XAi$@h}y=txh8(Y!siUrTYv|?MQ+SWb$ z=c>(QGJgp~T$~SJD2(&s#AsO81hhn9O>hS<&uW4RPEU$i!;B${G`W{pAR6^?zsHGu z-q@zx*!O9IHuuM^lfhBei{do*7bV4Br`qf0I%DqQx5safFN`hv6t|$d1=+C&ceL#f zJN|vg((VVZD)k*|eTNn*^LwO5pc}=%)RkDn7`_Z3=pN_i&Kt1SD-f$hBUUIzv0Aj^ z$%{3j15Xp4PCU(cy707!wPF#TR{So;(}rgWo_0J-@pRzn!PALn8J;e2omhdVTdV|` z*2kS}bUZRWF^Q2;szwpwe19%J$Z3J)HC31t@M}~gT(?oO*;f1Fe zOygZf%(!)AWFjyT9vO+0W#-qC4DJW25G^g|xR_8k&)>1nPig-M-fDPcqR2InmJ^oLPhXj1moCDK?Gs?B_5X6sFAmz|7n3BfIT`8 zBX0IhO=0rz8l~O%DeWb&A0R}>y zwCw$+C67|wtXNxAYm1z`S;ZM&N?VXhS63{RwYGSG7t}RhKQfGG^|>zY!ogW1hRHQ4 zGE*QHglS|?Tr);JRnQBKVN3EWD2L&a+CjUrCxr3bXktV_vWzQtV9X(U z);yPBWWGP*6fr?a6H_$p3UNoquQ&&mK7?%8+`$^*qXdtqsIKF2sRxlGl{yyBz;_m3 zL;C<2r@w8xZCltVSDpOCycGV)%^%%dc0H7o);_hhPiZ`^HXg?(+={hdwf4)&JC~G& zK*&hh2>4<=zhJmEdtqUmB}yopYIiN9H< z%iSb8(^&K|0|wDGYkmf0+|(_^LLGffdK{>2QC5D%`SL^Dk{L5#X;unP{uFD_r;O3( z4bZ17oo?3hYwJ<2tA{1K9`|#)CNO4X76N96JVF`QXxb2!>obVC8r-tTV(TozY<15zcw3CiF*p?78pI(F!D{jAua?VLnK82KD>sRKq1ac!5g7pQ77}7*&r2n9q&GOX5duU$k4f0 zx(Bl+4vB^#uQhx2;E5V>XQGZHRKvItrH-3esp2M(kQ=arh*)SB1kPb8+HSW($(fuXq5aNipByzlc7A42kTHk{LedHk%f&yfQi}GeMf>EUegCw& z5lzS%Q(Ki0Ydy6?I2V46_CptRi!+j-vWdzGrl5%mi>^7g=)#BGD`)P{S#+&2a2VH~ zY{Y`>0Rnj+W|LEH#t1>)Mm7ZVy444tJ#=MFVZ3Ng4~*Gy*I4!)x${jn7+Lxw)QN?- zY1BVC8IlH3ga~^Vq)xoE?JgF4hv=QH0JqT_TLzl6j!cwKECYcFatcC3gJ?!ir8rru zK^i)y5FGjtfUO2sIiu|i_>!P*{nwUW|Fy~M+7xHI>TH*t?Xk+5Kd^k)616OqD3wiW zWfR!fMHmP!@F`Bx7;gBJvk%0N-uU#P6i1C$(G4O>KKo$SDmi<}0VtgjAWJysBB*EcP&zx(<2wt_UHPz*v zMDwS}x6HHZc^UnNm)d|o-)4!GN3>;6zDQxtsQ?0I_;CYjVb4>GXXoO0?p*TK&Y3+n z3$LGf1H#=alHtJkvDeos0=sAz+sP2h=spW2ATEs1hS6Nr=D^~VsFC0z1m=76bMTJ)z0osDZL?b2jGkV+gMpu$ zmv210rM~>Cvip>}`&9bFnY{NOeI34}k`?nOQ zS9N-2rx&?Da@MXmYq5y%FZsSdp*Xjx&TX=DTdb`1-fMSXi>_13TGg`F`J=JIvQ@6Y z)v6nLqGy$&7PY8FE^0}J?^j>O3er58`FD2Bcy{%N?dt)1OD%vbMbX z&WBaJUKRnRTmDH$Mei&svqXKDDhc9sbx;z1SW#f3RQiG^(CPnzOV7;BK28 zOEQ}sOELgEXLCKWR<2kp7d;97wt7{oSGIZ~`g+@b+rH4gSQagQze*EH%hr1Beg-#5 z|H4hQ^Z~z48T>Yqg?<5$%eCp9QIc!3_eF{D7vfqbtZG;^MGf!U6lF;Mo`CX5w;9 z>CzoN{Qfb;x=FQel9Tr{xctz+aQSb=43Nz<@F$j`6ly!;xsj$Vcy1X|)X_?0KL z*;@+)eV6$3)3x~Yz23#4clzJ$PmiLXoPN-?T=la7rMXLO?n;OMuKDyu_>smIw$=FG zczLm{#szWKC>AgY+Pb_;XT(U)&oeo4u{-smF@+(;4=76Nf^05hHLwPTF6awM%2|st ztUb5ubQf!2@H1XA^-B_Rl}Ilq(GF4y0VGuwIib5LMtZGkV!V{4tRQ?@<6V;Fet=J* z_W>~8l~vt4d-v?(m8CkRtXVC?^3!bF#=v}ctgvQrS}ttBO{=`ZyM<9xbW#=C9t@|1 z7LZ%SiYZ!g18$1uy6al>NBh+EkZ&kO9codB%?)y zbtN~7uKXnz-C1!9^T*8))ZLPRsanzEIk$!_p zm&CH{(zh2>wI%&bxgWPemOBlTmM{i#7{1^oA!kbdOo*CDaT~WJZ0aJ`#EbCME=>9Y zFlZb1AAt2h;&si5jAtrZ8q6P0V&00#zvNUe4M`$oCq*Qa#E#9y@;gVtd!C% z{K^_BZXhUYq)6886N>#B7(BHyTG+5~Ua<^4G_P7f^x$0GjyUr*LJJp7r_<@^kZm)m#4Q2O$x_dwiQ=F$%=P8-pv68ZTo9}L3 z^eQC{YDvSqCFUrR9qUuuX4+L0pE2Cu9qmzSn$#MSli{}pmn{$N>h9y2L62)TL^m&a z)w*`2W~W-SlQzxC=#LL{KJ5AY=${WL2Zq!GLz$nRv7`Q);@qG*H^|NnnY(G9Zkv1Z z_Q}P~(d~+Jqw3r!J2%D(OW(eA`_`i8gKDL)LB-H&ZD3;muBW7lLCcwOy?>o*p(NW+Nv1h||XPO_Z=L323z+Dq=h~2R@@e zw5_Qgt)~NKg9#E8JunxTNV}c`tp?Ko@j^BO0& zJt(o6pytZ>)3*;eIVoB{nh<+-Aa5Mc?KSY0z!(^kIkTLb=tFL2?slOTG*nCR`r*1;! zpIM5mWdW>GTJn~|m0J$j5?q`$g)=6zXp$VdXI^c(TP)O1q}dZIH0Js0SzJ0X!IqVb>yu}-HZb?$mR8Z2=^~76x`V()~{W@ z8G}9#EUg+McREvM<6$zShRrs!pT^o{3WpJ3K~6ULqcA29!E~Bbaf7!4FtCPMws3Jm zyx4lt7Yg^oe)O0ay2#AZgRljFQTkp&bBl!}?aN`t9lUzg@1KGZL6bms`zZ_W7KWNF zu_B2fR*;%O9Jch6TIj8nK!m{835*lyB0!TOOd4R3KQ2f#FTw~-ZwlcQ1k&hhRu9qu zC1R^YD{T1Ll2Uqw!pM-XUpfUCsidl=O&-#A4bm{hJWb#XMRc)W5kGgq}7McmQsqzxiMOfp(ngR-7ZP{$n^gm>*%*q(|=+8J>yEiRt6Y_-;|YOzL(EQ<~^(%)j0 zRf}6baFIkk8U1l{+k?Xo#(s88X+EenAI$vp#AqaOI{>M#?WX`O9bmreACXJrqtdM_rCXP}e$xA+-Up|b&nZnkYE#eWRZ8igS~@u2 zmCCDciI=PTaKn7E{h|4@{RtBi7N$6ltIp%H^LQ+&hf^xHsuf%1itS6%d~d91|NQ#H(a*hq9#CE$R$m_0!k!ol$cO|0 zYg7O;8NehnEn*lJN0g#wwWwJxYL3;^M~|yD+aA@luhg`o;-{3FLu$<-O54G}LT9XY z!yoj0w@>5!hi(70e(f;`=6fFgXpUb929kXZtqzbRva~|qekXySbx%u8a$YmiC%CX@P$M#Q6$X0 za#xAb+(-x!f8!$%dGOgpyMA4iC!PcLi0Go}V}G;I49*y^IxsS;e^=_UFo5ZFMVjzB$u27tt<88_mDT;@rDxJx@ZGol%{Np}(Vf8k#! z1d#WTMd^ZHvDK=!TJ4ZU*3aiXg5ly!*3}};Sw0_{-%EcoU&h!V&X42d*VAfdhZLTM zmi{#q4@bii;KGHt@sdw`ilbgIRLYLP0ul8BMZ<9fEJF^ir%X7O{! zEP3vjrOzERYa{m0Liw`i&OK`b_l(?s7nHAf?sEPXRGR0;u-Samnkgq2t8{%lYYYgd zeE3BQUhcCe7V%jm@p#M-p?65 z@6_f^le_WFhdrmShaE{ukbPTrNg*sLdmWSYtO-Jmd^p#$62FvN;u$mQ`j@X`fir8F zwa(gRp%;m!v&(oB1%1xX;MxsgS32QLj*-4tw?;YgC8*nCOw7z|Lv7x^V%9m zu?509XZ9Gcuhpz8Z~a?mT+x4~rar@eJ&OY=BQPPh7Y0_x5 zwhBGn{oSVy4|R75M~|K87XEhbU7>40=pPsoy1R}I2}jNey@&g|S|SClt&x3*f67k+ zCgvZ7d^_xYUS|ps2NDl54fP6CTP~;h&M3NpY((Xfq4EG_^B=-YO2`0@sUPKrrQXVC6kO>Cl4&k;lHPJOS1kez*n{ND zggnTQN1Ia*sM!thhI&qE}`~a1r;Y-ptzsL67Gu#Ew ztl_N!m?Im)2u)rj<^FbtA=NttcghAi>6-|K7YTc3FZ^zd3?4h*jpM!FL15f4A^jUX z6V}6XObq(ezMmukB*{M*sn(pMWQc!L-^w9fV#n9Ng7CLwSi2t>V90A&Jp7^k{eHP} zi(0xh^+^-_V(rI8I#ZlQtkcumed_qJ{*j)6fv%Cxfm5#x4<_iLW443B0pSvPBp^}= zUyoE1DSe`Ncyh9l#2#AY&dbw*s}WyL+Ca#k&rZITu$&R$4(VH(Hs^q{} zBZd)Nx>7Vo3Mq^((z2sWPYq3xVl4#f0yaV+RMP}daFPKTr_&c!@XRj>)}(JxN5H+n z?}7oO?}74(c9-tsU3xFO<)wc|jq{8qZ_I4+;!`ramwXHL3%?)#5qOl>t%53ZE%r?&Ymea&(>}xe~vX>S#>Gd!qQEf|h z!IU1RG+Pg&Uj`&}FCMZQly(6F6fYztghWy6d;Uy$qVyKgzAC4?CDk$QM0%QY6WSKx zh%6j=;QMgh($|y?+tm%*@iXhzs857rSCS945eLkcq(FhUNmIXACDOda`BUAm48Zk? zAKrH0g=pL_eL%rBe*ii!nz>muG%bvqjUSAaq(H*vy` zelpEl+^lsI9Id6%pDA+a%t9)OSsP&ER*f8fF+^4p7cVAi!XBE+1}=ced6V=2-@n4Y z&>ur*_7z5?SXl+!u<(}e^nI&OF5IW^`&E9w%NKACe2V;*O4LPlaz%`6iifN=13~y}?D#JLld#Cl|ho`_sYY(x0CF*;(xupu(S0 z`BO4~>KQp-RCu4t`()miLVHQ!M^%1Q=0}t1q;K}W*+18xig85YJ5|0@=9AT&&yKMM z+BSu6SNV3CZ%^Ubr0| zsi5r&zeDAB$o!5((0u5d18)w@4J3bN7x99^zoGJP$ov~A9KUf9cPV^_%6G_oM>4my zGyftvSz&7Wba;9D&qp6N{K>>;6Thfdb`GgKhY+lk467x>bH`JK8dCUSl^>S*;m5`0 z?}ZlkDHWU5ip@%KqgqT#J+f5-m^a0&4m!>vm+pOF0?=;7x=*$4liB_3vOTWc5Z$U& zwy2db(6gH=o)CD;Id7VuPGLUxpiC}3r`?M6ylOo!ThGUuwv#FF1_of*Hs7_dX>nt; zBIYc7yYF_NT(MPgHmS}g+1Zo|dij%e55kIfzv|sDSG=sK0C-i#>^v6DJerQs5994H5l`D>EcgibDD%QzQPd?nNwD+m) zDA7snR-FB+vtM@hCt@w!RGfn96l8WMYQ50*R^gq(`NHJS9dEhsxaZw(xxYwGLzr$p z-ML)+^UjCHKk5Cf_b;v}ZLg|ruOe6}KBX3)n(Iq7=Agn4sr-=44{43L_nmLN`wgXd zvsz3}U`+cM$Y{zvP#l)-(Qd`MSGDey+5PLAa*I;gtX9HOJ5N)dB_=tm-HP>`YCR`g z&&3+xCLrCE0&B`mDH{Hc8WNh)Y+Gl z2A}Dp$Q0rpmuV1j1tHo+*5#zWoPh=?Op|!x%9Q71o41TxMf1lNy+YBDAHPm!oQ+F_ z3R8r7Qgjhk`uo^TW_~|TmE}t6ZEeRNKSYVs#y(^aDB<7WZ(1IBQyqtz_O~wyWB|p! zKLVjUC*c+>y(`1s_99e=FzKPwjLbbBvkSuBkvxQwcSCIl91c#ybEqg>O!_%(y_hf* zdSxOIppE;*-tNO)7vUcgCOFt&-v~}m63S+n0j0fZP6s6aB$gy%x(He>O{@g80T-o- zu`n|=L58DOg~r5&x|RHDj!nW306aKicMdPC%`9%qt!tCsM1DXJNNn2%wcvHX*rIJ=8F}E9^U`Dx?n|(N&J;I53^0iTq&#Q(NH9Pl z3@;HD8*{?w3xsaK+bR5~q8~JeMuStR@nmouJ}}|eGU3;g9I>)mQ(hE?y$^Fd%IXdM zwPq~^2X_-;EXSy1k&@ov#iq3KK5 z%)`5A2x@0E=ns&ZnNee%7#5M59M-^36%ex}=1=MS9|PzQy}DS9M!;!K5a_Q!1Q1&dtOycAh(d&vKV_=`^YmDiLLud63sm#r6K?h<%hFqxll z0I;VqnPE?3GQ-lvQFf<=((><(E^bxIH>u^DmP||G2Nxc8eZEDu4kIOOS7NSW_(yag zJ-|OOVCO8Zw})>Jzjfx$nN~K{HHgtgvL>{!3s!n2p)-;IwSrpNZ2+IGuzO zK#$X8(v<(q27MHjOlVK(#Fz{dA+s^65Kq;sj~1IG955o zA;UIyW$GoaSdyWl>0`5gGo}AETVNwkCCsBV+;|ly(?R28xMEBGg4_}{$uJAyVO(tr zlTmi!!da6Hf7H3sC`3K{M+ zhsj_iaa}1)z9D^4@;&n@IzP_Rrt3>8y3F^&83X*4rPB+O zv1#I($>Nl;EbS+A!c_@+I@aXDV)A$XoAKa(jJdfLKn_S=LK+qY`lMNv9MmbU9^=0O>g4{pojoA79JBTZg?eOcI{N zHIrqd1kF^H?t9kQh40lfyvT_)nKEYNnKf1$I2#u}oXmyeu53uYW6bt^T$@c>aor$S z|3WEla5s(TxEluV`u>QCxz3LB*PvaAtV^!sux5indQeCyo5q-6pmA&=O$B;D;tN|SFbSk$%z#4Dj-AYz&hk2UW` zdaFMG7x7rY#*@gq66X&i6{&=pp>ZgYSSRkMsSyL2;ma#{AtO5o`?uxyjI1BDeo~(4 zw(Cl2BG1{FWLS(tNw6Kud8#>6k$hy7{u8ps@kG=M-g|>SG4zopvt*|AI;ka-7*`VQ z*HRIDjn-e?KnC+^j<11fZ4!J@SxdIQk-L$1X5O7ywIKYlr}Evt#jxUOP(2ONv#O_M z)tHRV5^4$rl3GW~Qqb7-49w;x*r#L-nB2bD@B4@ zBt&cB{%7fyTC@iQ%}mG$Iz+vKT>Rr)EID_A=3^vyl?j9+<{MHF$`k1zvW*lm1xixC zNJ>_Z0GVw@0Q(;;enlMz+~k@V4?sORqBRgZkKwJ0)5!^K`R_iQI79IY{bv# z$IzkS4xQ>2lKu+ill~h(9GelyoSFA|duVEMg8qLA9MPj8Qad36nLj7pAV7x!;$}Fr ze`OfX?KN`2LF83&LWMn7I)(D9-2`&sVp?aoBJ?Yr;PbndR3&e9Xn8xO~$F4Hf)u6aGsjf|PM`OJG z5nr*wS1ekV%H>^k{%*BqtK8Nl z*K{j2-728_sOmmC*Rxu%-P9Hps5uX5!!_Y(r}npsi*sG@bHqE+73 ztyCOUD~>{dRa$fJ<-0GZjzhSrVnvmYD{9`2L>nK~wXf8*FOSPOa$I**tvjkz^r#g* za_>2{;{1H?7d4w7)wHeDw8`x!m70FFrXN|9SK`!kVa=n$x|PB@?S$|uXL6OS79{5hYRp@;r46X=+iZHAS!>cC5d_qGaJSEkXELgBLgcGpiw~v3} z5me8{m`8Zz*|Or<@}NidY*9S>RnPv%9)X;PJo0Q^@oZh{RXjUY&rSqJD-!-iZKmRq zCq@f7^8~;lRu_muZzbIJws~U)A-k1^!;k8FR_c2`cPRBkYWJFM0YuW}9>5(1!> z)teqw?^vncA-5e@s!yoZC+3gGO4mOs-MCV^G37R!krMSzjz_hdAJuMOsolQZA=hqK zYCF~1&PTQVE4BSf?JH{SE2wuR3I%|ASGwnWakR!&L{jQl@jA7*E_&io!`_vKy$^fj zhP_I|3AN$G=a=Q8GdQ9_)dIi?iv+;d+*Wu8zNKnbtToZD2ko-8MzQWzt-EFG?#EWQ z=2QLtrl=}fnwePXjCA+u3cl}X?ccsGnNrUDD z4nepT>kierL$>Z&xwO^k@nlLE8ItcjJy;_iB zJ)>IB$ksEl!lGYV-FI9I<4Z$8mcoj6++Y2^dCgB>ef1Udfd8kB$K59jxnC4kp4@Dt z!{0RJj*Q^6F)e2^4xQ5!gizYnWFH#mwG&ep=@TtsSt|I$rEx`imjDeG(!V9Z1TBOs zBc?ecl*wTJNdG-?ES`?Sd)LJ+BO^Emr=3q9o2LJrWn@IcP{K(n0X7Q9=ol|NliOI0?zy-_ggvC-AofNG~a!C$O1769G16-=;Sjvo%#EX$Q4Q zf(>o|3P0oa!CMe4UhBR&5oQJw+UjBxK0USW*ACPll%C=z#y~E#5lbnYxH1@4`BDRq zbLjwEI77Y6)n(paaD{X1FUC3M*k6ou&#}K4=bB@GF|Jrn-mzr-FDy-Se9TfhcjL{O zgvJ+ zI#7AUV5nZ@a$sLUwE+$j_27`9!_cfD0ymLOXVyu#lRWZ9~e#^qp!q7XX-#x9^ SYgK!#%-4ced^Nr@Hu^uN`ty?j literal 0 HcmV?d00001 diff --git a/tools/__pycache__/update-gherkin-dialects.cpython-311.pyc b/tools/__pycache__/update-gherkin-dialects.cpython-311.pyc new file mode 100644 index 0000000000000000000000000000000000000000..5b2381123a4a81978f956935041bbe01bbd9aba9 GIT binary patch literal 9471 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 str: return "\n".join(out) +def clone_and_pin(ref: str, destination: pathlib.Path) -> str: + """Clone upstream at `ref` and return the last commit that touched `testdata/`. + + Pinning `HEAD` instead would re-pin on every unrelated upstream commit, and the drift + check (.github/workflows/upstream-drift.yml) would then report news every week the + fixtures had not moved. The clone is blobless rather than shallow because a shallow + one cannot answer a path-scoped log; trees are cheap and blobs arrive on checkout. + """ + subprocess.run( + ["git", "clone", "--filter=blob:none", "--branch", ref, "-q", REPO, str(destination)], + check=True, + ) + log = subprocess.run( + ["git", "-C", str(destination), "log", "-1", "--format=%H", "--", "testdata"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + if log: + return log + # No commit touches testdata/ -- upstream moved it, so fall back to naming the checkout. + return subprocess.run( + ["git", "-C", str(destination), "rev-parse", "HEAD"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--ref", default="main") @@ -183,14 +212,7 @@ def main() -> int: workdir = pathlib.Path(tempfile.mkdtemp(prefix="expression-corpus-")) try: checkout = workdir / "cucumber-expressions" - subprocess.run( - ["git", "clone", "--depth", "1", "--branch", args.ref, "-q", REPO, str(checkout)], - check=True, - ) - ref = subprocess.run( - ["git", "-C", str(checkout), "rev-parse", "HEAD"], - check=True, capture_output=True, text=True, - ).stdout.strip() + ref = clone_and_pin(args.ref, checkout) testdata = checkout / "testdata" families: dict[str, list[dict]] = {} diff --git a/tools/update-gherkin-corpus.py b/tools/update-gherkin-corpus.py index 4ee9665..ee97037 100644 --- a/tools/update-gherkin-corpus.py +++ b/tools/update-gherkin-corpus.py @@ -314,6 +314,35 @@ def render(good: list[tuple[str, str, str]], bad: list[tuple[str, str, list[str] return "\n".join(out) +def clone_and_pin(ref: str, destination: pathlib.Path) -> str: + """Clone upstream at `ref` and return the last commit that touched `testdata/`. + + Pinning `HEAD` instead would re-pin on every unrelated upstream commit, and the drift + check (.github/workflows/upstream-drift.yml) would then report news every week the + fixtures had not moved. The clone is blobless rather than shallow because a shallow + one cannot answer a path-scoped log; trees are cheap and blobs arrive on checkout. + """ + subprocess.run( + ["git", "clone", "--filter=blob:none", "--branch", ref, "-q", REPO, str(destination)], + check=True, + ) + log = subprocess.run( + ["git", "-C", str(destination), "log", "-1", "--format=%H", "--", "testdata"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + if log: + return log + # No commit touches testdata/ -- upstream moved it, so fall back to naming the checkout. + return subprocess.run( + ["git", "-C", str(destination), "rev-parse", "HEAD"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + # --------------------------------------------------------------------------- main @@ -324,17 +353,8 @@ def main() -> int: workdir = pathlib.Path(tempfile.mkdtemp(prefix="gherkin-corpus-")) try: - subprocess.run( - ["git", "clone", "--depth", "1", "--branch", args.ref, "-q", REPO, str(workdir / "gherkin")], - check=True, - ) checkout = workdir / "gherkin" - ref = subprocess.run( - ["git", "-C", str(checkout), "rev-parse", "HEAD"], - check=True, - capture_output=True, - text=True, - ).stdout.strip() + ref = clone_and_pin(args.ref, checkout) good: list[tuple[str, str, str, str]] = [] for feature_path in sorted((checkout / "testdata" / "good").glob("*.feature")): diff --git a/tools/update-tag-expression-corpus.py b/tools/update-tag-expression-corpus.py index 2c71bce..95ee84e 100644 --- a/tools/update-tag-expression-corpus.py +++ b/tools/update-tag-expression-corpus.py @@ -108,6 +108,35 @@ def render(parsing, evaluations, errors, ref: str) -> str: return "\n".join(out) +def clone_and_pin(ref: str, destination: pathlib.Path) -> str: + """Clone upstream at `ref` and return the last commit that touched `testdata/`. + + Pinning `HEAD` instead would re-pin on every unrelated upstream commit, and the drift + check (.github/workflows/upstream-drift.yml) would then report news every week the + fixtures had not moved. The clone is blobless rather than shallow because a shallow + one cannot answer a path-scoped log; trees are cheap and blobs arrive on checkout. + """ + subprocess.run( + ["git", "clone", "--filter=blob:none", "--branch", ref, "-q", REPO, str(destination)], + check=True, + ) + log = subprocess.run( + ["git", "-C", str(destination), "log", "-1", "--format=%H", "--", "testdata"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + if log: + return log + # No commit touches testdata/ -- upstream moved it, so fall back to naming the checkout. + return subprocess.run( + ["git", "-C", str(destination), "rev-parse", "HEAD"], + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + def main() -> int: parser = argparse.ArgumentParser() parser.add_argument("--ref", default="main") @@ -116,14 +145,7 @@ def main() -> int: workdir = pathlib.Path(tempfile.mkdtemp(prefix="tag-expression-corpus-")) try: checkout = workdir / "tag-expressions" - subprocess.run( - ["git", "clone", "--depth", "1", "--branch", args.ref, "-q", REPO, str(checkout)], - check=True, - ) - ref = subprocess.run( - ["git", "-C", str(checkout), "rev-parse", "HEAD"], - check=True, capture_output=True, text=True, - ).stdout.strip() + ref = clone_and_pin(args.ref, checkout) testdata = checkout / "testdata" parsing = yaml.safe_load((testdata / "parsing.yml").read_text(encoding="utf-8"))