Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 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` now supports `--nightly` and `--debug` flags to search
nightly and nightly-debug cross-build environments respectively, and `pyodide xbuildenv
install` supports `--nightly` and `--debug` flags to install them.
Comment thread
agriyakhetarpal marked this conversation as resolved.
Outdated
[#350](https://github.com/pyodide/pyodide-build/pull/350)

## [0.34.4] - 2026/05/15

### Added
Expand Down
124 changes: 94 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,26 @@ 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)
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"],
)

if not releases:
click.echo(
"No compatible cross-build environment found for your system. Try using --all to see all versions."
)
raise SystemExit(1)
def _compat_kwargs() -> dict:
if show_all:
return {}
return {
"python_version": local["python"],
"pyodide_build_version": local["pyodide-build"],
}

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 +263,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