Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add schema and validate-pyproject support #1622

Merged
merged 4 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ repos:
hooks:
- id: mypy
name: mypy 3.8 on cibuildwheel/
exclude: ^cibuildwheel/resources/.*py$
exclude: ^cibuildwheel/resources/.*py|bin/generate_schema.py$
args: ["--python-version=3.8"]
additional_dependencies: &mypy-dependencies
- bracex
- nox
- packaging
- pygithub
Expand All @@ -49,7 +50,7 @@ repos:
- types-jinja2
- types-pyyaml
- types-requests
- bracex
- validate-pyproject
- id: mypy
name: mypy 3.11
exclude: ^cibuildwheel/resources/.*py$
Expand Down
263 changes: 263 additions & 0 deletions bin/generate_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,263 @@
#!/usr/bin/env python

import copy
import json
from typing import Any

import yaml

starter = """
$id: https://github.com/pypa/cibuildwheel/blob/main/cibuildwheel/resources/cibuildwheel.schema.json
$schema: http://json-schema.org/draft-07/schema
additionalProperties: false
description: cibuildwheel's settings.
type: object
properties:
archs:
description: Change the architectures built on your machine by default.
type: string_array
before-all:
description: Execute a shell command on the build system before any wheels are built.
type: string_array
before-build:
description: Execute a shell command preparing each wheel's build.
type: string_array
before-test:
description: Execute a shell command before testing each wheel.
type: string_array
build:
default: ['*']
description: Choose the Python versions to build.
type: string_array
build-frontend:
default: default
description: Set the tool to use to build, either "pip" (default for now) or "build"
oneOf:
- enum: [pip, build, default]
- type: string
pattern: '^pip; ?args:'
- type: string
pattern: '^build; ?args:'
- type: object
additionalProperties: false
required: [name]
properties:
name:
enum: [pip, build]
args:
type: array
items:
type: string
build-verbosity:
type: integer
minimum: -3
maximum: 3
default: 0
description: Increase/decrease the output of pip wheel.
config-settings:
description: Specify config-settings for the build backend.
type: string_table_array
container-engine:
oneOf:
- enum: [docker, podman]
- type: string
pattern: '^docker; ?create_args:'
- type: string
pattern: '^podman; ?create_args:'
- type: object
additionalProperties: false
required: [name]
properties:
name:
enum: [docker, podman]
create-args:
type: array
items:
type: string
dependency-versions:
default: pinned
description: Specify how cibuildwheel controls the versions of the tools it uses
type: string
environment:
description: Set environment variables needed during the build.
type: string_table
environment-pass:
description: Set environment variables on the host to pass-through to the container
during the build.
type: string_array
manylinux-aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-ppc64le-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-pypy_x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-s390x-image:
type: string
description: Specify alternative manylinux / musllinux container images
manylinux-x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-aarch64-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-i686-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-ppc64le-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-s390x-image:
type: string
description: Specify alternative manylinux / musllinux container images
musllinux-x86_64-image:
type: string
description: Specify alternative manylinux / musllinux container images
repair-wheel-command:
type: string_array
description: Execute a shell command to repair each built wheel.
skip:
description: Choose the Python versions to skip.
type: string_array
test-command:
description: Execute a shell command to test each built wheel.
type: string_array
test-extras:
description: Install your wheel for testing using `extras_require`
type: string_array
test-requires:
description: Install Python dependencies before running the tests
type: string_array
test-skip:
description: Skip running tests on some builds.
type: string_array
"""

schema = yaml.safe_load(starter)

string_array = yaml.safe_load(
"""
- type: string
- type: array
items:
type: string
"""
)

string_table_array = yaml.safe_load(
"""
- type: string
- type: object
additionalProperties: false
patternProperties:
.+:
oneOf:
- type: string
- type: array
items:
type: string
"""
)

string_table = yaml.safe_load(
"""
- type: string
- type: object
additionalProperties: false
patternProperties:
.+:
- type: string
"""
)

for value in schema["properties"].values():
match value:
case {"type": "string_array"}:
del value["type"]
value["oneOf"] = string_array
case {"type": "string_table"}:
del value["type"]
value["oneOf"] = string_table
case {"type": "string_table_array"}:
del value["type"]
value["oneOf"] = string_table_array

overrides = yaml.safe_load(
"""
type: array
description: An overrides array
items:
type: object
required: ["select"]
additionalProperties: false
properties:
select: {}
"""
)

non_global_options = copy.deepcopy(schema["properties"])
del non_global_options["build"]
del non_global_options["skip"]
del non_global_options["container-engine"]
del non_global_options["test-skip"]

henryiii marked this conversation as resolved.
Show resolved Hide resolved
overrides["items"]["properties"]["select"]["oneOf"] = string_array
overrides["items"]["properties"] |= non_global_options.copy()

del overrides["items"]["properties"]["archs"]

not_linux = non_global_options.copy()

del not_linux["environment-pass"]
for key in list(not_linux):
if "linux-" in key:
del not_linux[key]


def as_object(d: dict[str, Any]) -> dict[str, Any]:
return {
"type": "object",
"additionalProperties": False,
"properties": copy.deepcopy(d),
}


oses = {
"linux": as_object(non_global_options),
"windows": as_object(not_linux),
"macos": as_object(not_linux),
}

oses["linux"]["properties"]["repair-wheel-command"][
"default"
] = "auditwheel repair -w {dest_dir} {wheel}"
oses["macos"]["properties"]["repair-wheel-command"][
"default"
] = "delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel}"

del oses["linux"]["properties"]["dependency-versions"]

schema["properties"]["overrides"] = overrides
schema["properties"] |= oses

for key, value in schema["properties"].items():
value["title"] = f'CIBW_{key.replace("-", "_").upper()}'
for key, value in schema["properties"]["linux"]["properties"].items():
value["title"] = f'CIBW_{key.replace("-", "_").upper()}_LINUX'
for key, value in schema["properties"]["macos"]["properties"].items():
value["title"] = f'CIBW_{key.replace("-", "_").upper()}_MACOS'
for key, value in schema["properties"]["windows"]["properties"].items():
value["title"] = f'CIBW_{key.replace("-", "_").upper()}_WINDOWS'

print(json.dumps(schema, indent=2))
6 changes: 3 additions & 3 deletions cibuildwheel/_compat/tomllib.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import sys

if sys.version_info >= (3, 11):
from tomllib import load
from tomllib import load, loads
else:
from tomli import load
from tomli import load, loads

__all__ = ("load",)
__all__ = ["load", "loads"]
Loading