66import platform
77import sys
88import urllib .request
9+ from urllib .parse import urljoin
910import json
1011import hashlib
12+ import logging
1113
1214INDEX_URL = os .getenv ("ASDF_ZIG_INDEX_URL" , "https://ziglang.org/download/index.json" )
1315HTTP_TIMEOUT = int (os .getenv ("ASDF_ZIG_HTTP_TIMEOUT" , "30" ))
@@ -46,17 +48,21 @@ def all_versions(index=fetch_index()):
4648 return versions
4749
4850
49- def download_and_check (url , out_file , expected_shasum ):
50- print (f"Download tarball from { url } to { out_file } ..." )
51- chunk_size = 8192 # 8KB chunks
51+ def download_and_check (url , out_file , expected_shasum , total_size ):
52+ logging . info (f"Begin download tarball( { total_size } ) from { url } to { out_file } ..." )
53+ chunk_size = 1024 * 1024 # 1M chunks
5254 sha256_hash = hashlib .sha256 ()
5355 with urllib .request .urlopen (url , timeout = HTTP_TIMEOUT ) as response :
5456 if response .getcode () != 200 :
5557 raise Exception (f"Fetch index.json error: { response .getcode ()} " )
5658
59+ read_size = 0
5760 with open (out_file , "wb" ) as f :
5861 while True :
5962 chunk = response .read (chunk_size )
63+ read_size += len (chunk )
64+ progress_percentage = (read_size / total_size ) * 100 if total_size > 0 else 0
65+ logging .info (f'Downloaded: { read_size } /{ total_size } bytes ({ progress_percentage :.2f} %)' )
6066 if not chunk :
6167 break # eof
6268 sha256_hash .update (chunk )
@@ -69,20 +75,21 @@ def download_and_check(url, out_file, expected_shasum):
6975 )
7076
7177
72- def download_tarball (url , out_file , expected_shasum ):
78+ def download_tarball (url , out_file , expected_shasum , total_size ):
7379 filename = url .split ("/" )[- 1 ]
7480 random .shuffle (MIRRORS )
75- urls = [f"{ mirror } /{ filename } " for mirror in MIRRORS ]
7681
77- for url in urls :
82+ for mirror in MIRRORS :
7883 try :
79- download_and_check (url , out_file , expected_shasum )
84+ # Ensure base_url has a trailing slash
85+ mirror = mirror if mirror .endswith ('/' ) else mirror + '/'
86+ download_and_check (urljoin (mirror , filename ), out_file , expected_shasum , total_size )
8087 return
8188 except Exception as e :
82- print (f"Current mirror failed, try next. err:{ e } " )
89+ logging . error (f"Current mirror failed, try next. err:{ e } " )
8390
8491 # All mirrors failed, fallback to original url
85- download_and_check (url , out_file , expected_shasum )
92+ download_and_check (url , out_file , expected_shasum , total_size )
8693
8794
8895def download (version , out_file ):
@@ -101,7 +108,8 @@ def download(version, out_file):
101108
102109 tarball_url = links [link_key ]["tarball" ]
103110 tarball_shasum = links [link_key ]["shasum" ]
104- download_tarball (tarball_url , out_file , tarball_shasum )
111+ tarball_size = int (links [link_key ]["size" ])
112+ download_tarball (tarball_url , out_file , tarball_shasum , tarball_size )
105113
106114
107115def main (args ):
@@ -115,9 +123,10 @@ def main(args):
115123 elif command == "download" :
116124 download (args [1 ], args [2 ])
117125 else :
118- print (f"Unknown command: { command } " )
126+ logging . error (f"Unknown command: { command } " )
119127 sys .exit (1 )
120128
121129
122130if __name__ == "__main__" :
131+ logging .basicConfig (level = logging .INFO , format = '[%(asctime)s] %(message)s' )
123132 main (sys .argv [1 :])
0 commit comments