diff --git a/.readthedocs.yaml b/.readthedocs.yaml index 15b7b977..611854b7 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -6,13 +6,14 @@ sphinx: formats: [] -python: - install: - - requirements: docs/requirements-doc.txt - - method: pip - path: . - build: os: ubuntu-24.04 tools: python: "3.13" + +python: + install: + - method: uv + command: sync + groups: + - docs diff --git a/docs/conf.py b/docs/conf.py index 9db41351..7f3732d1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -3,6 +3,9 @@ from importlib import metadata as importlib_metadata from pathlib import Path +from docutils import nodes, statemachine +from sphinx.util.docutils import SphinxDirective + project = "pyodide-build" copyright = "2019-2026, Pyodide contributors" @@ -16,6 +19,7 @@ "myst_parser", "sphinx_autodoc_typehints", "sphinx_design", + "sphinx_click", ] myst_enable_extensions = [ @@ -60,3 +64,49 @@ release = "0.0.0" version = release + + +# -- Auto-generated CLI reference -------------------------------------------- + + +class PyodideCLIReference(SphinxDirective): + """ + Emit a sphinx-click block for a ``pyodide.cli`` entry point if it belongs + to pyodide-build, to automatically generate CLI reference documentation. + """ + + # Recipe-related commands are intentionally excluded: they are not relevant + # to most users building out-of-tree packages. + _EXCLUDE = {"build-recipes", "build-recipes-no-deps", "skeleton"} + + def run(self) -> list[nodes.Node]: + entry_points = sorted( + ( + entry_point + for entry_point in importlib_metadata.entry_points(group="pyodide.cli") + if entry_point.dist is not None + and entry_point.dist.name == "pyodide-build" + and entry_point.name not in self._EXCLUDE + ), + key=lambda ep: ep.name, + ) + + rst: list[str] = [] + for ep in entry_points: + obj = ep.load() + rst.append(f".. click:: {ep.value}") + rst.append(f" :prog: pyodide {ep.name}") + if hasattr( + obj, "commands" + ): # If it's a click group? Then let's recurse into subcommands + rst.append(" :nested: full") + rst.append("") + + result = statemachine.ViewList(rst, source="") + node: nodes.Node = nodes.section() + self.state.nested_parse(result, self.content_offset, node) + return node.children + + +def setup(app): + app.add_directive("pyodide-cli-reference", PyodideCLIReference) diff --git a/docs/reference/cli.md b/docs/reference/cli.md index 3a768cbc..03fd0764 100644 --- a/docs/reference/cli.md +++ b/docs/reference/cli.md @@ -2,152 +2,6 @@ All commands are accessed through the `pyodide` CLI, provided by the [pyodide-cli](https://pypi.org/project/pyodide-cli/) package (installed automatically with pyodide-build). -## pyodide build - -Build a Python package for WebAssembly. - -``` -pyodide build [OPTIONS] [SOURCE_LOCATION] -``` - -**Arguments:** - -| Argument | Description | -|---|---| -| `SOURCE_LOCATION` | Build source: a directory. Defaults to the current directory. | - -**Options:** - -| Option | Default | Description | -|---|---|---| -| `-o`, `--outdir` | `./dist` | Output directory for the built wheel | -| `--exports` | `requested` | Symbol export mode: `pyinit`, `requested`, `whole_archive`, or comma-separated list | -| `-C`, `--config-setting` | | Pass settings to the build backend (same as `pypa/build`) | -| `-n`, `--no-isolation` | `false` | Disable build isolation; build deps must be installed manually | -| `-x`, `--skip-dependency-check` | `false` | Skip build dependency check (only with `--no-isolation`) | -| `--compression-level` | `6` | Zip compression level for the wheel | -| `--xbuildenv-path` | platform cache | Path to the cross-build environment, inferred from platform cache if not specified | - -## pyodide venv - -Create a Pyodide virtual environment for testing. - -``` -pyodide venv [OPTIONS] DEST +```{eval-rst} +.. pyodide-cli-reference:: ``` - -**Arguments:** - -| Argument | Description | -|---|---| -| `DEST` | Directory to create the virtualenv at | - -**Options:** - -| Option | Default | Description | -|---|---|---| -| `--clear` / `--no-clear` | `no-clear` | Remove destination directory if it exists | -| `--no-vcs-ignore` | | Don't create VCS ignore directive (e.g., `.gitignore`) | -| `--download` / `--no-download` | | Enable/disable download of latest pip/setuptools from PyPI | -| `--extra-search-dir` | | Path containing additional wheels | -| `--pip` | `bundle` | pip version: `embed`, `bundle`, or exact version | -| `--setuptools` | | setuptools version: `embed`, `bundle`, `none`, or exact version | -| `--no-setuptools` | | Do not install setuptools | - -## pyodide config - -Query build configuration values. - -### pyodide config list - -``` -pyodide config list -``` - -Lists all config variables and their current values. - -### pyodide config get - -``` -pyodide config get CONFIG_VAR -``` - -Get a single config variable's value. Common variables: - -| Variable | Description | -|---|---| -| `cflags` | C compiler flags | -| `cxxflags` | C++ compiler flags | -| `ldflags` | Linker flags | -| `rustflags` | Rust compiler flags | -| `cmake_toolchain_file` | Path to CMake toolchain file | -| `meson_cross_file` | Path to Meson cross file | -| `rust_toolchain` | Required Rust nightly toolchain | -| `emscripten_version` | Required Emscripten version | -| `python_version` | Target Python version | -| `xbuildenv_path` | Cross-build environment path | -| `pyodide_abi_version` | Pyodide ABI version | - -## pyodide xbuildenv - -Manage the cross-build environment. - -### pyodide xbuildenv install - -``` -pyodide xbuildenv install [OPTIONS] [VERSION] -``` - -| Option | Env var | Description | -|---|---|---| -| `--path` | `PYODIDE_XBUILDENV_PATH` | Destination directory | -| `--url` | | Download from a custom URL | -| `-f`, `--force` | | Force install even if version is incompatible | -| `--nightly` | | Install a nightly release instead of a stable one | -| `--debug` | | Install the debug variant of a nightly or stable release, as available | - -### pyodide xbuildenv version - -``` -pyodide xbuildenv version [--path PATH] -``` - -Print the current active version. - -### pyodide xbuildenv versions - -``` -pyodide xbuildenv versions [--path PATH] -``` - -List all installed versions. Active version is marked with `*`. - -### pyodide xbuildenv use - -``` -pyodide xbuildenv use VERSION [--path PATH] -``` - -Switch to a specific installed version. - -### pyodide xbuildenv uninstall - -``` -pyodide xbuildenv uninstall [VERSION] [--path PATH] -``` - -Uninstall a version. Defaults to the current version if not specified. - -### pyodide xbuildenv search - -``` -pyodide xbuildenv search [OPTIONS] -``` - -| Option | Description | -|---|---| -| `--metadata` | Custom metadata file URL or path (cannot be combined with `--nightly`/`--debug`) | -| `-a`, `--all` | Show all versions, including incompatible ones | -| `--nightly` | Search nightly releases instead of stable ones | -| `--debug` | Search nightly debug releases instead of stable ones | -| `--json` | Output as JSON | diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 90fff9fc..48238c73 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -25,7 +25,7 @@ xbuildenv_path = "/path/to/xbuildenv" ## User-overridable settings -These keys can be set in `pyproject.toml` or via environment variables: +These keys can be set in `pyproject.toml` under `[tool.pyodide.build]` or via environment variables: | pyproject.toml key | Env variable | Description | |---|---|---| @@ -33,10 +33,16 @@ These keys can be set in `pyproject.toml` or via environment variables: | `cxxflags` | `CXXFLAGS` | C++ compiler flags | | `ldflags` | `LDFLAGS` | Linker flags | | `rustflags` | `RUSTFLAGS` | Rust compiler flags | -| `rust_toolchain` | `RUST_TOOLCHAIN` | Rust nightly toolchain version | -| `meson_cross_file` | `MESON_CROSS_FILE` | Path to Meson cross file | -| `xbuildenv_path` | `PYODIDE_XBUILDENV_PATH` | Path to cross-build environment | -| `ignored_build_requirements` | `IGNORED_BUILD_REQUIREMENTS` | Build requirements to ignore | +| `rust_toolchain` | `RUST_TOOLCHAIN` | Required Rust nightly toolchain | +| `meson_cross_file` | `MESON_CROSS_FILE` | Path to the Meson cross file | +| `xbuildenv_path` | `PYODIDE_XBUILDENV_PATH` | Path to the cross-build environment | +| `ignored_build_requirements` | `IGNORED_BUILD_REQUIREMENTS` | Space-separated PEP 508 build requirements to ignore | +| `skip_emscripten_version_check` | `SKIP_EMSCRIPTEN_VERSION_CHECK` | Skip Emscripten version compatibility check (`0`/`1`) | +| `default_cross_build_env_url` | `DEFAULT_CROSS_BUILD_ENV_URL` | URL override for the cross-build environment archive | +| `use_legacy_platform` | `USE_LEGACY_PLATFORM` | Use the legacy `pyodide_*` platform tag instead of `pyemscripten_*` (`0`/`1`) | + +Run `pyodide config list` to see all available variables and their current values. + ## Environment variables diff --git a/docs/requirements-doc.txt b/docs/requirements-doc.txt deleted file mode 100644 index 0ae1b9f6..00000000 --- a/docs/requirements-doc.txt +++ /dev/null @@ -1,5 +0,0 @@ -sphinx>=5.3.0 -sphinx_book_theme>=0.4.0rc1 -myst-parser -sphinx-autodoc-typehints>=1.21.7 -sphinx-design diff --git a/pyproject.toml b/pyproject.toml index 5fa82462..0b58a85e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,10 +73,15 @@ test = [ "click>=8.0,<8.3.3", ] docs = [ - "sphinx>=5.3.0", + # sphinx-click 6.2.0 is broken with Sphinx 9 due to a mock resolution issue. + # see https://github.com/click-contrib/sphinx-click/pull/160. We can remove + # this when merged and released. + "sphinx>=5.3.0,<9", "sphinx_book_theme>=0.4.0rc1", "myst-parser", "sphinx-autodoc-typehints>=1.21.7", + "sphinx-design", + "sphinx-click", ] [tool.hatch.version]