Skip to content

Commit

Permalink
Add wheels cli (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
joemarshall authored Nov 12, 2023
1 parent 92e9511 commit d825167
Show file tree
Hide file tree
Showing 8 changed files with 677 additions and 170 deletions.
3 changes: 2 additions & 1 deletion pyodide_lock/__init__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from .spec import PackageSpec, PyodideLockSpec
from .spec import InfoSpec, PackageSpec, PyodideLockSpec
from .utils import parse_top_level_import_name

__all__ = [
"PyodideLockSpec",
"PackageSpec",
"InfoSpec",
"parse_top_level_import_name",
]
57 changes: 57 additions & 0 deletions pyodide_lock/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
from pathlib import Path

import typer

from .spec import PyodideLockSpec
from .utils import add_wheels_to_spec

main = typer.Typer(help="manipulate pyodide-lock.json lockfiles.")


@main.command()
def add_wheels(
wheels: list[Path],
ignore_missing_dependencies: bool = typer.Option(
help="If this is true, dependencies "
"which are not in the original lockfile or "
"the added wheels will be added to the lockfile. "
"Warning: This will allow a broken lockfile to "
"be created.",
default=False,
),
input: Path = typer.Option(
help="Source lockfile", default=Path("pyodide-lock.json")
),
output: Path = typer.Option(
help="Updated lockfile", default=Path("pyodide-lock-new.json")
),
base_path: Path = typer.Option(
help="Base path for wheels - wheel file "
"names will be created relative to this path.",
default=None,
),
wheel_url: str = typer.Option(
help="Base url which will be appended to the wheel location."
"Use this if you are hosting these wheels on a different "
"server to core pyodide packages",
default="",
),
):
"""Add a set of package wheels to an existing pyodide-lock.json and
write it out to pyodide-lock-new.json
Each package in the wheel will be added to the output lockfile,
including resolution of dependencies in the lock file. By default
this will fail if a dependency isn't available in either the
existing lock file, or in the set of new wheels.
"""
sp = PyodideLockSpec.from_json(input)
add_wheels_to_spec(
sp,
wheels,
base_path=base_path,
base_url=wheel_url,
ignore_missing_dependencies=ignore_missing_dependencies,
)
sp.to_json(output)
47 changes: 4 additions & 43 deletions pyodide_lock/spec.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,7 @@
from pathlib import Path
from typing import Literal

from pydantic import BaseModel, Extra

from .utils import (
_generate_package_hash,
_wheel_depends,
parse_top_level_import_name,
)
from pydantic import BaseModel, Extra, Field


class InfoSpec(BaseModel):
Expand All @@ -24,7 +18,9 @@ class Config:
class PackageSpec(BaseModel):
name: str
version: str
file_name: str
file_name: str = Field(
description="Path (or URL) to wheel.", format="uri-reference"
)
install_dir: str
sha256: str = ""
package_type: Literal[
Expand All @@ -39,41 +35,6 @@ class PackageSpec(BaseModel):
class Config:
extra = Extra.forbid

@classmethod
def from_wheel(
cls,
path: Path,
marker_env: None | dict[str, str] = None,
) -> "PackageSpec":
"""Build a package spec from an on-disk wheel.
This currently assumes a "simple" noarch wheel: more complex packages
may require further postprocessing.
"""
import pkginfo
from packaging.utils import canonicalize_name

metadata = pkginfo.get_metadata(str(path))

if not metadata:
raise RuntimeError(f"Could not parse wheel metadata from {path.name}")

return PackageSpec(
name=canonicalize_name(metadata.name),
version=metadata.version,
file_name=path.name,
sha256=_generate_package_hash(path),
package_type="package",
install_dir="site",
imports=parse_top_level_import_name(path),
depends=_wheel_depends(metadata, marker_env),
)

def update_sha256(self, path: Path) -> "PackageSpec":
"""Update the sha256 hash for a package."""
self.sha256 = _generate_package_hash(path)
return self


class PyodideLockSpec(BaseModel):
"""A specification for the pyodide-lock.json file."""
Expand Down
Loading

0 comments on commit d825167

Please sign in to comment.