1
1
import os
2
2
import platform
3
3
import re
4
- import shlex
5
4
import shutil
6
5
import subprocess
7
6
import sys
8
7
import tempfile
9
8
from pathlib import Path
10
- from typing import Any , Dict , List , NamedTuple , Optional , Sequence , Set , Tuple , cast
9
+ from typing import Any , Dict , List , NamedTuple , Sequence , Set , Tuple , cast
11
10
12
11
from .architecture import Architecture
13
12
from .environment import ParsedEnvironment
23
22
install_certifi_script ,
24
23
prepare_command ,
25
24
read_python_configs ,
25
+ run ,
26
26
unwrap ,
27
27
)
28
28
29
29
30
- def call (
31
- args : Sequence [PathOrStr ],
32
- env : Optional [Dict [str , str ]] = None ,
33
- cwd : Optional [str ] = None ,
34
- shell : bool = False ,
35
- ) -> None :
36
- # print the command executing for the logs
37
- if shell :
38
- print (f"+ { args } " )
39
- else :
40
- print ("+ " + " " .join (shlex .quote (str (a )) for a in args ))
41
-
42
- subprocess .run (args , env = env , cwd = cwd , shell = shell , check = True )
43
-
44
-
45
30
def get_macos_version () -> Tuple [int , int ]:
46
31
"""
47
32
Returns the macOS major/minor version, as a tuple, e.g. (10, 15) or (11, 0)
@@ -147,8 +132,11 @@ def install_cpython(version: str, url: str) -> Path:
147
132
# download the pkg
148
133
download (url , Path ("/tmp/Python.pkg" ))
149
134
# install
150
- call (["sudo" , "installer" , "-pkg" , "/tmp/Python.pkg" , "-target" , "/" ])
151
- call (["sudo" , str (installation_bin_path / python_executable ), str (install_certifi_script )])
135
+ run (["sudo" , "installer" , "-pkg" , "/tmp/Python.pkg" , "-target" , "/" ], check = True )
136
+ run (
137
+ ["sudo" , str (installation_bin_path / python_executable ), str (install_certifi_script )],
138
+ check = True ,
139
+ )
152
140
153
141
pip_executable = "pip3"
154
142
make_symlinks (installation_bin_path , python_executable , pip_executable )
@@ -165,7 +153,7 @@ def install_pypy(version: str, url: str) -> Path:
165
153
if not installation_path .exists ():
166
154
downloaded_tar_bz2 = Path ("/tmp" ) / pypy_tar_bz2
167
155
download (url , downloaded_tar_bz2 )
168
- call (["tar" , "-C" , "/tmp" , "-xf" , downloaded_tar_bz2 ])
156
+ run (["tar" , "-C" , "/tmp" , "-xf" , downloaded_tar_bz2 ], check = True )
169
157
170
158
installation_bin_path = installation_path / "bin"
171
159
python_executable = "pypy3"
@@ -216,8 +204,8 @@ def setup_python(
216
204
env ["PIP_DISABLE_PIP_VERSION_CHECK" ] = "1"
217
205
218
206
# check what version we're on
219
- call (["which" , "python" ], env = env )
220
- call (["python" , "--version" ], env = env )
207
+ run (["which" , "python" ], env = env , check = True )
208
+ run (["python" , "--version" ], env = env , check = True )
221
209
which_python = subprocess .run (
222
210
["which" , "python" ], env = env , universal_newlines = True , check = True , stdout = subprocess .PIPE
223
211
).stdout .strip ()
@@ -229,10 +217,10 @@ def setup_python(
229
217
sys .exit (1 )
230
218
231
219
# install pip & wheel
232
- call (["python" , get_pip_script , * dependency_constraint_flags ], env = env , cwd = "/tmp" )
220
+ run (["python" , get_pip_script , * dependency_constraint_flags ], env = env , cwd = "/tmp" , check = True )
233
221
assert (installation_bin_path / "pip" ).exists ()
234
- call (["which" , "pip" ], env = env )
235
- call (["pip" , "--version" ], env = env )
222
+ run (["which" , "pip" ], env = env , check = True )
223
+ run (["pip" , "--version" ], env = env , check = True )
236
224
which_pip = subprocess .run (
237
225
["which" , "pip" ], env = env , universal_newlines = True , check = True , stdout = subprocess .PIPE
238
226
).stdout .strip ()
@@ -290,7 +278,7 @@ def setup_python(
290
278
env .setdefault ("SDKROOT" , arm64_compatible_sdks [0 ])
291
279
292
280
log .step ("Installing build tools..." )
293
- call (
281
+ run (
294
282
[
295
283
"pip" ,
296
284
"install" ,
@@ -301,6 +289,7 @@ def setup_python(
301
289
* dependency_constraint_flags ,
302
290
],
303
291
env = env ,
292
+ check = True ,
304
293
)
305
294
306
295
return env
@@ -319,7 +308,7 @@ def build(options: BuildOptions) -> None:
319
308
before_all_prepared = prepare_command (
320
309
options .before_all , project = "." , package = options .package_dir
321
310
)
322
- call ([before_all_prepared ], shell = True , env = env )
311
+ run ([before_all_prepared ], shell = True , env = env , check = True )
323
312
324
313
python_configurations = get_python_configurations (
325
314
options .build_selector , options .architectures
@@ -345,7 +334,7 @@ def build(options: BuildOptions) -> None:
345
334
before_build_prepared = prepare_command (
346
335
options .before_build , project = "." , package = options .package_dir
347
336
)
348
- call (before_build_prepared , env = env , shell = True )
337
+ run (before_build_prepared , env = env , shell = True , check = True )
349
338
350
339
log .step ("Building wheel..." )
351
340
if built_wheel_dir .exists ():
@@ -354,7 +343,7 @@ def build(options: BuildOptions) -> None:
354
343
355
344
# Path.resolve() is needed. Without it pip wheel may try to fetch package from pypi.org
356
345
# see https://github.com/joerick/cibuildwheel/pull/369
357
- call (
346
+ run (
358
347
[
359
348
"pip" ,
360
349
"wheel" ,
@@ -365,6 +354,7 @@ def build(options: BuildOptions) -> None:
365
354
* get_build_verbosity_extra_flags (options .build_verbosity ),
366
355
],
367
356
env = env ,
357
+ check = True ,
368
358
)
369
359
370
360
built_wheel = next (built_wheel_dir .glob ("*.whl" ))
@@ -392,7 +382,7 @@ def build(options: BuildOptions) -> None:
392
382
dest_dir = repaired_wheel_dir ,
393
383
delocate_archs = delocate_archs ,
394
384
)
395
- call (repair_command_prepared , env = env , shell = True )
385
+ run (repair_command_prepared , env = env , shell = True , check = True )
396
386
else :
397
387
shutil .move (str (built_wheel ), repaired_wheel_dir )
398
388
@@ -457,7 +447,11 @@ def build(options: BuildOptions) -> None:
457
447
458
448
# set up a virtual environment to install and test from, to make sure
459
449
# there are no dependencies that were pulled in at build time.
460
- call (["pip" , "install" , "virtualenv" , * dependency_constraint_flags ], env = env )
450
+ run (
451
+ ["pip" , "install" , "virtualenv" , * dependency_constraint_flags ],
452
+ env = env ,
453
+ check = True ,
454
+ )
461
455
venv_dir = Path (tempfile .mkdtemp ())
462
456
463
457
arch_prefix = []
@@ -470,18 +464,20 @@ def build(options: BuildOptions) -> None:
470
464
"don't know how to emulate {testing_arch} on {machine_arch}"
471
465
)
472
466
473
- # define a custom 'call ' function that adds the arch prefix each time
474
- def call_with_arch (args : Sequence [PathOrStr ], ** kwargs : Any ) -> None :
467
+ # define a custom 'run ' function that adds the arch prefix each time
468
+ def run_with_arch (args : Sequence [PathOrStr ], ** kwargs : Any ) -> None :
475
469
if isinstance (args , str ):
476
470
args = " " .join (arch_prefix ) + " " + args
477
471
else :
478
472
args = [* arch_prefix , * args ]
479
- call (args , ** kwargs )
473
+ run (args , ** kwargs )
480
474
481
475
# Use --no-download to ensure determinism by using seed libraries
482
476
# built into virtualenv
483
- call_with_arch (
484
- ["python" , "-m" , "virtualenv" , "--no-download" , venv_dir ], env = env
477
+ run_with_arch (
478
+ ["python" , "-m" , "virtualenv" , "--no-download" , venv_dir ],
479
+ env = env ,
480
+ check = True ,
485
481
)
486
482
487
483
virtualenv_env = env .copy ()
@@ -493,24 +489,29 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
493
489
)
494
490
495
491
# check that we are using the Python from the virtual environment
496
- call_with_arch (["which" , "python" ], env = virtualenv_env )
492
+ run_with_arch (["which" , "python" ], env = virtualenv_env , check = True )
497
493
498
494
if options .before_test :
499
495
before_test_prepared = prepare_command (
500
496
options .before_test , project = "." , package = options .package_dir
501
497
)
502
- call_with_arch (before_test_prepared , env = virtualenv_env , shell = True )
498
+ run_with_arch (
499
+ before_test_prepared , env = virtualenv_env , shell = True , check = True
500
+ )
503
501
504
502
# install the wheel
505
- call_with_arch (
503
+ run_with_arch (
506
504
["pip" , "install" , f"{ repaired_wheel } { options .test_extras } " ],
507
505
env = virtualenv_env ,
506
+ check = True ,
508
507
)
509
508
510
509
# test the wheel
511
510
if options .test_requires :
512
- call_with_arch (
513
- ["pip" , "install" ] + options .test_requires , env = virtualenv_env
511
+ run_with_arch (
512
+ ["pip" , "install" ] + options .test_requires ,
513
+ env = virtualenv_env ,
514
+ check = True ,
514
515
)
515
516
516
517
# run the tests from $HOME, with an absolute path in the command
@@ -521,11 +522,12 @@ def call_with_arch(args: Sequence[PathOrStr], **kwargs: Any) -> None:
521
522
project = Path ("." ).resolve (),
522
523
package = options .package_dir .resolve (),
523
524
)
524
- call_with_arch (
525
+ run_with_arch (
525
526
test_command_prepared ,
526
527
cwd = os .environ ["HOME" ],
527
528
env = virtualenv_env ,
528
529
shell = True ,
530
+ check = True ,
529
531
)
530
532
531
533
# clean up
0 commit comments