diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 22315221..e8443a7f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -70,6 +70,12 @@ repos: language: python entry: bin/update_readme_changelog.py files: ^docs/changelog.md$ + - id: update-readme-options-table + name: Update README options table + language: python + entry: bin/update_readme_options_table.py --force + files: ^docs/options.md$ + pass_filenames: false - repo: https://github.com/codespell-project/codespell rev: v2.4.1 diff --git a/README.md b/README.md index 574a422e..d40d7af0 100644 --- a/README.md +++ b/README.md @@ -124,35 +124,44 @@ The following diagram summarises the steps that cibuildwheel takes on each platf Explore an interactive version of this diagram [in the docs](https://cibuildwheel.pypa.io/en/stable/#how-it-works). -Options -------- + + | | Option | Description | -|---|--------|-------------| -| **Build selection** | [`CIBW_PLATFORM`](https://cibuildwheel.pypa.io/en/stable/options/#platform) | Override the auto-detected target platform | -| | [`CIBW_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip)
[`CIBW_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) | Choose the Python versions to build | -| | [`CIBW_ARCHS`](https://cibuildwheel.pypa.io/en/stable/options/#archs) | Change the architectures built on your machine by default. | -| | [`CIBW_PROJECT_REQUIRES_PYTHON`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project | -| | [`CIBW_PRERELEASE_PYTHONS`](https://cibuildwheel.pypa.io/en/stable/options/#prerelease-pythons) | Enable building with pre-release versions of Python if available | -| **Build customization** | [`CIBW_BUILD_FRONTEND`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "pip" (default for now) or "build" | -| | [`CIBW_ENVIRONMENT`](https://cibuildwheel.pypa.io/en/stable/options/#environment) | Set environment variables needed during the build | -| | [`CIBW_ENVIRONMENT_PASS_LINUX`](https://cibuildwheel.pypa.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container during the build. | -| | [`CIBW_BEFORE_ALL`](https://cibuildwheel.pypa.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. | -| | [`CIBW_BEFORE_BUILD`](https://cibuildwheel.pypa.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build | -| | [`CIBW_XBUILD_TOOLS`](https://cibuildwheel.pypa.io/en/stable/options/#xbuild-tools) | Binaries on the path that should be included in an isolated cross-build environment. | -| | [`CIBW_REPAIR_WHEEL_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel | -| | [`CIBW_MANYLINUX_*_IMAGE`
`CIBW_MUSLLINUX_*_IMAGE`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) | Specify alternative manylinux / musllinux Docker images | -| | [`CIBW_CONTAINER_ENGINE`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) | Specify which container engine to use when building Linux wheels | -| | [`CIBW_DEPENDENCY_VERSIONS`](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions) | Specify how cibuildwheel controls the versions of the tools it uses | -| **Testing** | [`CIBW_TEST_COMMAND`](https://cibuildwheel.pypa.io/en/stable/options/#test-command) | Execute a shell command to test each built wheel | -| | [`CIBW_BEFORE_TEST`](https://cibuildwheel.pypa.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel | -| | [`CIBW_TEST_SOURCES`](https://cibuildwheel.pypa.io/en/stable/options/#test-sources) | Files and folders from the source tree that are copied into an isolated tree before running the tests | -| | [`CIBW_TEST_REQUIRES`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests | -| | [`CIBW_TEST_EXTRAS`](https://cibuildwheel.pypa.io/en/stable/options/#test-extras) | Install your wheel for testing using extras_require | -| | [`CIBW_TEST_SKIP`](https://cibuildwheel.pypa.io/en/stable/options/#test-skip) | Skip running tests on some builds | -| **Other** | [`CIBW_BUILD_VERBOSITY`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of pip wheel | +|---|---|---| +| **Build selection** | [`platform`](https://cibuildwheel.pypa.io/en/stable/options/#platform) | Override the auto-detected target platform | +| | [`build`
`skip`](https://cibuildwheel.pypa.io/en/stable/options/#build-skip) | Choose the Python versions to build | +| | [`archs`](https://cibuildwheel.pypa.io/en/stable/options/#archs) | Change the architectures built on your machine by default. | +| | [`project-requires-python`](https://cibuildwheel.pypa.io/en/stable/options/#requires-python) | Manually set the Python compatibility of your project | +| | [`enable`](https://cibuildwheel.pypa.io/en/stable/options/#enable) | Enable building with extra categories of selectors present. | +| | [`allow-empty`](https://cibuildwheel.pypa.io/en/stable/options/#allow-empty) | Suppress the error code if no wheels match the specified build identifiers | +| **Build customization** | [`build-frontend`](https://cibuildwheel.pypa.io/en/stable/options/#build-frontend) | Set the tool to use to build, either "build" (default), "build\[uv\]", or "pip" | +| | [`config-settings`](https://cibuildwheel.pypa.io/en/stable/options/#config-settings) | Specify config-settings for the build backend. | +| | [`environment`](https://cibuildwheel.pypa.io/en/stable/options/#environment) | Set environment variables | +| | [`environment-pass`](https://cibuildwheel.pypa.io/en/stable/options/#environment-pass) | Set environment variables on the host to pass-through to the container. | +| | [`before-all`](https://cibuildwheel.pypa.io/en/stable/options/#before-all) | Execute a shell command on the build system before any wheels are built. | +| | [`before-build`](https://cibuildwheel.pypa.io/en/stable/options/#before-build) | Execute a shell command preparing each wheel's build | +| | [`xbuild-tools`](https://cibuildwheel.pypa.io/en/stable/options/#xbuild-tools) | Binaries on the path that should be included in an isolated cross-build environment. | +| | [`repair-wheel-command`](https://cibuildwheel.pypa.io/en/stable/options/#repair-wheel-command) | Execute a shell command to repair each built wheel | +| | [`manylinux-*-image`
`musllinux-*-image`](https://cibuildwheel.pypa.io/en/stable/options/#linux-image) | Specify manylinux / musllinux container images | +| | [`container-engine`](https://cibuildwheel.pypa.io/en/stable/options/#container-engine) | Specify the container engine to use when building Linux wheels | +| | [`dependency-versions`](https://cibuildwheel.pypa.io/en/stable/options/#dependency-versions) | Control the versions of the tools cibuildwheel uses | +| | [`pyodide-version`](https://cibuildwheel.pypa.io/en/stable/options/#pyodide-version) | Specify the Pyodide version to use for `pyodide` platform builds | +| **Testing** | [`test-command`](https://cibuildwheel.pypa.io/en/stable/options/#test-command) | The command to test each built wheel | +| | [`before-test`](https://cibuildwheel.pypa.io/en/stable/options/#before-test) | Execute a shell command before testing each wheel | +| | [`test-sources`](https://cibuildwheel.pypa.io/en/stable/options/#test-sources) | Files and folders from the source tree that are copied into an isolated tree before running the tests | +| | [`test-requires`](https://cibuildwheel.pypa.io/en/stable/options/#test-requires) | Install Python dependencies before running the tests | +| | [`test-extras`](https://cibuildwheel.pypa.io/en/stable/options/#test-extras) | Install your wheel for testing using `extras_require` | +| | [`test-groups`](https://cibuildwheel.pypa.io/en/stable/options/#test-groups) | Specify test dependencies from your project's `dependency-groups` | +| | [`test-skip`](https://cibuildwheel.pypa.io/en/stable/options/#test-skip) | Skip running tests on some builds | +| | [`test-environment`](https://cibuildwheel.pypa.io/en/stable/options/#test-environment) | Set environment variables for the test environment | +| **Debugging** | [`debug-keep-container`](https://cibuildwheel.pypa.io/en/stable/options/#debug-keep-container) | Keep the container after running for debugging. | +| | [`debug-traceback`](https://cibuildwheel.pypa.io/en/stable/options/#debug-traceback) | Print full traceback when errors occur. | +| | [`build-verbosity`](https://cibuildwheel.pypa.io/en/stable/options/#build-verbosity) | Increase/decrease the output of the build | -These options can be specified in a pyproject.toml file, as well; see [configuration](https://cibuildwheel.pypa.io/en/stable/options/#configuration). + + +These options can be specified in a pyproject.toml file, or as environment variables, see [configuration docs](https://cibuildwheel.pypa.io/en/latest/configuration/). Working examples ---------------- diff --git a/bin/update_readme_options_table.py b/bin/update_readme_options_table.py new file mode 100755 index 00000000..f78cbeac --- /dev/null +++ b/bin/update_readme_options_table.py @@ -0,0 +1,98 @@ +#!/usr/bin/env python3 + +import argparse +import dataclasses +import re +from pathlib import Path +from typing import Final + +DIR: Final[Path] = Path(__file__).parent.parent.resolve() +README: Final[Path] = DIR / "README.md" +OPTIONS_MD: Final[Path] = DIR / "docs" / "options.md" + +SECTION_HEADER_REGEX = re.compile(r"^## (?P.*?)$", re.MULTILINE) + +# https://regexr.com/8f1ff +OPTION_HEADER_REGEX = re.compile( + r"^### (?P.*?){.*#(?P\S+).*}\n+> ?(?P.*)$", re.MULTILINE +) + +README_OPTIONS_TABLE_SECTION = re.compile( + r"""(?<=\n).*(?=)""", + re.DOTALL, +) + + +@dataclasses.dataclass(kw_only=True) +class Option: + name: str + id: str + desc: str + section: str + + +def main() -> None: + parser = argparse.ArgumentParser( + description="Update the options table in the README from docs/options.md" + ) + parser.add_argument( + "--force", + action="store_true", + help="Updates the README inplace, rather than printing to stdout.", + ) + args = parser.parse_args() + + options_md = OPTIONS_MD.read_text(encoding="utf-8") + + sections = SECTION_HEADER_REGEX.split(options_md)[1:] + + options = [] + + for section_name, section_content in zip(sections[0::2], sections[1::2], strict=True): + for match in OPTION_HEADER_REGEX.finditer(section_content): + option = Option( + name=match.group("name").strip(), + id=match.group("id").strip(), + desc=match.group("desc").strip(), + section=section_name.strip(), + ) + options.append(option) + + table_md = "\n\n" + table_md += "| | Option | Description |\n" + table_md += "|---|---|---|\n" + last_section: str | None = None + + for option in options: + cells: list[str] = [] + + cells.append(f"**{option.section}**" if option.section != last_section else "") + last_section = option.section + + url = f"https://cibuildwheel.pypa.io/en/stable/options/#{option.id}" + name = option.name.replace(", ", "
") # Replace commas with line breaks + cells.append(f"[{name}]({url})") + + cells.append(option.desc) + + table_md += "| " + " | ".join(cells) + " |\n" + table_md += "\n" + + if not args.force: + print(table_md) + return + + readme_text = README.read_text(encoding="utf-8") + + if not re.search(README_OPTIONS_TABLE_SECTION, readme_text): + msg = "Options section not found in README" + raise ValueError(msg) + + readme_text = re.sub(README_OPTIONS_TABLE_SECTION, table_md, readme_text) + README.write_text(readme_text, encoding="utf-8") + + print("Updated README with options table.") + + +if __name__ == "__main__": + main() diff --git a/docs/options.md b/docs/options.md index 95a82e3d..4d762335 100644 --- a/docs/options.md +++ b/docs/options.md @@ -1889,40 +1889,6 @@ Some options support placeholders, like `{project}`, `{package}` or `{wheel}`, t } } - // write the markdown table for the README - - var markdown = '' - - markdown += '| | Option | Description |\n' - markdown += '|---|--------|-------------|\n' - - var prevHeader = null - - for (var i = 0; i < headers.length; i += 1) { - var header = headers[i]; - var headerOptions = options[header]; - for (var j = 0; j < headerOptions.length; j += 1) { - var option = headerOptions[j]; - - if (j == 0) { - markdown += '| **'+header+'** ' - } else { - markdown += '| ' - } - - var optionNames = option.name.trim().split(', ') - var url = 'https://cibuildwheel.pypa.io/en/stable/options/#'+option.id; - var namesMarkdown = $.map(optionNames, function(n) { - return '[`'+n+'`]('+url+') ' - }).join('
') - - markdown += '| '+namesMarkdown+' ' - markdown += '| '+option.description.trim()+' ' - markdown += '|\n' - } - } - console.log('readme options markdown\n', markdown) - // add the option tags to each heading $('.rst-content h3') .each(function (i, el) {