Skip to content
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: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
`pyodide xbuildenv search --all` and `pyodide xbuildenv search --all --json`.
[#349](https://github.com/pyodide/pyodide-build/pull/349)

- `pyodide xbuildenv search` and `pyodide xbuildenv install` now support `--nightly`
and `--debug` flags to search and install nightly and nightly-debug cross-build
environments respectively.
[#350](https://github.com/pyodide/pyodide-build/pull/350)

## [0.34.4] - 2026/05/15

### Added
Expand Down
7 changes: 4 additions & 3 deletions docs/getting-started/concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,10 @@ When you run `pyodide build`, pyodide-build automatically downloads and sets up
You can also manage the cross-build environment explicitly:

```bash
pyodide xbuildenv install # install (or update) the cross-build environment
pyodide xbuildenv install 0.29.3 # install a specific Pyodide version
pyodide xbuildenv versions # list installed versions
pyodide xbuildenv install # install (or update) the cross-build environment
pyodide xbuildenv install 0.29.3 # install a specific Pyodide version
pyodide xbuildenv install --nightly # install the latest nightly release
pyodide xbuildenv versions # list installed versions
```

See [Managing Cross-Build Environments](../how-to/xbuildenv.md) for more details.
Expand Down
20 changes: 19 additions & 1 deletion docs/how-to/xbuildenv.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@ pyodide xbuildenv install --url https://example.com/xbuildenv-0.27.0.tar

# Force install even if version compatibility check fails
pyodide xbuildenv install --force

# Install the latest nightly release
pyodide xbuildenv install --nightly

# Install a specific nightly version
pyodide xbuildenv install 20260520 --nightly

# Install the debug variant of the latest nightly release
pyodide xbuildenv install --debug
```

## Listing installed versions
Expand Down Expand Up @@ -68,9 +77,18 @@ pyodide xbuildenv uninstall 0.29.3
# Show versions compatible with your Python and pyodide-build
pyodide xbuildenv search

# Show all available versions
# Show all available versions (including incompatible ones)
pyodide xbuildenv search --all

# Search nightly releases
pyodide xbuildenv search --nightly

# Search nightly debug releases
pyodide xbuildenv search --debug

# Combine flags: show all nightly and debug releases
pyodide xbuildenv search --nightly --debug --all

# Output as JSON (useful for scripting)
pyodide xbuildenv search --json
```
Expand Down
6 changes: 5 additions & 1 deletion docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ pyodide xbuildenv install [OPTIONS] [VERSION]
| `--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

Expand Down Expand Up @@ -144,6 +146,8 @@ pyodide xbuildenv search [OPTIONS]

| Option | Description |
|---|---|
| `--metadata` | Custom metadata file URL or path |
| `--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 |
128 changes: 98 additions & 30 deletions pyodide_build/cli/xbuildenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from pyodide_build.views import MetadataView
from pyodide_build.xbuildenv import CrossBuildEnvManager
from pyodide_build.xbuildenv_releases import (
NIGHTLY_CROSS_BUILD_ENV_METADATA_URL,
NIGHTLY_DEBUG_CROSS_BUILD_ENV_METADATA_URL,
cross_build_env_metadata_url,
load_cross_build_env_metadata,
)
Expand Down Expand Up @@ -51,6 +53,18 @@ def check_xbuildenv_root(path: Path) -> None:
default=False,
help="force installation even if the version is not compatible.",
)
@click.option(
"--nightly",
is_flag=True,
default=False,
help="install a nightly cross-build environment instead of a stable release.",
)
@click.option(
"--debug",
is_flag=True,
default=False,
help="install the debug variant of the cross-build environment (nightly only).",
)
@click.option(
"--skip-cross-build-packages",
is_flag=True,
Expand All @@ -65,6 +79,8 @@ def _install(
path: Path,
url: str | None,
force_install: bool,
nightly: bool,
debug: bool,
skip_cross_build_packages: bool,
) -> None:
"""Install cross-build environment.
Expand All @@ -78,18 +94,21 @@ def _install(
Arguments:
VERSION: version of cross-build environment to install (optional)
"""
manager = CrossBuildEnvManager(path)
if nightly or debug:
metadata_url = (
NIGHTLY_DEBUG_CROSS_BUILD_ENV_METADATA_URL
if debug
else NIGHTLY_CROSS_BUILD_ENV_METADATA_URL
)
else:
metadata_url = None

manager = CrossBuildEnvManager(path, metadata_url=metadata_url)

if url:
manager.install(
url=url,
force_install=force_install,
)
manager.install(url=url, force_install=force_install)
else:
manager.install(
version=version,
force_install=force_install,
)
manager.install(version=version, force_install=force_install)

Comment thread
agriyakhetarpal marked this conversation as resolved.
click.echo(f"Pyodide cross-build environment installed at {path.resolve()}")

Expand Down Expand Up @@ -194,6 +213,18 @@ def _use(version: str, path: Path) -> None:
default=False,
help="search all versions, without filtering out incompatible ones.",
)
@click.option(
"--nightly",
is_flag=True,
default=False,
help="search nightly releases instead of stable ones.",
)
@click.option(
"--debug",
is_flag=True,
default=False,
help="search nightly debug releases instead of stable ones.",
)
@click.option(
"--json",
"json_output",
Expand All @@ -204,32 +235,30 @@ def _use(version: str, path: Path) -> None:
def _search(
metadata_path: str | None,
show_all: bool,
nightly: bool,
debug: bool,
json_output: bool,
) -> None:
"""Search for available versions of cross-build environment."""

# TODO: cache the metadata file somewhere to avoid downloading it every time

metadata_path = metadata_path or cross_build_env_metadata_url()
metadata = load_cross_build_env_metadata(metadata_path)
if metadata_path and (nightly or debug):
click.echo("--metadata cannot be combined with --nightly or --debug")
raise SystemExit(1)

local = local_versions()

if show_all:
releases = metadata.list_compatible_releases()
else:
releases = metadata.list_compatible_releases(
python_version=local["python"],
pyodide_build_version=local["pyodide-build"],
)
def _compat_kwargs() -> dict:
if show_all:
return {}
return {
"python_version": local["python"],
"pyodide_build_version": local["pyodide-build"],
}

if not releases:
click.echo(
"No compatible cross-build environment found for your system. Try using --all to see all versions."
)
raise SystemExit(1)

views = [
MetadataView(
def _make_view(release, source: str = "stable") -> MetadataView:
return MetadataView(
version=release.version,
python=release.python_version,
emscripten=release.emscripten_version,
Expand All @@ -238,18 +267,57 @@ def _search(
"max": release.max_pyodide_build_version,
},
published_at=release.published_at,
source=source,
compatible=release.is_compatible(
python_version=local["python"],
pyodide_build_version=local["pyodide-build"],
),
)
for release in releases
]

if nightly or debug:
# Nightly and/or debug releases (mutually exclusive with stable)
sources = []
if nightly:
sources.append(("nightly", NIGHTLY_CROSS_BUILD_ENV_METADATA_URL))
if debug:
sources.append(
("nightly-debug", NIGHTLY_DEBUG_CROSS_BUILD_ENV_METADATA_URL)
)
compat = _compat_kwargs()
views = [
_make_view(release, source)
for source, url in sources
for release in sorted(
(
release
for release in load_cross_build_env_metadata(url).releases.values()
if release.is_compatible(**compat)
),
key=lambda release: release.published_at,
reverse=True,
)
]
else:
# Stable releases
stable_metadata = load_cross_build_env_metadata(
metadata_path or cross_build_env_metadata_url()
)
Comment thread
agriyakhetarpal marked this conversation as resolved.
views = [
_make_view(r, "stable")
for r in stable_metadata.list_compatible_releases(**_compat_kwargs())
]

if not views:
click.echo(
"No compatible cross-build environment found for your system. Try using --all to see all versions."
)
raise SystemExit(1)

show_source = nightly or debug
if json_output:
print(MetadataView.to_json(views))
print(MetadataView.to_json(views, show_source=show_source))
else:
print(MetadataView.to_table(views))
print(MetadataView.to_table(views, show_source=show_source))


@app.command("install-emscripten")
Expand Down
Loading