Skip to content

Commit

Permalink
Refactor search + validation + install into one step
Browse files Browse the repository at this point in the history
  • Loading branch information
agriyakhetarpal committed Sep 24, 2024
1 parent 97e22c8 commit d30eb6a
Showing 1 changed file with 26 additions and 35 deletions.
61 changes: 26 additions & 35 deletions cibuildwheel/pyodide.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,20 @@ def install_emscripten(tmp: Path, version: str) -> Path:
return emcc_path


def retrieve_compatible_xbuildenvs() -> list[str]:
"""Search for compatible xbuildenvs for the current pyodide-build version."""
def search_and_install_xbuildenv(
env: dict[str, str], pyodide_build_version: str, pyodide_version: str
) -> str:
"""Searches, validates, and installs a particular Pyodide xbuildenv version."""
# Since pyodide-build was unvendored from Pyodide v0.27.0, the versions of pyodide-build are
# not guaranteed to match the versions of Pyodide or be in sync with them. Hence, we shall
# specify the pyodide-build version in the root path, which will set up the xbuildenv for
# the requested Pyodide version.
pyodide_root = (
CIBW_CACHE_PATH
/ f".pyodide-xbuildenv-{pyodide_build_version}/{pyodide_version}/xbuildenv/pyodide-root"
)

# Search for compatible xbuildenvs for the current pyodide-build version
xbuildenvs = call(
"pyodide",
"xbuildenv",
Expand All @@ -77,54 +89,33 @@ def retrieve_compatible_xbuildenvs() -> list[str]:
"--all",
capture_stdout=True,
).strip()

xbuildenvs_dict = json.loads(xbuildenvs)
compatible_xbuildenvs = [
env["version"] for env in xbuildenvs_dict["environments"] if env["compatible"]
]

# Fetch just the "stable" versions
compatible_xbuildenvs_filtered = [
version for version in compatible_xbuildenvs if not any(_ in version for _ in "abc")
]

return compatible_xbuildenvs_filtered


def validate_xbuildenv_version(pyodide_build_version: str, xbuildenv_version: str) -> None:
"""Validate that the requested xbuildenv version is compatible with the pyodide-build version."""
xbuildenvs = retrieve_compatible_xbuildenvs()
if xbuildenv_version not in xbuildenvs:
# Now, validate that the requested xbuildenv version is compatible with the pyodide-build version.
# The xbuildenv version is brought in sync with the pyodide-build version in build-platforms.toml,
# which will always be compatible. Hence, this condition really only checks for the case where the
# version is supplied manually through the CIBW_PYODIDE_VERSION environment variable.
cibw_pyodide_version = os.environ.get("CIBW_PYODIDE_VERSION", pyodide_version)
if cibw_pyodide_version not in compatible_xbuildenvs_filtered:
msg = (
f"The xbuildenv version {xbuildenv_version} is not compatible with the pyodide-build version {pyodide_build_version}."
f" The compatible versions are: {xbuildenvs}. Please use the 'pyodide xbuildenv search' command to find the compatible versions."
f"The xbuildenv version {cibw_pyodide_version} is not compatible with the pyodide-build"
f" version {pyodide_build_version}. The compatible versions available to download are:"
f" {compatible_xbuildenvs_filtered}. Please use the 'pyodide xbuildenv search' command to"
f" find the compatible versions for {pyodide_build_version}"
)
raise errors.FatalError(msg)


def install_xbuildenv(env: dict[str, str], pyodide_build_version: str, pyodide_version: str) -> str:
# Since pyodide-build was unvendored from Pyodide v0.27.0, the versions of pyodide-build are
# not guaranteed to match the versions of Pyodide or be in sync with them. Hence, we shall
# specify the pyodide-build version, which will set up the xbuildenv for the requested
# Pyodide version.
pyodide_root = (
CIBW_CACHE_PATH
/ f".pyodide-xbuildenv-{pyodide_build_version}/{pyodide_version}/xbuildenv/pyodide-root"
)

with FileLock(CIBW_CACHE_PATH / "xbuildenv.lock"):
if pyodide_root.exists():
return str(pyodide_root)

# Validate that the requested xbuildenv version is compatible with the pyodide-build version.
# The xbuildenv version is brought in sync with the pyodide-build version in build-platforms.toml,
# which will always be compatible. Hence, this function really only checks for the case where the
# version is supplied manually through CIBW_PYODIDE_VERSION environment variable.
cibw_pyodide_version = os.environ.get("CIBW_PYODIDE_VERSION")
if cibw_pyodide_version:
validate_xbuildenv_version(pyodide_build_version, cibw_pyodide_version)
pyodide_version = cibw_pyodide_version

# We don't want to mutate env but we need to delete any existing
# PYODIDE_ROOT so copy it first.
env = dict(env)
Expand All @@ -133,7 +124,7 @@ def install_xbuildenv(env: dict[str, str], pyodide_build_version: str, pyodide_v
"pyodide",
"xbuildenv",
"install",
pyodide_version,
cibw_pyodide_version,
env=env,
cwd=CIBW_CACHE_PATH,
)
Expand Down Expand Up @@ -222,7 +213,7 @@ def setup_python(
env["PATH"] = os.pathsep.join([str(emcc_path.parent), env["PATH"]])

log.step(f"Installing Pyodide xbuildenv version: {python_configuration.pyodide_version} ...")
env["PYODIDE_ROOT"] = install_xbuildenv(
env["PYODIDE_ROOT"] = search_and_install_xbuildenv(
env, python_configuration.pyodide_build_version, python_configuration.pyodide_version
)

Expand Down

0 comments on commit d30eb6a

Please sign in to comment.