#zip file with Tcl loader prepended. Requires either builtin zipfs, or vfs::zip to mount while zipped. #Alternatively unzip so that extracted #modpod-package-version folder is in same folder as .tm file. #generated using: modpod::lib::make_zip_modpod -offsettype archive if {[catch {file normalize [info script]}]} { error "modpod zip stub error. Unable to determine module path. (possible safe interp restrictions?)" } apply {{modfile} { if {$modfile eq "" || ![file exists $modfile]} { error "modpod zip stub error. Unable to determine module path" } set moddir [file dirname $modfile] set exedir [file dirname [file normalize [info nameofexecutable]]] set mod_and_ver [file rootname [file tail $modfile]] lassign [split $mod_and_ver -] moduletail version set do_intersect {{A B} { if {[llength $A] == 0} {return {}} if {[llength $B] == 0} {return {}} if {[llength $B] > [llength $A]} { set res $A set A $B set B $res } set res {} foreach x $A {set ($x) {}} foreach x $B { if {[info exists ($x)]} { lappend res $x } } return $res }} #determine module namespace so we can mount appropriately set lcase_tmfile_segments [string tolower [file split $moddir]] set lcase_modulepaths [string tolower [tcl::tm::list]] foreach lc_mpath $lcase_modulepaths { set mpath_segments [file split $lc_mpath] if {[llength [apply $do_intersect $lcase_tmfile_segments $mpath_segments]] == [llength $mpath_segments]} { set tail_segments [lrange [file split $moddir] [llength $mpath_segments] end] ;#use properly cased tail break } } if {[llength $tail_segments]} { set fullpackage [join [concat $tail_segments $moduletail] ::] ;#full name of package as used in package require set mount_at #modpod/[file join {*}$tail_segments]/#mounted-modpod-$mod_and_ver } else { set fullpackage $moduletail set mount_at #modpod/#mounted-modpod-$mod_and_ver } if {[info commands tcl::zipfs::mount] ne ""} { #argument order changed to be consistent with vfs::zip::Mount etc #early versions: zipfs::Mount mountpoint zipname #since 2023-09: zipfs::Mount zipname mountpoint #don't use 'file exists' when testing mountpoints. (some versions at least give massive delays on windows platform for non-existance) #This is presumably related to // being interpreted as a network path set mountpoints [dict keys [tcl::zipfs::mount]] if {"//zipfs:/$mount_at" ni $mountpoints} { #despite API change tcl::zipfs package version was unfortunately not updated - so we don't know argument order without trying it if {[catch { #tcl::zipfs::mount $modfile //zipfs:/#mounted-modpod-$mod_and_ver ;#extremely slow if this is a wrong guess (artifact of aforementioned file exists issue ?) #puts "tcl::zipfs::mount $modfile $mount_at" tcl::zipfs::mount $modfile $mount_at } errM]} { #try old api if {![catch {tcl::zipfs::mount //zipfs:/$mount_at $modfile}]} { puts stderr "modpod stub>>> tcl::zipfs::mount failed.\nbut old api: tcl::zipfs::mount succeeded\n tcl::zipfs::mount //zipfs://$mount_at $modfile" puts stderr "Consider upgrading tcl runtime to one with fixed zipfs API" } } if {![file exists //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm]} { puts stderr "modpod stub>>> mount at //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm failed\n zipfs mounts: [zipfs mount]" #tcl::zipfs::unmount //zipfs:/$mount_at error "Unable to find $mod_and_ver.tm in $modfile for module $fullpackage" } } # #modpod-$mod_and_ver subdirectory always present in the archive so it can be conveniently extracted and run in that form uplevel 1 [list source //zipfs:/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm] } else { #fallback to slower vfs::zip #NB. We don't create the intermediate dirs - but the mount still works if {![file exists $exedir/$mount_at]} { if {[catch {package require vfs::zip} errM]} { set msg "Unable to load vfs::zip package to mount module $mod_and_ver (and zipfs not available either)" append msg \n "If neither zipfs or vfs::zip are available - the module can still be loaded by manually unzipping the file $modfile in place." append msg \n "The unzipped data will all be contained in a folder named #modpod-$mod_and_ver in the same parent folder as $modfile" error $msg } else { set fd [vfs::zip::Mount $modfile $exedir/$mount_at] if {![file exists $exedir/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm]} { vfs::zip::Unmount $fd $exedir/$mount_at error "Unable to find $mod_and_ver.tm in $modfile for module $fullpackage" } } } uplevel 1 [list source $exedir/$mount_at/#modpod-$mod_and_ver/$mod_and_ver.tm] } }} [file normalize [info script]] #zipped data follows PK\*yg_.#modpod-packagetest-0.1.8/packagetest-0.1.8.tm,քG@i O`ҀKЛ/yZI9-8Q &LDl3> 8ҦLnogߤyX+}^<_ēoex<0o6ùQc'S Y% l@M2q(O7,\ 6DYx;rwq̓brN2/&ÙO(EFn6`# ;tP%V7)Ƿ|{fA eXoύy.sNT( z v*b4ا\nߥ`P6E^u3-+ I[!2s ->ga8ݤ|܎ xnfU|?m+"댋Bq!@v~;T&EHڪLi@4Ix]zrң6UfNO"|qyx\5Lƨ,x'|aQSӤ >rEqOGgi~Zo0ө;;/bө\Z"݆M|rKtH>yz<?1SjS'ZO- #@u#Siv5\DRwiF6-˄MM m 2LBjE4H:τ9`@Hn0e # >qdk$M0RPs k.!@^e1IF18a>Djh!I^ #*^NLi)1KyoÀ>tQjAF0[Syqx>5@ޤi sz: !#3^@H8B rZ0A.9Jwo  GE؜|Z7-IE I;Pd+VFѶ) 3lb7JD(K<&*qBɥ=_R)˽Hp 9 [f{L!$zN)uMA ) ۶(-=:tj2U )TƚmJxAZBks$͏oǷ) a+^,MLU!K/BϲbWXT05b^r f "bYݗ"ĢI{^t) 3Ks_l +2{/h U۷RktJ.U:"-S/f?gvB3m?6K8s,AzlVn"~#;#0@Ipؔ2=JJ[AބJ>>@JH a t*ݱb8Q-0ØBXPI"4SfZ5ؙW3 #fl¥> 8a^Ec2-#uZ J )XNs?xlzn[lưDd7e^餇]AhXl HR"L  /I#ȡ8IV ^bϛ=0uF("'i̼"DP]NQHEn]:%$ʱ@ɭ< 1HiEU8=vBUzF]̵n6IRj垿6siacP8Oc^-Ls9y1K Mdȋ d^؀˾e1 "sRA2vZE^pF4FB$g['=s14 yrHC~e`ұ྇}WO(a^PEe^q0)컙cΟIרT YBa50ТjBɖ,*`M"a<[s&$rT$[?ko='u3m^ylA@SbuhM!C?CG 3gxr\Ŏ N!Uj!zGJ%NcD3a-/1=cj׬90.A˰#xe X_>.$*CN r ncFvԤJ̯1; " ַ,ޟ|4AݛѠ;IS1N&<&)jUj,թJfM5^'Qti]Qzק@`i)aS W% &~ }5CFMkk;ZB4ι(رhusfPHm=dWsU*/9 MfcOhwhP47&/,1͛/MkFSBol-"A2pֿz.j^Y4Yg'5MteÛ曯_@vu$aE &zW]nW&AЃb IJV `ebsgӘ1BX0k1Z?!x&Xbךm PbgQZqAQ1gc,wJ8e^E=RLj^Z=E1q׫on'-Ⱥmv`AL%Q0PFrn*` Ւ퐺c/h^#P <$巤SWs4f ^,<4j]YZCEFiO~x–> )0قGiB .Rkgn̑C'qfi!S|o K,C $Hf9OƀEQ.+vC>& ]³ɱ]Y7彤SS e)G&"4k3!JYsmZ|' b`oP"صɜsx)_d]w h&OK+%֩٩89iAp-f) qYLBHl"8I w~yb |R rFAL饟"YCg5, ;JVl,P7f*עײ7m-|j$ti\wPq  Oe@:P pɝrѰ3 Ϩ䳄=^D& 0'〣2k~=slYPrJ#2 i}1'hn=m@M)v mG P0k,`m87CFFv1ZҌo^# ]1RVvdP0y_R ! Zu8bKJEXp>'f=諍jV()7>RVDaWZQl#b|OjGP@S XDn5K6hVck/δ^7ug^9~9{q8="uO3*m0>\̥8RQAW0fB&Vr>؄y ㆪL|HIw>Ih:&M@:?W9rCm (Y{=t}I\%.z<)2&׎|zHrupB ޖEe.H# #U~!M K/yEʼnybr \^NaʤPUۻMLM3"q5H y $U @] ~rH3X-E\JEP\>ZEs}u]CLOgI*qUՃE;2nT!1jPFD[QWl2Ы}٤ӍvĥY;𫍞Gr!qL)b@-O[%8kUJ$ЩMM3y] d$smO G3YLٸ"~ aإg[hT۷!o l2)&fϻ6njb6eO0ty,"L/p~ƓJ&~fƷI/TlqҩI4΃wA?:6#  &!I9 qFo'k-x5BEWX>?4C16j@\9X w#烈_[vkL(ny^ePcP,.L>eKV^I H/N.L0~R\]:6U[bJEͬgo^j/kWt] QP5qʪvN9NΣC}dX.5.*4W;GwOԻ)I<b?Jڗ7U,=7P[MEsqeŦ2JJ=7+T[ݙs+j;pnSv6W h.ʒ-q1avSPƋ֍( (;;%vhU,dU=Ɖh]VF5v୾`̘ PGZyOR.QQyqPGMF{v };oU]n/Byx qEPK\*yg_.#modpod-packagetest-0.1.8/packagetest-0.1.8.tmPK\1