Add log steps to macOS/Windows

This commit is contained in:
Joe Rickerby
2020-11-13 16:30:35 +00:00
parent 246aa0848e
commit 38297e6663
4 changed files with 226 additions and 186 deletions
+1 -3
View File
@@ -1,4 +1,3 @@
from cibuildwheel.logger import Logger
import platform import platform
import subprocess import subprocess
import sys import sys
@@ -8,6 +7,7 @@ from pathlib import Path, PurePath
from typing import List, NamedTuple, Union from typing import List, NamedTuple, Union
from .docker_container import DockerContainer from .docker_container import DockerContainer
from .logger import log
from .util import (BuildOptions, BuildSelector, NonPlatformWheelError, from .util import (BuildOptions, BuildSelector, NonPlatformWheelError,
get_build_verbosity_extra_flags, prepare_command) get_build_verbosity_extra_flags, prepare_command)
@@ -112,8 +112,6 @@ def build(options: BuildOptions) -> None:
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd) container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)
container_output_dir = PurePath('/output') container_output_dir = PurePath('/output')
log = Logger()
for implementation, platform_tag, docker_image in platforms: for implementation, platform_tag, docker_image in platforms:
platform_configs = [c for c in python_configurations if c.identifier.startswith(implementation) and c.identifier.endswith(platform_tag)] platform_configs = [c for c in python_configurations if c.identifier.startswith(implementation) and c.identifier.endswith(platform_tag)]
if not platform_configs: if not platform_configs:
+9 -2
View File
@@ -1,7 +1,7 @@
import os import os
import time
import sys
import re import re
import sys
import time
from typing import Optional, Union from typing import Optional, Union
DEFAULT_FOLD_PATTERN = ('{name}', '') DEFAULT_FOLD_PATTERN = ('{name}', '')
@@ -142,6 +142,13 @@ class Logger:
return colors_disabled return colors_disabled
'''
Global instance of the Logger.
'''
# (there's only one stdout per-process, so a global instance is justified)
log = Logger()
def build_description_from_identifier(identifier: str): def build_description_from_identifier(identifier: str):
python_identifier, _, platform_identifier = identifier.partition('-') python_identifier, _, platform_identifier = identifier.partition('-')
+26 -9
View File
@@ -9,9 +9,10 @@ from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence, Union from typing import Dict, List, NamedTuple, Optional, Sequence, Union
from .environment import ParsedEnvironment from .environment import ParsedEnvironment
from .util import (BuildOptions, BuildSelector, NonPlatformWheelError, download, from .logger import log
get_build_verbosity_extra_flags, get_pip_script, from .util import (BuildOptions, BuildSelector, NonPlatformWheelError,
prepare_command, install_certifi_script) download, get_build_verbosity_extra_flags, get_pip_script,
install_certifi_script, prepare_command)
def call(args: Union[str, Sequence[Union[str, PathLike]]], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None, shell: bool = False) -> int: def call(args: Union[str, Sequence[Union[str, PathLike]]], env: Optional[Dict[str, str]] = None, cwd: Optional[str] = None, shell: bool = False) -> int:
@@ -116,13 +117,18 @@ def install_pypy(version: str, url: str) -> Path:
def setup_python(python_configuration: PythonConfiguration, def setup_python(python_configuration: PythonConfiguration,
dependency_constraint_flags: Sequence[Union[str, PathLike]], dependency_constraint_flags: Sequence[Union[str, PathLike]],
environment: ParsedEnvironment) -> Dict[str, str]: environment: ParsedEnvironment) -> Dict[str, str]:
if python_configuration.identifier.startswith('cp'): implementation_id = python_configuration.identifier.split("-")[0]
log.step(f'Installing Python {implementation_id}...')
if implementation_id.startswith('cp'):
installation_bin_path = install_cpython(python_configuration.version, python_configuration.url) installation_bin_path = install_cpython(python_configuration.version, python_configuration.url)
elif python_configuration.identifier.startswith('pp'): elif implementation_id.startswith('pp'):
installation_bin_path = install_pypy(python_configuration.version, python_configuration.url) installation_bin_path = install_pypy(python_configuration.version, python_configuration.url)
else: else:
raise ValueError("Unknown Python implementation") raise ValueError("Unknown Python implementation")
log.step('Setting up build environment...')
env = os.environ.copy() env = os.environ.copy()
env['PATH'] = os.pathsep.join([ env['PATH'] = os.pathsep.join([
str(SYMLINKS_DIR), str(SYMLINKS_DIR),
@@ -156,7 +162,6 @@ def setup_python(python_configuration: PythonConfiguration,
if which_pip != '/tmp/cibw_bin/pip': if which_pip != '/tmp/cibw_bin/pip':
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr) print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
exit(1) exit(1)
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env)
# Set MACOSX_DEPLOYMENT_TARGET to 10.9, if the user didn't set it. # Set MACOSX_DEPLOYMENT_TARGET to 10.9, if the user didn't set it.
# CPython 3.5 defaults to 10.6, and pypy defaults to 10.7, causing # CPython 3.5 defaults to 10.6, and pypy defaults to 10.7, causing
@@ -170,6 +175,9 @@ def setup_python(python_configuration: PythonConfiguration,
# https://github.com/python/cpython/blob/a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10/Lib/_osx_support.py#L260 # https://github.com/python/cpython/blob/a5ed2fe0eedefa1649aa93ee74a0bafc8e628a10/Lib/_osx_support.py#L260
env.setdefault('ARCHFLAGS', '-arch x86_64') env.setdefault('ARCHFLAGS', '-arch x86_64')
log.step('Installing build tools...')
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate', *dependency_constraint_flags], env=env)
return env return env
@@ -178,7 +186,9 @@ def build(options: BuildOptions) -> None:
built_wheel_dir = temp_dir / 'built_wheel' built_wheel_dir = temp_dir / 'built_wheel'
repaired_wheel_dir = temp_dir / 'repaired_wheel' repaired_wheel_dir = temp_dir / 'repaired_wheel'
try:
if options.before_all: if options.before_all:
log.step('Running before_all...')
env = options.environment.as_dictionary(prev_environment=os.environ) env = options.environment.as_dictionary(prev_environment=os.environ)
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir) before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
call([before_all_prepared], shell=True, env=env) call([before_all_prepared], shell=True, env=env)
@@ -186,6 +196,8 @@ def build(options: BuildOptions) -> None:
python_configurations = get_python_configurations(options.build_selector) python_configurations = get_python_configurations(options.build_selector)
for config in python_configurations: for config in python_configurations:
log.build_start(config.identifier)
dependency_constraint_flags: Sequence[Union[str, PathLike]] = [] dependency_constraint_flags: Sequence[Union[str, PathLike]] = []
if options.dependency_constraints: if options.dependency_constraints:
dependency_constraint_flags = [ dependency_constraint_flags = [
@@ -194,12 +206,12 @@ def build(options: BuildOptions) -> None:
env = setup_python(config, dependency_constraint_flags, options.environment) env = setup_python(config, dependency_constraint_flags, options.environment)
# run the before_build command
if options.before_build: if options.before_build:
log.step('Running before_build...')
before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir) before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir)
call(before_build_prepared, env=env, shell=True) call(before_build_prepared, env=env, shell=True)
# build the wheel log.step('Building wheel...')
if built_wheel_dir.exists(): if built_wheel_dir.exists():
shutil.rmtree(built_wheel_dir) shutil.rmtree(built_wheel_dir)
built_wheel_dir.mkdir(parents=True) built_wheel_dir.mkdir(parents=True)
@@ -216,7 +228,6 @@ def build(options: BuildOptions) -> None:
built_wheel = next(built_wheel_dir.glob('*.whl')) built_wheel = next(built_wheel_dir.glob('*.whl'))
# repair the wheel
if repaired_wheel_dir.exists(): if repaired_wheel_dir.exists():
shutil.rmtree(repaired_wheel_dir) shutil.rmtree(repaired_wheel_dir)
repaired_wheel_dir.mkdir(parents=True) repaired_wheel_dir.mkdir(parents=True)
@@ -225,6 +236,7 @@ def build(options: BuildOptions) -> None:
raise NonPlatformWheelError() raise NonPlatformWheelError()
if options.repair_command: if options.repair_command:
log.step('Repairing wheel...')
repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir) repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir)
call(repair_command_prepared, env=env, shell=True) call(repair_command_prepared, env=env, shell=True)
else: else:
@@ -233,6 +245,7 @@ def build(options: BuildOptions) -> None:
repaired_wheel = next(repaired_wheel_dir.glob('*.whl')) repaired_wheel = next(repaired_wheel_dir.glob('*.whl'))
if options.test_command: if options.test_command:
log.step('Testing wheel...')
# set up a virtual environment to install and test from, to make sure # set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time. # there are no dependencies that were pulled in at build time.
call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env) call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env)
@@ -277,3 +290,7 @@ def build(options: BuildOptions) -> None:
# we're all done here; move it to output (overwrite existing) # we're all done here; move it to output (overwrite existing)
shutil.move(str(repaired_wheel), options.output_dir) shutil.move(str(repaired_wheel), options.output_dir)
log.build_end()
except subprocess.CalledProcessError as error:
log.error(f'Command {error.cmd} failed with code {error.returncode}. {error.stdout}')
exit(1)
+28 -10
View File
@@ -7,11 +7,13 @@ from os import PathLike
from pathlib import Path from pathlib import Path
from typing import Dict, List, NamedTuple, Optional, Sequence, Union from typing import Dict, List, NamedTuple, Optional, Sequence, Union
from zipfile import ZipFile from zipfile import ZipFile
import toml import toml
from .environment import ParsedEnvironment from .environment import ParsedEnvironment
from .util import (BuildOptions, BuildSelector, NonPlatformWheelError, download, from .logger import log
get_build_verbosity_extra_flags, get_pip_script, from .util import (BuildOptions, BuildSelector, NonPlatformWheelError,
download, get_build_verbosity_extra_flags, get_pip_script,
prepare_command) prepare_command)
IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists() IS_RUNNING_ON_AZURE = Path('C:\\hostedtoolcache').exists()
@@ -109,11 +111,15 @@ def install_pypy(version: str, arch: str, url: str) -> Path:
def setup_python(python_configuration: PythonConfiguration, dependency_constraint_flags: Sequence[Union[str, PathLike]], environment: ParsedEnvironment) -> Dict[str, str]: def setup_python(python_configuration: PythonConfiguration, dependency_constraint_flags: Sequence[Union[str, PathLike]], environment: ParsedEnvironment) -> Dict[str, str]:
nuget = Path('C:\\cibw\\nuget.exe') nuget = Path('C:\\cibw\\nuget.exe')
if not nuget.exists(): if not nuget.exists():
log.step('Downloading nuget...')
download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget) download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget)
if python_configuration.identifier.startswith('cp'): implementation_id = python_configuration.identifier.split("-")[0]
log.step(f'Installing Python {implementation_id}...')
if implementation_id.startswith('cp'):
installation_path = install_cpython(python_configuration.version, python_configuration.arch, nuget) installation_path = install_cpython(python_configuration.version, python_configuration.arch, nuget)
elif python_configuration.identifier.startswith('pp'): elif implementation_id.startswith('pp'):
assert python_configuration.url is not None assert python_configuration.url is not None
installation_path = install_pypy(python_configuration.version, python_configuration.arch, python_configuration.url) installation_path = install_pypy(python_configuration.version, python_configuration.arch, python_configuration.url)
else: else:
@@ -121,6 +127,8 @@ def setup_python(python_configuration: PythonConfiguration, dependency_constrain
assert (installation_path / 'python.exe').exists() assert (installation_path / 'python.exe').exists()
log.step('Setting up build environment...')
# set up PATH and environment variables for run_with_env # set up PATH and environment variables for run_with_env
env = os.environ.copy() env = os.environ.copy()
env['PYTHON_VERSION'] = python_configuration.version env['PYTHON_VERSION'] = python_configuration.version
@@ -151,7 +159,8 @@ def setup_python(python_configuration: PythonConfiguration, dependency_constrain
print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr) print("cibuildwheel: pip available on PATH doesn't match our installed instance. If you have modified PATH, ensure that you don't overwrite cibuildwheel's entry or insert pip above it.", file=sys.stderr)
exit(1) exit(1)
# prepare the Python environment log.step('Installing build tools...')
call(['python', '-m', 'pip', 'install', '--upgrade', 'pip', *dependency_constraint_flags], env=env) call(['python', '-m', 'pip', 'install', '--upgrade', 'pip', *dependency_constraint_flags], env=env)
call(['pip', '--version'], env=env) call(['pip', '--version'], env=env)
call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', *dependency_constraint_flags], env=env) call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', *dependency_constraint_flags], env=env)
@@ -182,6 +191,7 @@ def pep_518_cp35_workaround(package_dir: Path, env: Dict[str, str]) -> None:
) )
if requirements: if requirements:
log.step('Performing PEP518 workaround...')
with tempfile.TemporaryDirectory() as d: with tempfile.TemporaryDirectory() as d:
reqfile = Path(d) / "requirements.txt" reqfile = Path(d) / "requirements.txt"
with reqfile.open("w") as f: with reqfile.open("w") as f:
@@ -195,17 +205,18 @@ def build(options: BuildOptions) -> None:
built_wheel_dir = temp_dir / 'built_wheel' built_wheel_dir = temp_dir / 'built_wheel'
repaired_wheel_dir = temp_dir / 'repaired_wheel' repaired_wheel_dir = temp_dir / 'repaired_wheel'
# install nuget as best way to provide python try:
nuget = Path('C:\\cibw\\nuget.exe')
download('https://dist.nuget.org/win-x86-commandline/latest/nuget.exe', nuget)
if options.before_all: if options.before_all:
log.step('Running before_all...')
env = options.environment.as_dictionary(prev_environment=os.environ) env = options.environment.as_dictionary(prev_environment=os.environ)
before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir) before_all_prepared = prepare_command(options.before_all, project='.', package=options.package_dir)
shell(before_all_prepared, env=env) shell(before_all_prepared, env=env)
python_configurations = get_python_configurations(options.build_selector) python_configurations = get_python_configurations(options.build_selector)
for config in python_configurations: for config in python_configurations:
log.build_start(config.identifier)
dependency_constraint_flags: Sequence[Union[str, PathLike]] = [] dependency_constraint_flags: Sequence[Union[str, PathLike]] = []
if options.dependency_constraints: if options.dependency_constraints:
dependency_constraint_flags = [ dependency_constraint_flags = [
@@ -217,6 +228,7 @@ def build(options: BuildOptions) -> None:
# run the before_build command # run the before_build command
if options.before_build: if options.before_build:
log.step('Running before_build...')
before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir) before_build_prepared = prepare_command(options.before_build, project='.', package=options.package_dir)
shell(before_build_prepared, env=env) shell(before_build_prepared, env=env)
@@ -225,7 +237,7 @@ def build(options: BuildOptions) -> None:
if config.version.startswith('3.5'): if config.version.startswith('3.5'):
pep_518_cp35_workaround(options.package_dir, env) pep_518_cp35_workaround(options.package_dir, env)
# build the wheel log.step('Building wheel...')
if built_wheel_dir.exists(): if built_wheel_dir.exists():
shutil.rmtree(built_wheel_dir) shutil.rmtree(built_wheel_dir)
built_wheel_dir.mkdir(parents=True) built_wheel_dir.mkdir(parents=True)
@@ -250,6 +262,7 @@ def build(options: BuildOptions) -> None:
raise NonPlatformWheelError() raise NonPlatformWheelError()
if options.repair_command: if options.repair_command:
log.step('Repairing wheel...')
repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir) repair_command_prepared = prepare_command(options.repair_command, wheel=built_wheel, dest_dir=repaired_wheel_dir)
shell(repair_command_prepared, env=env) shell(repair_command_prepared, env=env)
else: else:
@@ -258,6 +271,7 @@ def build(options: BuildOptions) -> None:
repaired_wheel = next(repaired_wheel_dir.glob('*.whl')) repaired_wheel = next(repaired_wheel_dir.glob('*.whl'))
if options.test_command: if options.test_command:
log.step('Testing wheel...')
# set up a virtual environment to install and test from, to make sure # set up a virtual environment to install and test from, to make sure
# there are no dependencies that were pulled in at build time. # there are no dependencies that were pulled in at build time.
call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env) call(['pip', 'install', 'virtualenv', *dependency_constraint_flags], env=env)
@@ -306,3 +320,7 @@ def build(options: BuildOptions) -> None:
# we're all done here; move it to output (remove if already exists) # we're all done here; move it to output (remove if already exists)
shutil.move(str(repaired_wheel), options.output_dir) shutil.move(str(repaired_wheel), options.output_dir)
log.build_end()
except subprocess.CalledProcessError as error:
log.error(f'Command {error.cmd} failed with code {error.returncode}. {error.stdout}')
exit(1)