3737WASMTIME_HOST_RUNNER_VAR = f"{{{ WASMTIME_VAR_NAME } }}"
3838
3939
40+ def separator ():
41+ """Print a separator line across the terminal width."""
42+ try :
43+ tput_output = subprocess .check_output (
44+ ["tput" , "cols" ], encoding = "utf-8"
45+ )
46+ except subprocess .CalledProcessError :
47+ terminal_width = 80
48+ else :
49+ terminal_width = int (tput_output .strip ())
50+ print ("⎯" * terminal_width )
51+
52+
53+ def log (emoji , message , * , spacing = None ):
54+ """Print a notification with an emoji.
55+
56+ If 'spacing' is None, calculate the spacing based on the number of code points
57+ in the emoji as terminals "eat" a space when the emoji has multiple code points.
58+ """
59+ if spacing is None :
60+ spacing = " " if len (emoji ) == 1 else " "
61+ print ("" .join ([emoji , spacing , message ]))
62+
63+
4064def updated_env (updates = {}):
4165 """Create a new dict representing the environment to use.
4266
@@ -60,9 +84,10 @@ def updated_env(updates={}):
6084 if os .environ .get (key ) != value :
6185 env_diff [key ] = value
6286
63- print ("🌎 Environment changes:" )
64- for key in sorted (env_diff .keys ()):
65- print (f" { key } ={ env_diff [key ]} " )
87+ env_vars = (
88+ f"\n { key } ={ item } " for key , item in sorted (env_diff .items ())
89+ )
90+ log ("🌎" , f"Environment changes:{ '' .join (env_vars )} " )
6691
6792 return environment
6893
@@ -77,22 +102,14 @@ def wrapper(context):
77102
78103 if callable (working_dir ):
79104 working_dir = working_dir (context )
80- try :
81- tput_output = subprocess .check_output (
82- ["tput" , "cols" ], encoding = "utf-8"
83- )
84- except subprocess .CalledProcessError :
85- terminal_width = 80
86- else :
87- terminal_width = int (tput_output .strip ())
88- print ("⎯" * terminal_width )
89- print ("📁" , working_dir )
105+ separator ()
106+ log ("📁" , os .fsdecode (working_dir ))
90107 if (
91108 clean_ok
92109 and getattr (context , "clean" , False )
93110 and working_dir .exists ()
94111 ):
95- print ("🚮 Deleting directory (--clean)..." )
112+ log ("🚮" , " Deleting directory (--clean)..." )
96113 shutil .rmtree (working_dir )
97114
98115 working_dir .mkdir (parents = True , exist_ok = True )
@@ -116,7 +133,7 @@ def call(command, *, context=None, quiet=False, logdir=None, **kwargs):
116133 elif quiet and logdir is None :
117134 raise ValueError ("When quiet is True, logdir must be specified" )
118135
119- print ("❯" , " " .join (map (str , command )))
136+ log ("❯" , " " .join (map (str , command )), spacing = " " )
120137 if not quiet :
121138 stdout = None
122139 stderr = None
@@ -130,7 +147,7 @@ def call(command, *, context=None, quiet=False, logdir=None, **kwargs):
130147 suffix = ".log" ,
131148 )
132149 stderr = subprocess .STDOUT
133- print ( f"📝 Logging output to { stdout .name } (--quiet)..." )
150+ log ( "📝" , f" Logging output to { stdout .name } (--quiet)..." )
134151
135152 subprocess .check_call (command , ** kwargs , stdout = stdout , stderr = stderr )
136153
@@ -163,11 +180,11 @@ def configure_build_python(context, working_dir):
163180 """Configure the build/host Python."""
164181 if LOCAL_SETUP .exists ():
165182 if LOCAL_SETUP .read_bytes () == LOCAL_SETUP_MARKER :
166- print ( f"👍 { LOCAL_SETUP } exists ..." )
183+ log ( "👍" , f" { LOCAL_SETUP } exists ..." )
167184 else :
168- print ( f "⚠️ { LOCAL_SETUP } exists, but has unexpected contents" )
185+ log ( "⚠️" , f" { LOCAL_SETUP } exists, but has unexpected contents" )
169186 else :
170- print ( f"📝 Creating { LOCAL_SETUP } ..." )
187+ log ( "📝" , f" Creating { LOCAL_SETUP } ..." )
171188 LOCAL_SETUP .write_bytes (LOCAL_SETUP_MARKER )
172189
173190 configure = [os .path .relpath (CHECKOUT / "configure" , working_dir )]
@@ -191,30 +208,50 @@ def make_build_python(context, working_dir):
191208 ]
192209 version = subprocess .check_output (cmd , encoding = "utf-8" ).strip ()
193210
194- print ( f"🎉 { binary } { version } " )
211+ log ( "🎉" , f" { binary } { version } " )
195212
196213
197214def find_wasi_sdk ():
198215 """Find the path to the WASI SDK."""
199- if wasi_sdk_path := os .environ .get ("WASI_SDK_PATH" ):
200- return pathlib .Path (wasi_sdk_path )
201-
202- opt_path = pathlib .Path ("/opt" )
203- # WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team
204- # has said they don't plan to ever do a point release and all of their Git tags
205- # lack the ``.0`` suffix.
206- # Starting with WASI SDK 23, the tarballs went from containing a directory named
207- # ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g.
208- # ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``.
209- potential_sdks = [
210- path
211- for path in opt_path .glob (f"wasi-sdk-{ WASI_SDK_VERSION } .0*" )
212- if path .is_dir ()
213- ]
214- if len (potential_sdks ) == 1 :
215- return potential_sdks [0 ]
216- elif (default_path := opt_path / "wasi-sdk" ).is_dir ():
217- return default_path
216+ wasi_sdk_path = None
217+
218+ if wasi_sdk_path_env_var := os .environ .get ("WASI_SDK_PATH" ):
219+ wasi_sdk_path = pathlib .Path (wasi_sdk_path_env_var )
220+ else :
221+ opt_path = pathlib .Path ("/opt" )
222+ # WASI SDK versions have a ``.0`` suffix, but it's a constant; the WASI SDK team
223+ # has said they don't plan to ever do a point release and all of their Git tags
224+ # lack the ``.0`` suffix.
225+ # Starting with WASI SDK 23, the tarballs went from containing a directory named
226+ # ``wasi-sdk-{WASI_SDK_VERSION}.0`` to e.g.
227+ # ``wasi-sdk-{WASI_SDK_VERSION}.0-x86_64-linux``.
228+ potential_sdks = [
229+ path
230+ for path in opt_path .glob (f"wasi-sdk-{ WASI_SDK_VERSION } .0*" )
231+ if path .is_dir ()
232+ ]
233+ if len (potential_sdks ) == 1 :
234+ wasi_sdk_path = potential_sdks [0 ]
235+ elif (default_path := opt_path / "wasi-sdk" ).is_dir ():
236+ wasi_sdk_path = default_path
237+
238+ # Starting with WASI SDK 25, a VERSION file is included in the root
239+ # of the SDK directory that we can read to warn folks when they are using
240+ # an unsupported version.
241+ if wasi_sdk_path and (version_file := wasi_sdk_path / "VERSION" ).is_file ():
242+ version_details = version_file .read_text (encoding = "utf-8" )
243+ found_version = version_details .splitlines ()[0 ]
244+ # Make sure there's a trailing dot to avoid false positives if somehow the
245+ # supported version is a prefix of the found version (e.g. `25` and `2567`).
246+ if not found_version .startswith (f"{ WASI_SDK_VERSION } ." ):
247+ major_version = found_version .partition ("." )[0 ]
248+ log (
249+ "⚠️" ,
250+ f" Found WASI SDK { major_version } , "
251+ f"but WASI SDK { WASI_SDK_VERSION } is the supported version" ,
252+ )
253+
254+ return wasi_sdk_path
218255
219256
220257def wasi_sdk_env (context ):
@@ -330,7 +367,7 @@ def configure_wasi_python(context, working_dir):
330367 with exec_script .open ("w" , encoding = "utf-8" ) as file :
331368 file .write (f'#!/bin/sh\n exec { host_runner } { python_wasm } "$@"\n ' )
332369 exec_script .chmod (0o755 )
333- print ( f"🏃♀️ Created { exec_script } (--host-runner)... " )
370+ log ( "🏃" , f" Created { exec_script } (--host-runner)... " )
334371 sys .stdout .flush ()
335372
336373
@@ -345,9 +382,10 @@ def make_wasi_python(context, working_dir):
345382
346383 exec_script = working_dir / "python.sh"
347384 call ([exec_script , "--version" ], quiet = False )
348- print (
349- f"🎉 Use `{ exec_script .relative_to (context .init_dir )} ` "
350- "to run CPython w/ the WASI host specified by --host-runner"
385+ log (
386+ "🎉" ,
387+ f"Use `{ exec_script .relative_to (context .init_dir )} ` "
388+ "to run CPython w/ the WASI host specified by --host-runner" ,
351389 )
352390
353391
@@ -366,12 +404,12 @@ def build_all(context):
366404def clean_contents (context ):
367405 """Delete all files created by this script."""
368406 if CROSS_BUILD_DIR .exists ():
369- print ( f"🧹 Deleting { CROSS_BUILD_DIR } ..." )
407+ log ( "🧹" , f" Deleting { CROSS_BUILD_DIR } ..." )
370408 shutil .rmtree (CROSS_BUILD_DIR )
371409
372410 if LOCAL_SETUP .exists ():
373411 if LOCAL_SETUP .read_bytes () == LOCAL_SETUP_MARKER :
374- print ( f"🧹 Deleting generated { LOCAL_SETUP } ..." )
412+ log ( "🧹" , f" Deleting generated { LOCAL_SETUP } ..." )
375413
376414
377415def main ():
0 commit comments