diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a824225..e4455dd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- The `pyodide skeleton pypi --update` command and the `--update-patched` variant now + validate the version and the source checksum when updating a package's recipe. + [#27](https://github.com/pyodide/pyodide-build/pull/27) + - `pyo3_config_file` is no longer available in `pyodide config` command. Pyodide now sets `PYO3_CROSS_PYTHON_VERSION`, `PYO3_CROSS_LIB_DIR` to specify the cross compilation environment for PyO3. diff --git a/pyodide_build/mkpkg.py b/pyodide_build/mkpkg.py index 5cd9497a..fa5ffd0c 100755 --- a/pyodide_build/mkpkg.py +++ b/pyodide_build/mkpkg.py @@ -245,18 +245,46 @@ def update_package( old_fmt = "sdist" pypi_metadata = _get_metadata(package, version) + + # Grab versions from metadata pypi_ver = Version(pypi_metadata["info"]["version"]) local_ver = Version(yaml_content["package"]["version"]) - already_up_to_date = pypi_ver <= local_ver and ( + + # and grab checksums from metadata + source_fmt = source_fmt or old_fmt + dist_metadata = _find_dist(pypi_metadata, [source_fmt]) + sha256 = dist_metadata["digests"]["sha256"] + sha256_local = yaml_content["source"].get("sha256") + + # fail if local version is newer than PyPI version + # since updating isn't possible in that case + if pypi_ver < local_ver: + raise MkpkgFailedException( + f"Local version {local_ver} is newer than PyPI version {pypi_ver}, " + f"cannot update {package}. Please verify in case the version was " + "updated manually and is correct." + ) + + # conditions to check if the package is up to date + is_sha256_up_to_date = sha256 == sha256_local + is_version_up_to_date = pypi_ver == local_ver + + already_up_to_date = (is_sha256_up_to_date and is_version_up_to_date) and ( source_fmt is None or source_fmt == old_fmt ) if already_up_to_date: logger.success( - f"{package} already up to date. Local: {local_ver} PyPI: {pypi_ver}" + f"{package} already up to date." + f" Local: {local_ver} and PyPI: {pypi_ver}" + f" and checksum received: {sha256} matches local: {sha256_local} ✅" ) return - logger.info(f"{package} is out of date: {local_ver} <= {pypi_ver}.") + logger.info( + f"{package} is out of date:" + f" either {local_ver} < {pypi_ver}" + f" or checksums might have mismatched: received {sha256} against local {sha256_local} 🚨" + ) if yaml_content["source"].get("patches"): if update_patched: @@ -267,6 +295,7 @@ def update_package( else: raise MkpkgFailedException( f"Pyodide applies patches to {package}. Skipping update." + f" Use --update-patched to force updating {package}." ) if source_fmt: