mirror of https://github.com/pyodide/pyodide.git
128 lines
3.7 KiB
Python
128 lines
3.7 KiB
Python
import argparse
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
import tempfile
|
|
from collections.abc import Generator
|
|
from contextlib import contextmanager
|
|
from pathlib import Path
|
|
|
|
import requests
|
|
from packaging.version import Version
|
|
|
|
from pyodide_build.xbuildenv_releases import (
|
|
CrossBuildEnvMetaSpec,
|
|
CrossBuildEnvReleaseSpec,
|
|
)
|
|
|
|
METADATA_FILE = Path(__file__).parents[1] / "pyodide-cross-build-environments.json"
|
|
|
|
BASE_URL = "https://github.com/pyodide/pyodide/releases/download/{version}/xbuildenv-{version}.tar.bz2"
|
|
|
|
# Pyodide build version that is compatible with the latest cross-build environment
|
|
# Note for maintainers: update this value when there is a breaking changes in the cross-build environment
|
|
MIN_COMPATIBLE_PYODIDE_BUILD_VERSION = "0.26.0"
|
|
|
|
|
|
def parse_args() -> argparse.Namespace:
|
|
parser = argparse.ArgumentParser("Update cross-build environments files")
|
|
parser.add_argument("version", help="version of the cross-build environment")
|
|
|
|
return parser.parse_args()
|
|
|
|
|
|
def get_archive(url: str) -> bytes:
|
|
resp = requests.get(url)
|
|
resp.raise_for_status()
|
|
|
|
return resp.content
|
|
|
|
|
|
def parse_env_var(content: str, var_name: str) -> str:
|
|
# A very dummy parser for env vars.
|
|
for line in content.splitlines():
|
|
if line.startswith(f"export {var_name}"):
|
|
return line.split("=")[1].strip()
|
|
|
|
return ""
|
|
|
|
|
|
@contextmanager
|
|
def extract_archive(archive: bytes) -> Generator[Path, None, None]:
|
|
with tempfile.TemporaryDirectory() as tmp_dir:
|
|
tmp_dir_path = Path(tmp_dir)
|
|
archive_path = tmp_dir_path / "xbuildenv.tar.bz2"
|
|
archive_path.write_bytes(archive)
|
|
|
|
# Extract the archive
|
|
shutil.unpack_archive(str(archive_path), extract_dir=tmp_dir)
|
|
|
|
yield tmp_dir_path
|
|
|
|
|
|
def add_version(
|
|
raw_metadata: str,
|
|
version: str,
|
|
url: str,
|
|
digest: str,
|
|
python_version: str | None = None,
|
|
emscripten_version: str | None = None,
|
|
min_pyodide_build_version: str | None = None,
|
|
max_pyodide_build_version: str | None = None,
|
|
) -> str:
|
|
metadata = CrossBuildEnvMetaSpec.parse_raw(raw_metadata)
|
|
new_release = CrossBuildEnvReleaseSpec(
|
|
version=version,
|
|
url=url,
|
|
sha256=digest,
|
|
python_version=python_version or "FIXME",
|
|
emscripten_version=emscripten_version or "FIXME",
|
|
min_pyodide_build_version=min_pyodide_build_version or "FIXME",
|
|
# Max version is optional, and maintainers should update it when needed.
|
|
max_pyodide_build_version=max_pyodide_build_version or None,
|
|
)
|
|
|
|
metadata.releases[version] = new_release
|
|
|
|
# Sort releases in reverse order
|
|
metadata.releases = dict(
|
|
sorted(metadata.releases.items(), reverse=True, key=lambda x: Version(x[0]))
|
|
)
|
|
dictionary = metadata.dict(exclude_none=True)
|
|
return json.dumps(dictionary, indent=2)
|
|
|
|
|
|
def main():
|
|
args = parse_args()
|
|
|
|
version = args.version
|
|
full_url = BASE_URL.format(version=version)
|
|
|
|
content = get_archive(full_url)
|
|
digest = hashlib.sha256(content).hexdigest()
|
|
|
|
with extract_archive(content) as extracted:
|
|
makefile_path = extracted / "xbuildenv" / "pyodide-root" / "Makefile.envs"
|
|
makefile_content = makefile_path.read_text()
|
|
python_version = parse_env_var(makefile_content, "PYVERSION")
|
|
emscripten_version = parse_env_var(
|
|
makefile_content, "PYODIDE_EMSCRIPTEN_VERSION"
|
|
)
|
|
|
|
metadata = METADATA_FILE.read_text()
|
|
new_metadata = add_version(
|
|
metadata,
|
|
version,
|
|
full_url,
|
|
digest,
|
|
python_version=python_version,
|
|
emscripten_version=emscripten_version,
|
|
min_pyodide_build_version=MIN_COMPATIBLE_PYODIDE_BUILD_VERSION,
|
|
)
|
|
|
|
METADATA_FILE.write_text(new_metadata + "\n")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|