From fc2906454bd3adffb621b73020b8db17afb80018 Mon Sep 17 00:00:00 2001 From: Henry Schreiner Date: Sat, 13 Nov 2021 14:30:22 -0500 Subject: [PATCH] refactor: use passenv on Docker --- cibuildwheel/docker_container.py | 12 ++++++++++-- cibuildwheel/environment.py | 3 --- cibuildwheel/linux.py | 10 ++++++++-- cibuildwheel/options.py | 12 +++--------- unit_test/options_test.py | 2 +- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/cibuildwheel/docker_container.py b/cibuildwheel/docker_container.py index 1fbf80a99..6c8e91e63 100644 --- a/cibuildwheel/docker_container.py +++ b/cibuildwheel/docker_container.py @@ -7,7 +7,7 @@ import uuid from pathlib import Path, PurePath from types import TracebackType -from typing import IO, Dict, List, Optional, Sequence, Type, cast +from typing import IO, Dict, List, Optional, Sequence, Tuple, Type, cast from .typing import PathOrStr, PopenBytes @@ -31,7 +31,12 @@ class DockerContainer: bash_stdout: IO[bytes] def __init__( - self, *, docker_image: str, simulate_32_bit: bool = False, cwd: Optional[PathOrStr] = None + self, + *, + docker_image: str, + simulate_32_bit: bool = False, + cwd: Optional[PathOrStr] = None, + passenv: Tuple[str, ...] = (), ): if not docker_image: raise ValueError("Must have a non-empty docker image to run.") @@ -40,16 +45,19 @@ def __init__( self.simulate_32_bit = simulate_32_bit self.cwd = cwd self.name: Optional[str] = None + self.passenv = passenv def __enter__(self) -> "DockerContainer": self.name = f"cibuildwheel-{uuid.uuid4()}" cwd_args = ["-w", str(self.cwd)] if self.cwd else [] shell_args = ["linux32", "/bin/bash"] if self.simulate_32_bit else ["/bin/bash"] + passenv = (f"--env={name}" for name in self.passenv) subprocess.run( [ "docker", "create", "--env=CIBUILDWHEEL", + *passenv, f"--name={self.name}", "--interactive", "--volume=/:/host", # ignored on CircleCI diff --git a/cibuildwheel/environment.py b/cibuildwheel/environment.py index 6ca4c5d14..748398c54 100644 --- a/cibuildwheel/environment.py +++ b/cibuildwheel/environment.py @@ -84,9 +84,6 @@ def as_dictionary( return environment - def add(self, name: str, value: str) -> None: - self.assignments.append(EnvironmentAssignment(f'{name}="{value}"')) - def as_shell_commands(self) -> List[str]: return [a.as_shell_assignment() for a in self.assignments] diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 4031e038d..e28b7792a 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -32,6 +32,7 @@ class BuildStep(NamedTuple): platform_configs: List[PythonConfiguration] platform_tag: str docker_image: str + passenv: Tuple[str, ...] def get_python_configurations( @@ -85,15 +86,19 @@ def get_build_steps( _, platform_tag = config.identifier.split("-", 1) before_all = options.build_options(config.identifier).before_all + passenv = options.build_options(config.identifier).passenv docker_image = docker_image_for_python_configuration(config, options) - step_key = (platform_tag, docker_image, before_all) + step_key = (platform_tag, docker_image, before_all, passenv) if step_key in steps: steps[step_key].platform_configs.append(config) else: steps[step_key] = BuildStep( - platform_configs=[config], platform_tag=platform_tag, docker_image=docker_image + platform_configs=[config], + platform_tag=platform_tag, + docker_image=docker_image, + passenv=passenv, ) yield from steps.values() @@ -339,6 +344,7 @@ def build(options: Options) -> None: docker_image=build_step.docker_image, simulate_32_bit=build_step.platform_tag.endswith("i686"), cwd=container_project_path, + passenv=build_step.passenv, ) as docker: build_on_docker( diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 32cabb6d3..ee8961594 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -60,6 +60,7 @@ class GlobalOptions(NamedTuple): class BuildOptions(NamedTuple): globals: GlobalOptions environment: ParsedEnvironment + passenv: Tuple[str, ...] before_all: str before_build: Optional[str] repair_command: str @@ -408,7 +409,7 @@ def build_options(self, identifier: Optional[str]) -> BuildOptions: environment_config = self.reader.get( "environment", table={"item": '{k}="{v}"', "sep": " "} ) - passenv = self.reader.get("passenv", sep=",").split(",") + passenv = tuple(self.reader.get("passenv", sep=",").split(" ")) before_build = self.reader.get("before-build", sep=" && ") repair_command = self.reader.get("repair-wheel-command", sep=" && ") @@ -439,14 +440,6 @@ def build_options(self, identifier: Optional[str]) -> BuildOptions: traceback.print_exc(None, sys.stderr) sys.exit(2) - # Pass through environment variables - if self.platform == "linux": - for passedenv in passenv: - try: - environment.add(passedenv, os.environ[passedenv]) - except KeyError: - pass - if dependency_versions == "pinned": dependency_constraints: Optional[ DependencyConstraints @@ -515,6 +508,7 @@ def build_options(self, identifier: Optional[str]) -> BuildOptions: build_verbosity=build_verbosity, repair_command=repair_command, environment=environment, + passenv=passenv, dependency_constraints=dependency_constraints, manylinux_images=manylinux_images or None, musllinux_images=musllinux_images or None, diff --git a/unit_test/options_test.py b/unit_test/options_test.py index 68b44d526..e8b6d12ec 100644 --- a/unit_test/options_test.py +++ b/unit_test/options_test.py @@ -85,4 +85,4 @@ def test_passthrough(tmp_path, monkeypatch): default_build_options = options.build_options(identifier=None) - assert default_build_options.environment == parse_environment('FOO="BAR" EXAMPLE_ENV="ONE"') + assert default_build_options.passenv == ("EXAMPLE_ENV",)