From a91a8d6bc400dfec42214c2742be9787d099ca3f Mon Sep 17 00:00:00 2001 From: 3v0k4 Date: Thu, 6 Jun 2024 14:57:50 +0200 Subject: [PATCH] chore: knapsack to knapsack_pro --- .github/assets/knapsack-diamonds.png | Bin 0 -> 17632 bytes MIGRATE_TO_KNAPSACK_PRO.md | 77 +++++++++++++++++++ README.md | 60 ++++++++------- spec/knapsack/adapters/rspec_adapter_spec.rb | 2 + 4 files changed, 113 insertions(+), 26 deletions(-) create mode 100644 .github/assets/knapsack-diamonds.png create mode 100644 MIGRATE_TO_KNAPSACK_PRO.md diff --git a/.github/assets/knapsack-diamonds.png b/.github/assets/knapsack-diamonds.png new file mode 100644 index 0000000000000000000000000000000000000000..e9cce59be7560013515d89705923706a41f7deaa GIT binary patch literal 17632 zcmb@t^;=s_)HWIV5LyBxVwfFP1@2@DDJL-0!50uI{^a4rASJ#7I%k2 zfgmkb91hQW&bi({;QM~qSN7gBvu3jPnwfj8bx)+8jw%@m0|@{CAX8UUG5`Q@`2M?y z2=3o_`^UQ9{}4N=y>tZtK-B+TIDm{S`ump;-IQT&hK_IDJP|I|0QonLudG?r?Gf*+ z4XhDwyqyQEr2zmXdvzswBd__rY*4)Uru$Z>x6N|K!+b(qjuIr%y7gQ9etJS*f&}`7 zNRx#8X+3piOwYl5n={*BxoBpDXpcJ5s8@x;`6V%{%R(rId!c@+PHW_xx-OX zoG>DVXDp8sRBYag2*#*n+}t*GPWWH`^Z)ny^56b(O)ED2Am?Cu-#73qaM<(fu`xd% zANOZ94qigzA%O>xO1OOY4^;3-B{rOt`x|1k65D6BAWo`CeAxXBM;F!qU-Dm-&j3x1 z|F7h~D*yKz|F8W2>G^*L_dh-V@8JI5p8t1n|5NgR-Z%EjC@`MLkPu1U#RZ>py!WDhy6P^!4{!P?V(*FOECMca}1AALX#$ptOp=|A=0 zlzaV=fJ#05j|~AFgnu^*ojXo#Y{&+iSnl;4(qr36ymU0qWXE9SYM+d?sa9V~wW-k8 zZcrz<-ClZm`m6AZ&ggt~{*>TKc$qn;1gdvJfV>iXI#uCoooza&R|TCe?USi?&<^07 zI0j)W1$E1ITtOA(C4)Z8{gV>Awbbv1E2U3RnGM8v5XO#P4CKi+>(F;Ae$ z7cyBfoAVzznyvHqwVH2##)-TsnL7qF5nAQe=biqDlo&$Xcod8sI$GtXH96Fb|HZ7} zdaTF_E7mmOjS4$x9+?)@B_xURv7sLH`2X&a+`ZM`PgqS_3_8|j&Qh1(a;2LxTU!>Z zcBoyX4eL95?*ycTpT*dX2inPu1Q8o5-y2$gh_PTd3Hp3K{OwfB2X(A7$zk&Yl7OwM zoyk87Y0-6gy+nFU`FamVJcpc@yt=7Qt?~FbiXZ#gkGs5;$G5@p3SteVO*r&F`gz|dnGg~N zYuonh>OM&5x5m+96j_nTA_p!}VL3L6;}i0y~Ul+TXCTmV_*3u_m{}jFLJvm>9kW8IVJPb|v zL`RHX2SLOWI`ARl9AdD~$EJ21Tmi^KaYe`C0oL>g3`Lc!VW)mdi)R|NWFc9NJD# zb%gohzUEyh0IU?iiXJ=_uJGw0F=3uu*g6fz&M{;6GeKqxsvBiA@W{m}U9>{Ef*#B{ zqE}JgMVceb)9@|L82Mwnu){209=yk{X@G2M3U*u`bH>$wjT16rA=w=!j(761TlW4} z5e(*mToG@jIhPn*JWYa(Z3kmS?Z0p2=**TZH3x6a?s@OtKHG{uV_KyatXn z(cXC1yjoo>QdICuAPm=`CLLR2)gP3IU{D~&E4QRBA)qv$S&7=cpSua@%SZmM6gT8> z3GFXDMHQm287d}L*N9K27!>R>6FMij5ov#uc7siHj_-z`WR(eFp$tZ6JDDrBEj&|= zMH)*TB|0~!pWldg{2C+>mG-yX59o8YRYRMjV7PHX?6Fn+s)wtz<*NMbd7Gea5#vPQ;L{zQ9yMm3JsWnp zUKdNE!b^3M zqTKn%#1xf^zMs)`tiJ;rD~bzWN^MT z;b#9?p8H+r@S7L4zRFeD&inyf8f1jm!N1c}M%V)v1TIQAWfHN;;wt?58;Sb+%6!Yw zWuuo|3l(pIc@h>c6zslhG(HSWScS-9#^*mN83dYU!U9p|`F)sH^cp-#K|a%9R4IGT z^@ZkC3;({Ynd)!SkVHu({IrxCH}li4B2^5GvD>m8l7;b2y0Mlx&|(FH1ckLtCxpyK`5rXG$(c6t(1(^=bnvq}z}$kR!}b`dhvP)6l5b2^3YHmkJXv4bRZ zfp@9cDzifSC*^`vaAUrD15m~*OZY5Rgf^-W11fa^fxK^d%P>(k+-aM2@evGCnPf+Q zELPsMRM%A3m_V@O8yT;W*HxDxLHf#{goN!=+3yW~U=(XoA`s1hMF!L6V){yV!$=6V zZ%LLOhiK)5v%k(?)l*U|HhOH=#W6ytQ`Eiq+I+&wa;8k@+9z}VZin{fZsfZ2ZUgfL zJAIP~ZRYN}w|3!tcUgH*M|n?}XObV`woX{)Zt5C3BrNpb*F$|0U^Zila`o9w_SW`d z2*ZoS#Vt+IdO>(Ks4!g1UXt%x&}EVY&C6uEEz-Im=`G?`2C`v+*LsLt#YSj;#d8v= z5mFQHzxr;s{|Os4TGnSUa1@?|VGwaQ$+l02f4|u%&?CG1sgB*Cc>-EHx8w?SuAn%@~n%gKr)^I&EDXsC6CONSvG-;?nn1JXE2m0%Gt%ao0 zp0He-wRe>dTrt#iAR{ho+TRPnC|cTV>C|pHeirZ9pKyO)?_TO7;N$bam5k(GwYVEu~&5MmmOVTdN97s1d)*H5GxAO7 z#Y60FtxSAlzz4;9>r-U5(d0J=h!#HT6!z;~QDVP)bhUw3g#f=Ip(w%XX+z^TeB+h5 z^nMO2bYBgz(zv<69)7ci&)?6prI91pTdS2q)+zS2T!1FcV^a~NDrJ3EN_m9d$pA*7 zlTyWpNpAS7$cqjFSKBMC9p#sisbWPRzwxeEi6=jmJN!s|ce&Y54Uaqug;r?pG%csO zFcFhJGmfA-Flm~)M27sbrYG@f<;w)r$1oTza9-b6CBdr-0K-Wr7^g{orL>n|0ctc@ zcabUa@Q@GrQ8LsyDV2+tFa*AHCGj1>Cij00D5|pY`I~s8H|p-Izu{Q4Cx?*d=kfF5 zf7+A6y{gr0{YZjV>P13xkJ5Xn-&72vHM?zoD9Bfr{@hpZsG7*bCjQk8;xuKnIpvMx zk(MvP#$)Q@$iMT^YzXYmoIs14z&?*s3h!~Ash& zT0dE6Uh>yVdukv}*5=5h-`)SNpOgaF)PDfJN2^G;moE*yMu};TGAa_ssOH4^x?+(b z`uomcsr=2l<%5|8D{PhGzmI@Qs=O&X^UqVnNk>ozLwD{q9Xqyy>oqvTE8P@Z%1M$C zqtxZbU3?Nh5BxLYX8il@6FMD280c;`fcKQ>`?LEMBF<$ZGpDSN|R=GPR8|W1t5t3jtf>C}d zw>JG0wcs~KWry>LpN@;psW;=}gABp~W;)ZwJmwj%-x{*#xOZ}B)GMSj=T@`kMl#ciIY6`x5e4-4l&4b*_!hi`XY2 zHUiDNe;-OU|Gn|k4Bgdz^9O`pC#aI~|AHqgIAwA)@w=-}T5<9%>&u?6FNlGzc(gVX z+nWVmQg7QvLqRb>O7hqn6|?DI0F#yOm%fVfxHEJj%>k?{ApnTZC|0$8?O22_gx79= zlK}OJ8n7zAHJ$^$t)#$F`R6ox+Z;W#E{STg#4!;X;6{AwE&ba}v_x|GMt2hxxYh~a zgL#3Mv^_f7h!tr)2%=URw00v=Mp%Sb}UmA>Gf@ zX?wdEK04%GUX+?n1})p{JROWcxKW<{awZU{Sfg?xM!&+T(#6`hR=1MW4km?#0QE`E ziEv~C*Qid{wiYHm#hzR9O}8$fzK7yV!h13D%}>Sj=3Ei=T@ZfR@IGR5zBe3B11wS6 z32t=8|A_y7gW<*!$jV;Vsx;gjU4H8OEOhs$X1MGnEtn18yvkxWf8d86WgfPzqWc+w zVwJT9n0*=3NXo4sf>l$HV!BBAhKN+c#}5me*2^`lw!OOa5&hC);eQk5V{A7X%pn;8 zRw0U8T*hvf?J4lndAdD>>b417%}1w^bF3r)K!iQ1S~+kA#RVU!(k2;0HSP*NGD)1U z-F!QSsX6|A>_LP3po2FcBY5mW&heXFt2hhg+a3!EwIJj2u5qEuXV3gT4bA>~qC49E z4;Up90W?o0M)~999b+D4PI9HbYvumIq}1R$Gg0c_os5GjKYp0ck}S(2vXoU_Mh7=0 zK?@CrJUsTf>Y^c%$xFcWm9r1$KQD<1){J@zQN-v}_i5MYaAea{owSSKfLaX5Qt6r{ zwb!$ALfdJ(sqz#a$4t35sKe-A!*>MFXgglyHyQqxYd3MMeD<-vXs|Vk^-s_|Jry}E zfl$ycqMmBZtcH>I&=V#fgzOt2zL~GsAX*u<*ED>)p5B4Y@hVWF?L>bewL z|J(4lzEs(clsp+(pTMsy<7x_zeq&_l^Dy8KpfCJUKW$qU({<_3u@*LI`+);w} zAcd&~XL03cwG%#n-S$I4+ni2`i5#nfCT6t&NRGe|9qf0(^uGRArt7VC3V%%Vcg!;9LP z@1tfzYt*vvix`^mUmju`MORerP-kx2=6h!%Hp-;eYQeP7!(wLp{7g+By_mL9`)VD1 zxgD`$ni)m~z_&S#`_W=i#dqem+F1OuFf8{XRekDq!nxtJg=e>m!TIZY!P3@im-BBF zFiU~xtr{eIpeLkmXR@CAauA?8lIz+@G3DkzG# ziK6C2;H#DNV-N_kY@OVO(P)8eR08OD8Gp^}shNz89t|U%e%NRV)Z@dA1h`%Hiq2U0h(z+&=EC?o>yG+^%`iYfE<6$^A-O zLvJ9jOv8-Rnm>$&rHl8qXR_%4zPhGl&;xA4+>@mB8B15NVjTOY2S*LfzQiL%>X~;+BEUr z3Dnc);?z$V-9o^Q#h;?tY?~LObe~%Hr3hBqq#B#WGS4T`z<&OGfQxG&-am>%$NZ@Lhm71B~ZhFwLB*1`J*ONh?xH2j#!O@-qaj8(5x4c99Nfets;Z{ zB{_LDXnl&+Of6Eym#wM^Gt*um=UCDgVu03<25IOleKa4MugKQ@x1AX_r)L}NQ_ziM z$}HYvD-ud8SkfHSKP2v#2dQMkk-vtQUrwfGF{E+-oXfVr27!z2EQ5??e5@Spc2a#M zv6Cz2e?BxgcjXi8swd8bn7L%&uDOq*ue+DaCN1BqacaTZk!{)wuHm29_vpNkRR7Gl zMqVE3D|TLkdz$^=$g^J4aPlt@)aK&JQ`ne5C!=D|?#Vx*o1@wOEO+Hct}n}|yzzKl zySha@o_jgrxKWmyN@$H>XTSOsIX%eUu`q9Ff{J`o`M)d@(2)gtD==VQk}OX!!a1+j`5RQ|B3W z_rT44G?BTl_VRD_5XvKC9f69}hV<^KA-ecpwq;Pz$oy~p%W|N*Gs>hP^*iby2@}GU`czPOcbTFtI zXKnbwoVQkYxACX2aw&h4=iEM7vcEZg_Y@fUPQC1!c_?%tr2o4%>0n;SUFKQfl;tlH zh&icupWc=7gA1Ok!O`Dd9eo?69s^;QBsjE8Ha-~Q=EMVx@u#z?@6w7Dg~8OWX54w7 z>}pnp&(iIc@{+%V6N$9XJ@$loz`9?~aVh;04_Q!UTT00-Q1VIT7>CfnNX`Al>9@mr zgF`~YE2g{~YRzzEuni^x^Y4)~QqRxQ_`AQtfJcBg zoAx5z7D!1s#%I*oEP|{fXvqo0Ba9Rt6H+`$Sm$lVu#059=zK6R4`F^$fHU>3rfIx$ zB7puVc-nH{y|qnRY+Rs>Ozv8>)0$$zA~_^i=~5?Ir-)+c01TIqkES{*KOzhwasc%P z*0&P(sN|HMJ3VKAXeHpWg)pi|^Id*&+OEe+5JntJg)xoH|&OtptY zwd0Rl(NkuNK(OB44ZNXX?JCVYz`QY%X${32NqHx?Z(O9n`RRZs;#*s|fpJi$z1VPf zCEqKqEYsdxnt@-NM4fTWg8U3n3agp2fV@D@ZJam|Mqogj7)|2Lvi@dKzEg0DaCzqf zc$O%ZP7zIocB1;=>SdEn@Y5-%Gvb$D&(`~<486MX{7o-7+~vml=M?tm04nFDTG5%h zgN8znLU<%#ROR(d2OK=*G+Gsp<{G^V?EBsE`x|f5ohQ#mbFNeWESxja4F{^9k4$_V zxvknxKK=1G^Y<>|*vi+RWtZb|=7NaJ z!$tcE2G7&ZnfzU~m?`d5hacQK`JOg71WZoKcF-!lRFr8olz%98RgcOIi!w0WN_ga! zrEUEv)5P|m{mggD7&2wKd+qD0{rfky23dxEUKZ<<3IIHvv+?3#vd|-wxP4Eqh@i!Z zI*q$=fvW>o+3~#AUsPlefi9v)a!ProT9nNx{OZfNAI|5By}RR`Ujfo+s-iR~_{b^@ zpX-4Yc6mkTywASSp6gHL@CLmQE}Zmzmymbls##1WPYN(IPF-XS6UGg)t09<0XJr&9 z15?7M%r4*h$8SlxyL?;Z*GhNZw(pn{`BNzZJLNGviPHNsnq=Upqe^EGfLjl!)xcbz7IMma%ken#r$7%z=O1@mqbD78p z7is@+f%Yf092czUG5#ybM^=d=*)p2&Yb}oRs$BP{U|GbnG&K=4?P3_=?pP2j7-Fh_ zlPQ9-EWL?b3Ql~;5iKvp7u(vT}Lzxv{m@>ZrK&`^DR;@Fu zCz6_}$=TJs$USD@C++iszYV%Q%FZxg1USstu55y<%X&BU00jBy?z@M|`?Fp*=YaTOE*(JrzapJ>@e-2DV{uJG^vKx2?#+mOsGlao&?nc4H2r z@!&F_wx{E05|u&p{@f-peH-^OHo=6ZD`W$n9~^bFP5ulQ{YsMkS|{(nlfaqdICuoJw*gWALUQq+r8%xMc46)( zrScIIsb~2Psag}-_aieux za8O=V;AzAosoh+PFS;#rqY2kU{n{7&%#M)IkNoJ9oR+Hiu7a5g4x6WREs81>kOwfo zL9*^a7rh^+;w^jvr95IIr}r?c!xiM2 zyaiODr+YCEi7y)VSv2>%uQh*I55Z;jrNStr)E5ZQ#9(DMg*U^^DI_?=A~r=g3FckK z5{v{$TTmU3FZli~FX5sVm0r|4{fs>BXN^h85W13=Sb|^>OX{*+IQ#y0D2UQx5b)h5 z0ffq&7U}Es(&0jgS3y)Lrf`T?63ycBk_hx`uMY68nJ;W^z3$#a9XYh}`1;fi>_m>{ zZ0(@>^N&aD?hoyjrlbaKV@-{2N9+Rr`vsb8*khzYaQrkQ`>Nm%+0R3n z{sC*AJJE;APXSO3n#*qfr3yu97X^pNvphowHE!R$YH~nf;_ELz4L_N!ci25$1V<)} zJL`N+91@-x(|P!m&k@PX*xN2E&fJCXv+?&KWJO8cl_=6v4miRN%a2QBMtRu~(Hq!& z%u1&gS4}94be1|tISHj=|CxuK$>($aUd!JN{WF<8@U(dO@lk+IOh7HfQDd3b6jQ?^ z`V@PU)$l0Ev~ix&^evX$JS8mrsRyhcR+0>l04dm|>Ch6?H43Icuz_4Jx*xtQXZ~PI zE^R@GR!o#7%71ewHRr+p-O$a4b^wdGp0U)6kaiNVpwAEOwN(9nuV=_(o%n9F)tB!h=M zA4q!BcheFAs!{e9zS^*%4gU^=y(o5pSEKX_W{b59S;fF~X7t7nNzP;vKUanpW@b2m?izZqv~{l4l}vJ1Y6W!F&#GZ7fq z+=1B3_gSZl4BD%w!-!i(OJaaTru-{_!)pZe{y1v(Dx4QwzeA ze`uE+&*)*u2z}oar7xV7lmq6i-NJ+4ob^Pt50!33w+YkWBvD=no%SVgh8Zf`5@kkU z>RM*&JYSLvV2P8>o1Ow$vs|VB42|;`6TDR&1e)iQs7j!EwEh#a*YI*zc%_Dmyo*=) zmKVJI$g_#h2CR|8N#M<+_So(%Z%P*lw!kSk@cebmbb)~Qmd@uYk-|%uR8saA{OTrc zNcjj0F2Kmfx$0!a2#W3x_rIn{#RXAs{Y z*qr9=N9n`Jw^?7NFG>3E*4w+ezorkq&GwxRG;ia(lCbe|stL&bq7O95v;KM#VZ|b8 zNS|g0Zc7xpA&6%{EUDnI14yJgUXVTcI+@y<-=WeW0=*pySh_*E7w?^4{VKMQji(2WQeda1uI%dr~X7RRlEhlrKvS7P_RI4e?tWS?DpJ|*^ zEpFCCe@j6r#JlqWqe)LUe3kLr@%LvjxK!T*^G2#Htcm#!m_fiw^r`|5k9Mr3zDco) zwspsHxv@1V3dqPMD+8S$k+-`-zHB${s2jO*4s)2fc3G3^hjE`qGK-4e5byB_CNUPfOJT6nn9$KL*5Gsb7MW21Txg2;5UI6^Q3HD66otjgm&5ag~35h zmQT?2MdmwHOqnk2glWn$%b53qwmP)kL$7g5v=&@=#m)`-6liBry>fz_O}n#UQmw7O=?6Pt}~0&KZriF?K_Pw z!`-#$sB-rK2(7VZtz3rKKleHe_iH!8IdgTo8QcAW?MUZn=6>ucet4F`il$@A)Q$PM+;v3H^X5v*V3=`>s%k4;5XEB3jI#!3>sn1yh4mvDs&5F) zI}5r+sd(T!6mI1^xjAs!+M&%Yotl{*o!P!8!pFIuU)Qe1X6I7HOe$%AwqOjmrrM7K zu2IXEgHwp)I-AJ=Hg*nFCAm1@0lv~R!`=&Y0Ag+KrIq*(#q1;G9N?6saUq zKh0^B%*e@)i286=&w~&i1QInL*D0?w!$_>H4gYXI0za`;%pglbpgcp zML1tb196>j7!bWP%1$7{8#(1X%=$BN3TN3P8?`C=FWu3)(d5!5PCO<+I2yylec*9Rf5ePW^Vzc%wSM)I=lwVk6`_J7=LVgj*UNQtPn(~Cf>mpBmBezI_UMr3&qtaGD=_i@)XB-XQkb^KsDms|Cd_0b^|OyrSdTn8%GjOtwv3ep9kpKP zH_d$<^sr5jL!)`f@O?^m?GFeYR7JL}*y2AXiE$=~C>Rt&=w&#>2d_O<)F;5v>n5x6 zwPnMDa%XmlWXn%j_i9VWJ(tc-U)Yuh zXiti;i^fH3Im}Yx7co278aM`)Oof2f;JG|`9(Z)jO!dE)TZ2gQv+Z}Jw;&MTSSFN* z)0}Pds4Y;`oDd)O6bG85puq6(14Sm^U)PsgQA*aGXQwvK)XD4meMFXUed}E)AV~#WYzOd^Yl z@o<0>bU0Kz`tg0}g`SMdiR@<3ppuY@nAo|QJIr6!3C2M2SFXWNAWws`Z&KF>XJ}w^ z&XDDvOF|yPTR&ooTK$ex`AwklWI zYvq1-GL(IL0SUr>OdqFy+ZaiQ4haIsj^zIp`6F|QiyANA(7qzUqEpT{5~7UfSLtX8 z2(5YA;>brSLVvB1e>6*(sqmCpsQCB6c92)d!qm(<`58^YtDK$=7Pz&jDO4ROxbO0Rvx_&Is@4S-phK9!lQ4Ajh=&wvpf4O@t>N>n0kk_bP~?+Lzj$$4Q@zuB+iJ^zXC`9?Wnq zH*u?Klq$m0fyd}x4sZ7Jd4+@{PuN#>q_PWaszIVt@DUH6`}FtYVGC)DKH9mibLew-r;RKg0!yshK@E^7aA3tU0j44A$^X zqr-zt46gw{6agJoSL#M=0{MP9wOU|NUWYr{L*pjwxOBG7*UOn*iVjgF*RW}I45_+D zslIwxV)jm5R2D`72l_qMbo>D_A!abK;ym#!<^@3i)#6h zarUI1ir|NAn6mfsJ^uO2|7C;kTrADewef6}$9=-!;52l2EliGNOuMK$+~_ikySfnQ_m@%F%QWh)CtqFO`ENXdo` z$|x0U8Lrl?5=O(1637;gMGR4IDOW&;w!O{3x84<|7nz2KJfY^>_bP8Vult(!i_%KC z&}I!gM}>SV@F#kGmh9)}`BQd;qC!o`m;!Nce#Darlb5CI6M4CFw6y=eF~B5?E}wPy z=QVAW1HLc@gY$*HQNw<>0pivZ(8J)Hc{FB(6s8(Lzl3F#Q20tke= z5{tW>BYHEgO&;r;IX^k`T%__K+1=LK|LC=t4eVy>vTt>=_TOj}O$x9O zu!$SM#BhWJPt%ihCou8n9mLH@U-)(YcQ@Z@Z$SWv>!4!cgrzQ*ubw=%XxQq)#2H5N~*Z+DHjrO6G zb5C9VJMb^_THAJnjqY?IQsuNIdVGoa?mUAQLds#|ALymxzdM?gk)zw!37HTw;2M4t zP!6DDOs8nRJWY8J0k%A6u*^|wO)AxSa%}!5Tm5${01XbvU*9WA1}OqxG@=XRiIfjL zo!n;{IhY=+TpcuzUi}%)N_VgFmwH@_jz5C2%XAI)TQzLak>dt^km(lvbH_ZDOZQ?R@pE20M?Z>w)~&*HeeYr(iOc zYYRfD!HCn%1i(AGWx|E8)UH_7Kf@Jc9E*Tz``MGNtD1XwddD2?#q#6>m)c9v8cm}j zpZSN3!@IW3`GV8Ct}{dl3o9SvJx7e2&&^d=Ixsm7!}}a%u!f8s7`vchSuR>1m^FY?QSWhO;JZq7`C^5s&B?sgUlO^j-kg=AzEgcbM)-Z;-i@Y4aUqH<2BA z-uC(Z-M5V=iL7r&*$^BqW5HmPHM^|3?&j)7XhTzDS#6}cs93Iacf4$mNe|cgLg1OR z0u)A8YTL2ZaxH+%rxd60*iQU3G-8M?V(N3>d?-F-d8UFMy)Fq~9)j)#Nm&V|V}uWE z+miL3F_Y``k)vj~em`UU{G$CToSgD=AMS^Kdw+jyy`5UxVDQfDCeZ()@3^+b=Iv*S zZ!ify)$Eb>phdTR0{4LmFt+1Yq3zwO9S>ajCl7=Dr=G2DwS139PePmsr{!{hh0$aX zj(Pp%)d$#v@0iQG8x0=Cp8Y4+24XfQ_%>Zj0BJ^3eCkgJ?#&z`@xMa8gkVA{*9G2x zgN}yH;L&HZ0G%4K5X$K6&M*Caub_`CH>}Foaa#z;Mg5E<^ZT`x^gXMd%c3l+A2aK$ zbiPry|8D<~4r&1#BF4G#Vp zKAjTWc}Ved{2zsMyr8pRh3UsVxB8t=x{xy=pf8HH#)=J>-;N~RXNt+7RJk$I2NtNp zxP)sD&)(g1uRFKSMuAP-COk(*Xw!;csCyCVyFBjJK`VSNcc&h2fhwW@W*A%_HfJ_SLV}nCU&#w4y^#q)x z+mfA$57@-Wt{pXeF6U-Au&<{Q%Jggd2ad$<7Ka|#DV*Bl~@NB@172dd7> z3cu6-S^NH5bNQ{GW#?*_unz7f9+vmny6OdwhEL*JIoL~J9mr=4|T8bcwBwJ0e7~|q@avjjjCorkb%G{uv zYYj-IF2Yt+8kNdm0&doQ8W8V~Udx`F{%u!_#K;fEh_|L2gjtBoXD`#Cd-|>UtohHT z4tDC;QoK~fr|cb{Q8!|2^5M#nZmHKsor6z5TT;OBc#$1m&OT zHJL5En3_ycM99!s@@Rz~7aLJ((8Z6}pKR7&Jc9i`W6|^h<3gR>oQ!k>oTiD5yt&3T zH_?7eVEkqPEJ9}lA_DcAftDW-@(5sm2r&R)oaBU6zj_}hj5$+t!oh4>%5_rx{z&N8 zKaaY~ApAvHs-MTY(QI<*_o$#lc)n_hgrDGT5ZdlVRgaO09N0qKE8A`P7qjwCyw3 z^N=o*nm9_?IHgO0n{eE}KO_!6dIiByi z-FiB<4^bnZ6L`N#muPp_Qr^+Eqb6#x(sVEX#PI%WifGUELPRW6Ra2<)A6B1pY*P=Y zkIJW<)L}@52L;_u)Qb!QDkiVk1L1Q^UZWitWlv7M$hr>VhXJUb*Pkbb$rMGC?hM z_(&p8dOct_CwNq=gj~YE9$ih+3pCf#oz6uGQCgFi!8;E_R#{mcHwaa?Hby^8xN9V< z?bqQ!Du_K@43s0bi)1KFP?3yi*m{Sma_N+o7*4d{jy1($ylaokkvtq+taMp`quB<@ z`uOstwxHS^(mR}jG`le`KNNz8vB^}CubbE_-(*a(zy(rF@;Gf2wcUq4XosTGEPSZlWb>L{C9mm z&~gkKs-m0VTB|`-n{-63x+V&hKhyywCh*%Z>8VkhbE6 z*Jt=a_HTtJkIWHny~U|T0pxgm|Cl)0j*^Rd#sj52pxSA}ZPJ08g!h!baSZn#+5rY= z-1x|Bs^ELMb{R^CSL$s%}068MEx4!wCJeu-v^s8ERPn>z`UG2SsqY&j}I8w_)V5 zYE07E2c!2Kmud2_!ug}cqz0pQ`$>wtR@F{gxhcA0{mukHba160bCWy!BhGI&g%ea( z<`309BZdnpi3t<84i!9Zd81hKt;)7{i9(+&sTZn(j&VTEe)Ly5Yz_YF_1q5aL|4^79GF=d)t#Ra~SC3#rJ*O+BU8hMAyALA`Av zvrM!&m8-FTCu{%4yN>@b`d;%NVPd9Qx6E1-!*x362?oQ-{#u34F7|BRFZ;fjm;Xt3 zoQ%gtUY1!61aEFNqKez37irBWW~x8vM1)6_y87JRuYMK|Ed>R1?*tlMfFrd%r3MZ= zttxnxnE9TlZb_Gp+C52$RLPHn&p$sVhD$W_L&#Nwxi8y%QEy&P8IG-2IKiAu5eRUx z)967FZI$>l)rie$&tl*xa-3d0*PsU$hM48d83TkwoXdwrskrG7p;7<$g+yKc^W3NQfP-QP}izbjC7ii#~W>LS@~)Wgah zF<93lL-n0atev}j!7&6LuxExBf$?K!Bnd$)qqX1XU5xQdw?Ar-q4FF+kqXNuUzz~Ip>NOd9fjMzBPFnWxaDdD#WsX{n zyl*d!W<=+#$!)$ciip&24#z*jwD+P~qFK%6l)Am-*qkcv0OBG=B+Q-~ z4`z|V7$ha)GTHJYSV6IKhCD&4(vGOZ3U)5TUG@OJx!EX9v*R>sznR4i7~yvc` zf?-tT8fx4juH4;~v zk9qF-53+04#v<7@rw6{6`c#Z0m}ii#HO=0Us-js z1W{T!N=QDw;y1z(;2ymzBUV4C_>09rx97_%6#oYPpDmx3dT>>I-<=m;MG;4@@8Da1 ztDtB{Yj}YX$9^+C-+4A1$2D@CIa%b~Z%p&<7WZ10pW(N@&Ur&o)n4scT8Cp9PrX@W zka)Ja#D>rrAV zl32TVmWIWW7;ZmCtu6eYSFK)DAb7qzd6TTcvF``2Mb@}9XYH0*^mOqm@D3~2Yrq{= z4`1Ew{GfOJ6DyPG9O1^(-Yo8S*d*UFO9ZAdmIDWoJ~D|pu!bKkYAOi5t;!!?Meg8v#u*!b;)1<@nP)Kd!?xx+{+-qbUT4S#AUA`Em!sq?u;ig?a6&YWH z9Q!zauF^Qb_*A4Iry!{z)3Ws&mM?j#%Wgp+X^@(rpydp2xsXSn&f zYIj8b>Mzr#{#}@9R}*_E#^G4_tVRx(0zXFeqGZ*pj+=Qqnt=you+&8N6d%48xu~Df zfLHoD%W)Hp0?@e`jttk5=SbgQ5Oe+9t>blS9K4s+dOv~>st6IB#8wAAR)a<-SAb9J gc(U%l{s9J#{=AnAq6t~R(@7XSUHx3vIVCg!0D7clI{*Lx literal 0 HcmV?d00001 diff --git a/MIGRATE_TO_KNAPSACK_PRO.md b/MIGRATE_TO_KNAPSACK_PRO.md new file mode 100644 index 0000000..d811689 --- /dev/null +++ b/MIGRATE_TO_KNAPSACK_PRO.md @@ -0,0 +1,77 @@ +# Migration steps: from Knapsack to Knapsack Pro + +Follow these steps to migrate from `knapsack` to `knapsack_pro` in 10 minutes. + +Commands are provided to help you with each step. + +On Linux, you need to remove the `''` part from the `sed` commands. Also, you can ignore the `sed: no input files` warning that is printed when there's no substitution to perform. + +## Steps + +- [ ] Remove the `knapsack` gem: + ```bash + bundle remove knapsack + ``` + +- [ ] Remove `Knapsack.load_tasks` from the `Rakefile` if present: + ```bash + sed -i '' '/Knapsack\.load_tasks/d' Rakefile + ``` + +- [ ] Replace `require "knapsack"` with `require "knapsack_pro"`: + ```bash + grep --files-with-matches --recursive "require.*knapsack" . | xargs sed -i '' "s/'knapsack'/'knapsack_pro'/g" + grep --files-with-matches --recursive "require.*knapsack" . | xargs sed -i '' 's/"knapsack"/"knapsack_pro"/g' + ``` + +- [ ] Remove the following code from the test runner configuration: + ```diff + - Knapsack.tracker.config({ + - enable_time_offset_warning: true, + - time_offset_in_seconds: 30 + - }) + + - Knapsack.report.config({ + - test_file_pattern: 'spec/**{,/*/**}/*_spec.rb', # ⬅️ Take note of this one for later + - report_path: 'knapsack_custom_report.json' + - }) + ``` + +- [ ] Replace `Knapsack` with `KnapsackPro`: + ```bash + grep --files-with-matches --recursive "Knapsack\." . | xargs sed -i '' 's/Knapsack\./KnapsackPro./g' + grep --files-with-matches --recursive "Knapsack::" . | xargs sed -i '' 's/Knapsack::/KnapsackPro::/g' + ``` + +- [ ] Rename `KnapsackPro::Adapters::RspecAdapter` to `KnapsackPro::Adapters::RSpecAdapter`: + ```bash + grep --files-with-matches --recursive "KnapsackPro::Adapters::RspecAdapter" . | xargs sed -i '' 's/RspecAdapter/RSpecAdapter/g' + ``` + +- [ ] Remove any line that mentions `KNAPSACK_GENERATE_REPORT` or `KNAPSACK_REPORT_PATH`: + ```bash + grep --files-with-matches --recursive "KNAPSACK_GENERATE_REPORT" . | xargs sed -i '' '/KNAPSACK_GENERATE_REPORT/d' + grep --files-with-matches --recursive "KNAPSACK_REPORT_PATH" . | xargs sed -i '' '/KNAPSACK_REPORT_PATH/d' + ``` + +- [ ] Rename ENVs from `KNAPSACK_X` to `KNAPSACK_PRO_X`: + ```bash + grep --files-with-matches --recursive "KNAPSACK_" . | xargs sed -i '' 's/KNAPSACK_/KNAPSACK_PRO_/g' + ``` + +- [ ] Remove all the reports: + ```bash + rm knapsack_*_report.json + ``` + +- [ ] [Configure Knapsack Pro](https://docs.knapsackpro.com/knapsack_pro-ruby/guide/) + +- [ ] Ensure all the CI commands are updated: + ```bash + grep --files-with-matches --recursive "knapsack:spinach" . | xargs sed -i '' 's/knapsack:spinach/knapsack_pro:spinach/g' + grep --files-with-matches --recursive "knapsack:" . | xargs sed -i '' 's/knapsack:/knapsack_pro:queue:/g' + grep --files-with-matches --recursive "CI_NODE_TOTAL" . | xargs sed -i '' 's/CI_NODE_TOTAL/KNAPSACK_PRO_CI_NODE_TOTAL/g' + grep --files-with-matches --recursive "CI_NODE_INDEX" . | xargs sed -i '' 's/CI_NODE_INDEX/KNAPSACK_PRO_CI_NODE_INDEX/g' + ``` + +- [ ] If you removed `test_file_pattern` when deleting `Knapsack.report.config`, use [`KNAPSACK_PRO_TEST_FILE_PATTERN`](https://docs.knapsackpro.com/ruby/reference/#knapsack_pro_test_file_pattern) instead diff --git a/README.md b/README.md index 96ca099..2b84e70 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,44 @@ -# knapsack gem +# Knapsack -Knapsack splits tests evenly across parallel CI nodes to run fast CI build and save you time. +

+ + Knapsack + +

-| | knapsack gem | knapsack_pro gem | -| -------------------------------------------- | ------------ | ---------------- | -| __Is free__ | ✓ Yes | ✓ Yes, [free plan](https://knapsackpro.com?utm_source=github&utm_medium=readme&utm_campaign=knapsack_gem&utm_content=free_plan) | -| __Regular Mode - a static tests split__ | ✓ Yes | ✓ Yes | -| __Queue Mode - a dynamic tests split__
([ensures all CI nodes finish work at the same time](https://docs.knapsackpro.com/2020/how-to-speed-up-ruby-and-javascript-tests-with-ci-parallelisation)) | No | ✓ Yes | -| __Auto [split slow RSpec test file](https://knapsackpro.com/faq/question/how-to-split-slow-rspec-test-files-by-test-examples-by-individual-it) between parallel CI nodes__
(a single test file can be auto split by test examples between parallel jobs) | No | ✓ Yes | -| Tracking tests timing per commit, branch | No | ✓ Yes | -| Support for other programming languages | No | ✓ Yes | -| Support for CI providers | limited | ✓ Yes | -| __Installation README__ | [Install README](http://docs.knapsackpro.com/ruby/knapsack) | [Install README](https://docs.knapsackpro.com) | +

Speed up your tests

+

Run your 1-hour test suite in 2 minutes with optimal parallelisation on your existing CI infrastructure

-[Features of knapsack vs knapsack_pro Ruby gem](https://knapsackpro.com/features/ruby_knapsack_pro_vs_knapsack?utm_source=github&utm_medium=readme&utm_campaign=knapsack_gem&utm_content=ruby_knapsack_pro_vs_knapsack) +--- -# Do you use Heroku? + -Do you know Knapsack Pro Ruby gem is available as Heroku add-on? It works with your current CI server. -https://elements.heroku.com/addons/knapsack-pro +
+
-Knapsack Pro has Queue Mode that will split Ruby & JS tests in a dynamic way across parallel CI nodes to ensure each parallel job takes a similar time. Thanks to that there is no bottleneck in your CI pipelines. +Knapsack wraps your current test runner and works with your existing CI infrastructure to split tests optimally. -__See introduction how the Knapsack Pro add-on works__ -https://youtu.be/rmXES2N0_QU +It comes in two flavors, `knapsack` and `knapsack_pro`: -You may also find useful article how to run parallel dynos on Heroku CI to complete tests faster -https://docs.knapsackpro.com/2019/how-to-run-tests-faster-on-heroku-ci-with-parallel-dynos +| | `knapsack` | `knapsack_pro` | +| ------------------------------- | ---------- | --------------------------------------- | +| Free | ✅ | ✅ [Free plan](https://knapsackpro.com?utm_source=github&utm_medium=readme&utm_campaign=knapsack_gem&utm_content=free_plan) | +| Static split | ✅ | ✅ | +| [Dynamic split](https://docs.knapsackpro.com/overview/#queue-mode-dynamic-split) | ❌ | ✅ | +| [Split by test examples](https://docs.knapsackpro.com/ruby/split-by-test-examples/) | ❌ | ✅ | +| Graphs, metrics, and stats | ❌ | ✅ | +| Programming languages | 🤞 (Ruby) | ✅ (Ruby, Cypress, Jest, SDK/API) | +| CI providers | 🤞 Limited | ✅ (All) | +| [Heroku add-on](https://elements.heroku.com/addons/knapsack-pro) | ❌ | ✅ | +| Additional features | ❌ | 🤘 ([Overview](https://docs.knapsackpro.com/overview/)) | +| | [Install](http://docs.knapsackpro.com/ruby/knapsack) | [Install](https://docs.knapsackpro.com) | -## Do you know +[`knapsack` vs `knapsack_pro` full comparison](https://knapsackpro.com/features/ruby_knapsack_pro_vs_knapsack?utm_source=github&utm_medium=readme&utm_campaign=knapsack_gem&utm_content=ruby_knapsack_pro_vs_knapsack) -* Knapsack Pro is risk-free integration! Knapsack Pro runs tests in Fallback Mode if your CI servers can't reach our API for any reason. -* We don't need access to your repository. Knapsack Pro is just wrapper around test runner like RSpec, Cucumber, Minitest etc. -* Hundreds of developers use Knapsack Pro every day to run fast CI builds. -* It works with other programming languages. +# Migrate from `knapsack` to `knapsack_pro` + +If you are already using `knapsack` and want to give `knapsack_pro` a try, here's [how to migrate in 10 minutes](./MIGRATE_TO_KNAPSACK_PRO.md). diff --git a/spec/knapsack/adapters/rspec_adapter_spec.rb b/spec/knapsack/adapters/rspec_adapter_spec.rb index 91f3823..0ae29b4 100644 --- a/spec/knapsack/adapters/rspec_adapter_spec.rb +++ b/spec/knapsack/adapters/rspec_adapter_spec.rb @@ -1,3 +1,5 @@ +require 'ostruct' + describe Knapsack::Adapters::RSpecAdapter do context do before { expect(::RSpec).to receive(:configure) }