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) {