Make container-engine a build (non-global) option (#1792)
This commit is contained in:
@@ -247,7 +247,6 @@ for key, value in schema["properties"].items():
|
|||||||
non_global_options = {k: {"$ref": f"#/properties/{k}"} for k in schema["properties"]}
|
non_global_options = {k: {"$ref": f"#/properties/{k}"} for k in schema["properties"]}
|
||||||
del non_global_options["build"]
|
del non_global_options["build"]
|
||||||
del non_global_options["skip"]
|
del non_global_options["skip"]
|
||||||
del non_global_options["container-engine"]
|
|
||||||
del non_global_options["test-skip"]
|
del non_global_options["test-skip"]
|
||||||
|
|
||||||
overrides["items"]["properties"]["select"]["oneOf"] = string_array
|
overrides["items"]["properties"]["select"]["oneOf"] = string_array
|
||||||
@@ -258,6 +257,7 @@ del overrides["items"]["properties"]["archs"]
|
|||||||
not_linux = non_global_options.copy()
|
not_linux = non_global_options.copy()
|
||||||
|
|
||||||
del not_linux["environment-pass"]
|
del not_linux["environment-pass"]
|
||||||
|
del not_linux["container-engine"]
|
||||||
for key in list(not_linux):
|
for key in list(not_linux):
|
||||||
if "linux-" in key:
|
if "linux-" in key:
|
||||||
del not_linux[key]
|
del not_linux[key]
|
||||||
|
|||||||
+38
-32
@@ -11,8 +11,8 @@ from typing import OrderedDict, Tuple
|
|||||||
from ._compat.typing import assert_never
|
from ._compat.typing import assert_never
|
||||||
from .architecture import Architecture
|
from .architecture import Architecture
|
||||||
from .logger import log
|
from .logger import log
|
||||||
from .oci_container import OCIContainer
|
from .oci_container import OCIContainer, OCIContainerEngineConfig
|
||||||
from .options import Options
|
from .options import BuildOptions, Options
|
||||||
from .typing import PathOrStr
|
from .typing import PathOrStr
|
||||||
from .util import (
|
from .util import (
|
||||||
AlreadyBuiltWheelError,
|
AlreadyBuiltWheelError,
|
||||||
@@ -44,6 +44,7 @@ class PythonConfiguration:
|
|||||||
class BuildStep:
|
class BuildStep:
|
||||||
platform_configs: list[PythonConfiguration]
|
platform_configs: list[PythonConfiguration]
|
||||||
platform_tag: str
|
platform_tag: str
|
||||||
|
container_engine: OCIContainerEngineConfig
|
||||||
container_image: str
|
container_image: str
|
||||||
|
|
||||||
|
|
||||||
@@ -65,8 +66,9 @@ def get_python_configurations(
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
def container_image_for_python_configuration(config: PythonConfiguration, options: Options) -> str:
|
def container_image_for_python_configuration(
|
||||||
build_options = options.build_options(config.identifier)
|
config: PythonConfiguration, build_options: BuildOptions
|
||||||
|
) -> str:
|
||||||
# e.g
|
# e.g
|
||||||
# identifier is 'cp310-manylinux_x86_64'
|
# identifier is 'cp310-manylinux_x86_64'
|
||||||
# platform_tag is 'manylinux_x86_64'
|
# platform_tag is 'manylinux_x86_64'
|
||||||
@@ -91,15 +93,18 @@ def get_build_steps(
|
|||||||
Groups PythonConfigurations into BuildSteps. Each BuildStep represents a
|
Groups PythonConfigurations into BuildSteps. Each BuildStep represents a
|
||||||
separate container instance.
|
separate container instance.
|
||||||
"""
|
"""
|
||||||
steps = OrderedDict[Tuple[str, str, str], BuildStep]()
|
steps = OrderedDict[Tuple[str, str, str, OCIContainerEngineConfig], BuildStep]()
|
||||||
|
|
||||||
for config in python_configurations:
|
for config in python_configurations:
|
||||||
_, platform_tag = config.identifier.split("-", 1)
|
_, platform_tag = config.identifier.split("-", 1)
|
||||||
|
|
||||||
before_all = options.build_options(config.identifier).before_all
|
build_options = options.build_options(config.identifier)
|
||||||
container_image = container_image_for_python_configuration(config, options)
|
|
||||||
|
|
||||||
step_key = (platform_tag, container_image, before_all)
|
before_all = build_options.before_all
|
||||||
|
container_image = container_image_for_python_configuration(config, build_options)
|
||||||
|
container_engine = build_options.container_engine
|
||||||
|
|
||||||
|
step_key = (platform_tag, container_image, before_all, container_engine)
|
||||||
|
|
||||||
if step_key in steps:
|
if step_key in steps:
|
||||||
steps[step_key].platform_configs.append(config)
|
steps[step_key].platform_configs.append(config)
|
||||||
@@ -107,6 +112,7 @@ def get_build_steps(
|
|||||||
steps[step_key] = BuildStep(
|
steps[step_key] = BuildStep(
|
||||||
platform_configs=[config],
|
platform_configs=[config],
|
||||||
platform_tag=platform_tag,
|
platform_tag=platform_tag,
|
||||||
|
container_engine=container_engine,
|
||||||
container_image=container_image,
|
container_image=container_image,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -388,29 +394,6 @@ def build_in_container(
|
|||||||
|
|
||||||
|
|
||||||
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
||||||
try:
|
|
||||||
# check the container engine is installed
|
|
||||||
subprocess.run(
|
|
||||||
[options.globals.container_engine.name, "--version"],
|
|
||||||
check=True,
|
|
||||||
stdout=subprocess.DEVNULL,
|
|
||||||
)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print(
|
|
||||||
unwrap(
|
|
||||||
f"""
|
|
||||||
cibuildwheel: {options.globals.container_engine} not found. An
|
|
||||||
OCI exe like Docker or Podman is required to run Linux builds.
|
|
||||||
If you're building on Travis CI, add `services: [docker]` to
|
|
||||||
your .travis.yml. If you're building on Circle CI in Linux,
|
|
||||||
add a `setup_remote_docker` step to your .circleci/config.yml.
|
|
||||||
If you're building on Cirrus CI, use `docker_builder` task.
|
|
||||||
"""
|
|
||||||
),
|
|
||||||
file=sys.stderr,
|
|
||||||
)
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
python_configurations = get_python_configurations(
|
python_configurations = get_python_configurations(
|
||||||
options.globals.build_selector, options.globals.architectures
|
options.globals.build_selector, options.globals.architectures
|
||||||
)
|
)
|
||||||
@@ -425,6 +408,29 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
|||||||
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)
|
container_package_dir = container_project_path / abs_package_dir.relative_to(cwd)
|
||||||
|
|
||||||
for build_step in get_build_steps(options, python_configurations):
|
for build_step in get_build_steps(options, python_configurations):
|
||||||
|
try:
|
||||||
|
# check the container engine is installed
|
||||||
|
subprocess.run(
|
||||||
|
[build_step.container_engine.name, "--version"],
|
||||||
|
check=True,
|
||||||
|
stdout=subprocess.DEVNULL,
|
||||||
|
)
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
print(
|
||||||
|
unwrap(
|
||||||
|
f"""
|
||||||
|
cibuildwheel: {build_step.container_engine.name} not found. An
|
||||||
|
OCI exe like Docker or Podman is required to run Linux builds.
|
||||||
|
If you're building on Travis CI, add `services: [docker]` to
|
||||||
|
your .travis.yml. If you're building on Circle CI in Linux,
|
||||||
|
add a `setup_remote_docker` step to your .circleci/config.yml.
|
||||||
|
If you're building on Cirrus CI, use `docker_builder` task.
|
||||||
|
"""
|
||||||
|
),
|
||||||
|
file=sys.stderr,
|
||||||
|
)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
ids_to_build = [x.identifier for x in build_step.platform_configs]
|
ids_to_build = [x.identifier for x in build_step.platform_configs]
|
||||||
log.step(f"Starting container image {build_step.container_image}...")
|
log.step(f"Starting container image {build_step.container_image}...")
|
||||||
@@ -435,7 +441,7 @@ def build(options: Options, tmp_path: Path) -> None: # noqa: ARG001
|
|||||||
image=build_step.container_image,
|
image=build_step.container_image,
|
||||||
enforce_32_bit=build_step.platform_tag.endswith("i686"),
|
enforce_32_bit=build_step.platform_tag.endswith("i686"),
|
||||||
cwd=container_project_path,
|
cwd=container_project_path,
|
||||||
engine=options.globals.container_engine,
|
engine=build_step.container_engine,
|
||||||
) as container:
|
) as container:
|
||||||
build_in_container(
|
build_in_container(
|
||||||
options=options,
|
options=options,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import sys
|
|||||||
import typing
|
import typing
|
||||||
import uuid
|
import uuid
|
||||||
from collections.abc import Mapping, Sequence
|
from collections.abc import Mapping, Sequence
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path, PurePath, PurePosixPath
|
from pathlib import Path, PurePath, PurePosixPath
|
||||||
from types import TracebackType
|
from types import TracebackType
|
||||||
from typing import IO, Dict, Literal
|
from typing import IO, Dict, Literal
|
||||||
@@ -32,7 +32,7 @@ ContainerEngineName = Literal["docker", "podman"]
|
|||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
class OCIContainerEngineConfig:
|
class OCIContainerEngineConfig:
|
||||||
name: ContainerEngineName
|
name: ContainerEngineName
|
||||||
create_args: Sequence[str] = ()
|
create_args: tuple[str, ...] = field(default_factory=tuple)
|
||||||
disable_host_mount: bool = False
|
disable_host_mount: bool = False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@@ -58,7 +58,7 @@ class OCIContainerEngineConfig:
|
|||||||
)
|
)
|
||||||
|
|
||||||
return OCIContainerEngineConfig(
|
return OCIContainerEngineConfig(
|
||||||
name=name, create_args=create_args, disable_host_mount=disable_host_mount
|
name=name, create_args=tuple(create_args), disable_host_mount=disable_host_mount
|
||||||
)
|
)
|
||||||
|
|
||||||
def options_summary(self) -> str | dict[str, str]:
|
def options_summary(self) -> str | dict[str, str]:
|
||||||
|
|||||||
+16
-14
@@ -75,7 +75,6 @@ class GlobalOptions:
|
|||||||
build_selector: BuildSelector
|
build_selector: BuildSelector
|
||||||
test_selector: TestSelector
|
test_selector: TestSelector
|
||||||
architectures: set[Architecture]
|
architectures: set[Architecture]
|
||||||
container_engine: OCIContainerEngineConfig
|
|
||||||
|
|
||||||
|
|
||||||
@dataclasses.dataclass(frozen=True)
|
@dataclasses.dataclass(frozen=True)
|
||||||
@@ -95,6 +94,7 @@ class BuildOptions:
|
|||||||
build_verbosity: int
|
build_verbosity: int
|
||||||
build_frontend: BuildFrontendConfig | None
|
build_frontend: BuildFrontendConfig | None
|
||||||
config_settings: str
|
config_settings: str
|
||||||
|
container_engine: OCIContainerEngineConfig
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def package_dir(self) -> Path:
|
def package_dir(self) -> Path:
|
||||||
@@ -545,25 +545,12 @@ class Options:
|
|||||||
)
|
)
|
||||||
test_selector = TestSelector(skip_config=test_skip)
|
test_selector = TestSelector(skip_config=test_skip)
|
||||||
|
|
||||||
container_engine_str = self.reader.get(
|
|
||||||
"container-engine",
|
|
||||||
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
|
||||||
)
|
|
||||||
|
|
||||||
try:
|
|
||||||
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
|
|
||||||
except ValueError as e:
|
|
||||||
msg = f"cibuildwheel: Failed to parse container config. {e}"
|
|
||||||
print(msg, file=sys.stderr)
|
|
||||||
sys.exit(2)
|
|
||||||
|
|
||||||
return GlobalOptions(
|
return GlobalOptions(
|
||||||
package_dir=package_dir,
|
package_dir=package_dir,
|
||||||
output_dir=output_dir,
|
output_dir=output_dir,
|
||||||
build_selector=build_selector,
|
build_selector=build_selector,
|
||||||
test_selector=test_selector,
|
test_selector=test_selector,
|
||||||
architectures=architectures,
|
architectures=architectures,
|
||||||
container_engine=container_engine,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def build_options(self, identifier: str | None) -> BuildOptions:
|
def build_options(self, identifier: str | None) -> BuildOptions:
|
||||||
@@ -643,6 +630,8 @@ class Options:
|
|||||||
|
|
||||||
manylinux_images: dict[str, str] = {}
|
manylinux_images: dict[str, str] = {}
|
||||||
musllinux_images: dict[str, str] = {}
|
musllinux_images: dict[str, str] = {}
|
||||||
|
container_engine: OCIContainerEngineConfig | None = None
|
||||||
|
|
||||||
if self.platform == "linux":
|
if self.platform == "linux":
|
||||||
all_pinned_container_images = _get_pinned_container_images()
|
all_pinned_container_images = _get_pinned_container_images()
|
||||||
|
|
||||||
@@ -677,6 +666,18 @@ class Options:
|
|||||||
|
|
||||||
musllinux_images[build_platform] = image
|
musllinux_images[build_platform] = image
|
||||||
|
|
||||||
|
container_engine_str = self.reader.get(
|
||||||
|
"container-engine",
|
||||||
|
table_format={"item": "{k}:{v}", "sep": "; ", "quote": shlex.quote},
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
container_engine = OCIContainerEngineConfig.from_config_string(container_engine_str)
|
||||||
|
except ValueError as e:
|
||||||
|
msg = f"cibuildwheel: Failed to parse container config. {e}"
|
||||||
|
print(msg, file=sys.stderr)
|
||||||
|
sys.exit(2)
|
||||||
|
|
||||||
return BuildOptions(
|
return BuildOptions(
|
||||||
globals=self.globals,
|
globals=self.globals,
|
||||||
test_command=test_command,
|
test_command=test_command,
|
||||||
@@ -693,6 +694,7 @@ class Options:
|
|||||||
musllinux_images=musllinux_images or None,
|
musllinux_images=musllinux_images or None,
|
||||||
build_frontend=build_frontend,
|
build_frontend=build_frontend,
|
||||||
config_settings=config_settings,
|
config_settings=config_settings,
|
||||||
|
container_engine=container_engine,
|
||||||
)
|
)
|
||||||
|
|
||||||
def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None:
|
def check_for_invalid_configuration(self, identifiers: Iterable[str]) -> None:
|
||||||
|
|||||||
@@ -491,6 +491,9 @@
|
|||||||
"config-settings": {
|
"config-settings": {
|
||||||
"$ref": "#/properties/config-settings"
|
"$ref": "#/properties/config-settings"
|
||||||
},
|
},
|
||||||
|
"container-engine": {
|
||||||
|
"$ref": "#/properties/container-engine"
|
||||||
|
},
|
||||||
"dependency-versions": {
|
"dependency-versions": {
|
||||||
"$ref": "#/properties/dependency-versions"
|
"$ref": "#/properties/dependency-versions"
|
||||||
},
|
},
|
||||||
@@ -579,6 +582,9 @@
|
|||||||
"config-settings": {
|
"config-settings": {
|
||||||
"$ref": "#/properties/config-settings"
|
"$ref": "#/properties/config-settings"
|
||||||
},
|
},
|
||||||
|
"container-engine": {
|
||||||
|
"$ref": "#/properties/container-engine"
|
||||||
|
},
|
||||||
"environment": {
|
"environment": {
|
||||||
"$ref": "#/properties/environment"
|
"$ref": "#/properties/environment"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ from pathlib import Path
|
|||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
import cibuildwheel.linux
|
import cibuildwheel.linux
|
||||||
import cibuildwheel.oci_container
|
from cibuildwheel.oci_container import OCIContainerEngineConfig
|
||||||
from cibuildwheel.options import CommandLineArguments, Options
|
from cibuildwheel.options import CommandLineArguments, Options
|
||||||
|
|
||||||
|
|
||||||
def test_linux_container_split(tmp_path: Path, monkeypatch):
|
def test_linux_container_split(tmp_path: Path, monkeypatch):
|
||||||
"""
|
"""
|
||||||
Tests splitting linux builds by container image and before_all
|
Tests splitting linux builds by container image, container engine, and before_all
|
||||||
"""
|
"""
|
||||||
|
|
||||||
args = CommandLineArguments.defaults()
|
args = CommandLineArguments.defaults()
|
||||||
@@ -28,13 +28,17 @@ def test_linux_container_split(tmp_path: Path, monkeypatch):
|
|||||||
archs = "x86_64 i686"
|
archs = "x86_64 i686"
|
||||||
|
|
||||||
[[tool.cibuildwheel.overrides]]
|
[[tool.cibuildwheel.overrides]]
|
||||||
select = "cp{38,39,310}-*"
|
select = "cp{37,38,39,310}-*"
|
||||||
manylinux-x86_64-image = "other_container_image"
|
manylinux-x86_64-image = "other_container_image"
|
||||||
manylinux-i686-image = "other_container_image"
|
manylinux-i686-image = "other_container_image"
|
||||||
|
|
||||||
[[tool.cibuildwheel.overrides]]
|
[[tool.cibuildwheel.overrides]]
|
||||||
select = "cp39-*"
|
select = "cp39-*"
|
||||||
before-all = "echo 'a cp39-only command'"
|
before-all = "echo 'a cp39-only command'"
|
||||||
|
|
||||||
|
[[tool.cibuildwheel.overrides]]
|
||||||
|
select = "cp310-*"
|
||||||
|
container-engine = "docker; create_args: --privileged"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -55,21 +59,35 @@ def test_linux_container_split(tmp_path: Path, monkeypatch):
|
|||||||
def before_alls(step):
|
def before_alls(step):
|
||||||
return [options.build_options(c.identifier).before_all for c in step.platform_configs]
|
return [options.build_options(c.identifier).before_all for c in step.platform_configs]
|
||||||
|
|
||||||
|
def container_engines(step):
|
||||||
|
return [options.build_options(c.identifier).container_engine for c in step.platform_configs]
|
||||||
|
|
||||||
pprint(build_steps)
|
pprint(build_steps)
|
||||||
|
|
||||||
|
default_container_engine = OCIContainerEngineConfig(name="docker")
|
||||||
|
|
||||||
assert build_steps[0].container_image == "normal_container_image"
|
assert build_steps[0].container_image == "normal_container_image"
|
||||||
assert identifiers(build_steps[0]) == [
|
assert identifiers(build_steps[0]) == [
|
||||||
"cp36-manylinux_x86_64",
|
"cp36-manylinux_x86_64",
|
||||||
"cp37-manylinux_x86_64",
|
|
||||||
"cp311-manylinux_x86_64",
|
"cp311-manylinux_x86_64",
|
||||||
"cp312-manylinux_x86_64",
|
"cp312-manylinux_x86_64",
|
||||||
]
|
]
|
||||||
assert before_alls(build_steps[0]) == ["", "", "", ""]
|
assert before_alls(build_steps[0]) == [""] * 3
|
||||||
|
assert container_engines(build_steps[0]) == [default_container_engine] * 3
|
||||||
|
|
||||||
assert build_steps[1].container_image == "other_container_image"
|
assert build_steps[1].container_image == "other_container_image"
|
||||||
assert identifiers(build_steps[1]) == ["cp38-manylinux_x86_64", "cp310-manylinux_x86_64"]
|
assert identifiers(build_steps[1]) == ["cp37-manylinux_x86_64", "cp38-manylinux_x86_64"]
|
||||||
assert before_alls(build_steps[1]) == ["", ""]
|
assert before_alls(build_steps[1]) == [""] * 2
|
||||||
|
assert container_engines(build_steps[1]) == [default_container_engine] * 2
|
||||||
|
|
||||||
assert build_steps[2].container_image == "other_container_image"
|
assert build_steps[2].container_image == "other_container_image"
|
||||||
assert identifiers(build_steps[2]) == ["cp39-manylinux_x86_64"]
|
assert identifiers(build_steps[2]) == ["cp39-manylinux_x86_64"]
|
||||||
assert before_alls(build_steps[2]) == ["echo 'a cp39-only command'"]
|
assert before_alls(build_steps[2]) == ["echo 'a cp39-only command'"]
|
||||||
|
assert container_engines(build_steps[2]) == [default_container_engine]
|
||||||
|
|
||||||
|
assert build_steps[3].container_image == "other_container_image"
|
||||||
|
assert identifiers(build_steps[3]) == ["cp310-manylinux_x86_64"]
|
||||||
|
assert before_alls(build_steps[3]) == [""]
|
||||||
|
assert container_engines(build_steps[3]) == [
|
||||||
|
OCIContainerEngineConfig(name="docker", create_args=("--privileged",))
|
||||||
|
]
|
||||||
|
|||||||
@@ -340,7 +340,7 @@ def test_create_args_volume(tmp_path: Path, container_engine):
|
|||||||
test_mount_dir.mkdir()
|
test_mount_dir.mkdir()
|
||||||
(test_mount_dir / "test_file.txt").write_text("1234")
|
(test_mount_dir / "test_file.txt").write_text("1234")
|
||||||
container_engine = OCIContainerEngineConfig(
|
container_engine = OCIContainerEngineConfig(
|
||||||
name="docker", create_args=[f"--volume={test_mount_dir}:/test_mount"]
|
name="docker", create_args=(f"--volume={test_mount_dir}:/test_mount",)
|
||||||
)
|
)
|
||||||
|
|
||||||
with OCIContainer(
|
with OCIContainer(
|
||||||
@@ -356,37 +356,37 @@ def test_create_args_volume(tmp_path: Path, container_engine):
|
|||||||
(
|
(
|
||||||
"docker",
|
"docker",
|
||||||
"docker",
|
"docker",
|
||||||
[],
|
(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"docker;create_args:",
|
"docker;create_args:",
|
||||||
"docker",
|
"docker",
|
||||||
[],
|
(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"docker;create_args:--abc --def",
|
"docker;create_args:--abc --def",
|
||||||
"docker",
|
"docker",
|
||||||
["--abc", "--def"],
|
("--abc", "--def"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"docker; create_args: --abc --def",
|
"docker; create_args: --abc --def",
|
||||||
"docker",
|
"docker",
|
||||||
["--abc", "--def"],
|
("--abc", "--def"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
"name:docker; create_args: --abc --def",
|
"name:docker; create_args: --abc --def",
|
||||||
"docker",
|
"docker",
|
||||||
["--abc", "--def"],
|
("--abc", "--def"),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'docker; create_args: --some-option="value with spaces"',
|
'docker; create_args: --some-option="value with spaces"',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option=value with spaces"],
|
("--some-option=value with spaces",),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'docker; create_args: --some-option="value; with; semicolons" --another-option',
|
'docker; create_args: --some-option="value; with; semicolons" --another-option',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option=value; with; semicolons", "--another-option"],
|
("--some-option=value; with; semicolons", "--another-option"),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -206,49 +206,49 @@ def test_toml_environment_quoting(tmp_path: Path, toml_assignment, result_value)
|
|||||||
(
|
(
|
||||||
'container-engine = "podman"',
|
'container-engine = "podman"',
|
||||||
"podman",
|
"podman",
|
||||||
[],
|
(),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "podman"}',
|
'container-engine = {name = "podman"}',
|
||||||
"podman",
|
"podman",
|
||||||
[],
|
(),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = "docker; create_args: --some-option"',
|
'container-engine = "docker; create_args: --some-option"',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option"],
|
("--some-option",),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "docker", create-args = ["--some-option"]}',
|
'container-engine = {name = "docker", create-args = ["--some-option"]}',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option"],
|
("--some-option",),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "docker", create-args = ["--some-option", "value that contains spaces"]}',
|
'container-engine = {name = "docker", create-args = ["--some-option", "value that contains spaces"]}',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option", "value that contains spaces"],
|
("--some-option", "value that contains spaces"),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "docker", create-args = ["--some-option", "value;that;contains;semicolons"]}',
|
'container-engine = {name = "docker", create-args = ["--some-option", "value;that;contains;semicolons"]}',
|
||||||
"docker",
|
"docker",
|
||||||
["--some-option", "value;that;contains;semicolons"],
|
("--some-option", "value;that;contains;semicolons"),
|
||||||
False,
|
False,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "docker", disable-host-mount = true}',
|
'container-engine = {name = "docker", disable-host-mount = true}',
|
||||||
"docker",
|
"docker",
|
||||||
[],
|
(),
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'container-engine = {name = "docker", disable_host_mount = true}',
|
'container-engine = {name = "docker", disable_host_mount = true}',
|
||||||
"docker",
|
"docker",
|
||||||
[],
|
(),
|
||||||
True,
|
True,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -269,7 +269,7 @@ def test_container_engine_option(
|
|||||||
)
|
)
|
||||||
|
|
||||||
options = Options(platform="linux", command_line_arguments=args, env={})
|
options = Options(platform="linux", command_line_arguments=args, env={})
|
||||||
parsed_container_engine = options.globals.container_engine
|
parsed_container_engine = options.build_options(None).container_engine
|
||||||
|
|
||||||
assert parsed_container_engine.name == result_name
|
assert parsed_container_engine.name == result_name
|
||||||
assert parsed_container_engine.create_args == result_create_args
|
assert parsed_container_engine.create_args == result_create_args
|
||||||
|
|||||||
@@ -20,11 +20,39 @@ def test_validate_default_schema():
|
|||||||
assert validator(example) is not None
|
assert validator(example) is not None
|
||||||
|
|
||||||
|
|
||||||
def test_validate_bad_container_engine():
|
def test_validate_container_engine():
|
||||||
|
"""
|
||||||
|
This test checks container engine can be overridden - it used to be a
|
||||||
|
global option but is now a build option.
|
||||||
|
"""
|
||||||
|
|
||||||
example = tomllib.loads(
|
example = tomllib.loads(
|
||||||
"""
|
"""
|
||||||
|
[tool.cibuildwheel]
|
||||||
|
container-engine = "docker"
|
||||||
|
|
||||||
[tool.cibuildwheel.linux]
|
[tool.cibuildwheel.linux]
|
||||||
container-engine = "docker"
|
container-engine = "docker"
|
||||||
|
|
||||||
|
[[tool.cibuildwheel.overrides]]
|
||||||
|
select = "*_x86_64"
|
||||||
|
container-engine = "docker; create_args: --platform linux/arm64/v8"
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
validator = validate_pyproject.api.Validator()
|
||||||
|
assert validator(example) is not None
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("platform", ["macos", "windows"])
|
||||||
|
def test_validate_bad_container_engine(platform: str):
|
||||||
|
"""
|
||||||
|
container-engine is not a valid option for macos or windows
|
||||||
|
"""
|
||||||
|
example = tomllib.loads(
|
||||||
|
f"""
|
||||||
|
[tool.cibuildwheel.{platform}]
|
||||||
|
container-engine = "docker"
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user