Skip to content

Commit

Permalink
migrated poetry; hasn't finished with maturin
Browse files Browse the repository at this point in the history
  • Loading branch information
Binh Vu committed Oct 16, 2023
1 parent 370d8b5 commit 1ca3d00
Show file tree
Hide file tree
Showing 13 changed files with 935 additions and 855 deletions.
7 changes: 4 additions & 3 deletions pbt/package/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

from dataclasses import dataclass
from itertools import chain
import networkx as nx
from typing import Dict, Iterable, List, Optional, Type, Union

from pbt.package.package import Package, DepConstraints, PackageType
import networkx as nx

from pbt.package.package import DepConstraints, Package, PackageType


@dataclass
Expand Down Expand Up @@ -39,7 +40,7 @@ def from_pkgs(pkgs: Dict[str, Package]) -> PkgGraph:
for pkg in pkgs.values():
for deps, is_dev in [
(pkg.dependencies, False),
(pkg.dev_dependencies, True),
(pkg.extra_dependencies, True),
]:
deps: Dict[str, DepConstraints]
for dep, specs in deps.items():
Expand Down
38 changes: 21 additions & 17 deletions pbt/package/manager/manager.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,23 @@
from __future__ import annotations

import glob
import os
import re
from abc import ABC, abstractmethod
from contextlib import contextmanager
from pathlib import Path
from typing import Dict, List, Literal, Optional, Sequence, Set, Tuple, Union
from typing import Generic, List, Literal, Optional, Set, Tuple, TypeVar, Union

import semver

from pbt.config import PBTConfig
from pbt.misc import cache_func, cache_method
from pbt.misc import cache_func
from pbt.package.package import DepConstraint, DepConstraints, Package, VersionSpec

P = TypeVar("P", bound=Package)


class PkgManager(ABC):
class PkgManager(ABC, Generic[P]):
"""A package manager that is responsible for all tasks related to packages such as dicovering, parsing, building, installing, and publishing."""

def __init__(self, cfg: PBTConfig) -> None:
Expand Down Expand Up @@ -58,7 +62,7 @@ def discover(
return out

@abstractmethod
def load(self, dir: Path) -> Package:
def load(self, dir: Path) -> P:
"""Load a package from the given directory.
Args:
Expand All @@ -67,7 +71,7 @@ def load(self, dir: Path) -> Package:
raise NotImplementedError()

@abstractmethod
def save(self, package: Package):
def save(self, package: P):
"""Save the current configuration of the package
Args:
Expand All @@ -76,7 +80,7 @@ def save(self, package: Package):
raise NotImplementedError()

@abstractmethod
def clean(self, package: Package):
def clean(self, package: P):
"""Remove previously installed dependencies and the environment where the package is installed, for a freshly start.
In addition, this also cleans built artifacts.
Expand All @@ -86,7 +90,7 @@ def clean(self, package: Package):
raise NotImplementedError()

@abstractmethod
def publish(self, package: Package):
def publish(self, package: P):
"""Publish the package to the package registry
Args:
Expand All @@ -97,9 +101,9 @@ def publish(self, package: Package):
@abstractmethod
def build(
self,
package: Package,
package: P,
skip_deps: Optional[List[str]] = None,
additional_deps: Optional[Dict[str, DepConstraints]] = None,
additional_deps: Optional[dict[str, DepConstraints]] = None,
release: bool = True,
clean_dist: bool = True,
):
Expand All @@ -117,8 +121,8 @@ def build(
@abstractmethod
def install_dependency(
self,
package: Package,
dependency: Package,
package: P,
dependency: P,
skip_dep_deps: Optional[List[str]] = None,
):
"""Install the given dependency for the given package.
Expand All @@ -139,10 +143,10 @@ def install_dependency(
@abstractmethod
def install(
self,
package: Package,
package: P,
include_dev: bool = False,
skip_deps: Optional[List[str]] = None,
additional_deps: Optional[Dict[str, DepConstraints]] = None,
additional_deps: Optional[dict[str, DepConstraints]] = None,
):
"""Install the package, assuming the the specification is updated. Note that if the package is phantom, only the dependencies are installed.
Expand All @@ -159,7 +163,7 @@ def install(
raise NotImplementedError()

@abstractmethod
def compute_pkg_hash(self, pkg: Package, target: Optional[str] = None) -> str:
def compute_pkg_hash(self, pkg: P, target: Optional[str] = None) -> str:
"""Compute hash of package's content.
Args:
Expand Down Expand Up @@ -192,7 +196,7 @@ def mask_file(
finally:
os.rename(file_path + ".tmp", file_path)

def filter_included_files(self, pkg: Package, files: List[str]) -> List[str]:
def filter_included_files(self, pkg: P, files: List[str]) -> List[str]:
"""Filter out the files that are not included in the package, these are files that
won't affect the content of the package.
Expand Down Expand Up @@ -243,7 +247,7 @@ def find_latest_specs(
'compatible' means all versions must be compatible.
None means we don't check
"""
constraints: Dict[Optional[str], Tuple[VersionSpec, DepConstraint]] = {}
constraints: dict[Optional[str], Tuple[VersionSpec, DepConstraint]] = {}
for specs in lst_specs:
for spec in specs:
version_spec = self.parse_version_spec(spec.version_spec)
Expand Down Expand Up @@ -434,7 +438,7 @@ def parse_version(cls, version: str) -> semver.VersionInfo:

return semver.VersionInfo.parse(version)

def next_version(self, pkg: Package, rule: Literal["major", "minor", "patch"]):
def next_version(self, pkg: P, rule: Literal["major", "minor", "patch"]):
"""Update version of the package if a valid bump rule is provided
Args:
Expand Down
105 changes: 60 additions & 45 deletions pbt/package/manager/maturin.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from __future__ import annotations

import os
import shutil
from contextlib import contextmanager
Expand All @@ -11,21 +13,16 @@
from pbt.config import PBTConfig
from pbt.misc import InvalidPackageError, NewEnvVar, exec
from pbt.package.manager.manager import DepConstraints
from pbt.package.manager.python import Pep518PkgManager
from pbt.package.manager.python import Pep518PkgManager, PythonPackage
from pbt.package.package import DepConstraint, Package, PackageType

if TYPE_CHECKING:
from pbt.package.manager.poetry import Poetry


@dataclass
class MaturinPackage(Package):
"""Temporary class until we fix the optionals dependency"""
class MaturinPackage(PythonPackage):
pass

optional_dep_name: Optional[str] = None


class Maturin(Pep518PkgManager):
class Maturin(Pep518PkgManager[MaturinPackage]):
def __init__(self, cfg: PBTConfig) -> None:
super().__init__(cfg, pkg_type=PackageType.Maturin, backend="maturin")

Expand All @@ -43,12 +40,17 @@ def load(self, dir: Path) -> MaturinPackage:
k, specs = self.parse_dep_spec(item)
dependencies[k] = specs

dev_dependencies = {}
opt = self.get_optional_dependency_name(project_cfg)
if opt is not None:
for item in project_cfg["project"]["optional-dependencies"][opt]:
k, specs = self.parse_dep_spec(item)
dev_dependencies[k] = specs
extra_dependencies = {}
extra_self_reference_deps = {}
for extra, items in project_cfg["project"]["optional-dependencies"].items():
extra_dependencies[extra] = {
(r := self.parse_dep_spec(item))[0]: r[1]
for item in items
}

if name in extra_dependencies[extra]:
assert len(items) == 1
extra_self_reference_deps[extra] = items[0]

# not supported yet in pep-621
# https://peps.python.org/pep-0621/#specify-files-to-include-when-building
Expand All @@ -67,12 +69,12 @@ def load(self, dir: Path) -> MaturinPackage:
name=name,
version=version,
dependencies=dependencies,
dev_dependencies=dev_dependencies,
extra_dependencies=extra_dependencies,
extra_self_reference_deps=extra_self_reference_deps,
type=PackageType.Maturin,
location=dir,
include=include,
exclude=exclude,
optional_dep_name=opt,
)

def save(self, pkg: Package):
Expand All @@ -96,37 +98,50 @@ def save(self, pkg: Package):
doc["project"]["version"] = pkg.version
is_modified = True

for dependencies, old_dependencies, corr_key in [
(pkg.dependencies, old_pkg.dependencies, "dependencies"),
(
pkg.dev_dependencies,
old_pkg.dev_dependencies,
"optional-dependencies",
),
]:
dependencies: Dict[str, DepConstraints]
is_dep_modified = False
for dep, specs in dependencies.items():
if dep not in old_dependencies or old_dependencies[dep] != specs:
is_dep_modified = True
break
if is_dep_modified:
is_dep_modified = False
for dep, specs in pkg.dependencies.items():
if dep not in old_pkg.dependencies or old_pkg.dependencies[dep] != specs:
is_dep_modified = True
break
if is_dep_modified:
is_modified = True
lst = array(
[
dep + " " + self.serialize_dep_specs(specs)
for dep, specs in pkg.dependencies.items()
] # type: ignore
)
lst.multiline(True)
doc["project"]["dependencies"] = lst

for extra, extra_deps in pkg.extra_dependencies.items():
if extra not in old_pkg.extra_dependencies:
is_modified = True
lst = array(
doc["project"]["optional-dependencies"][extra] = array(
[
dep + " " + self.serialize_dep_specs(specs)
for dep, specs in dependencies.items()
for dep, specs in extra_deps.items()
] # type: ignore
)
lst.multiline(True)
if corr_key == "dependencies":
doc["project"][corr_key] = lst
else:
opt = self.get_optional_dependency_name(doc)
assert (
opt is not None
), "The dep is modified, we should have optional-dependencies"
doc["project"][corr_key][opt] = lst
else:
is_dep_modified = False
for dep, specs in extra_deps.items():
if (
dep not in old_pkg.extra_dependencies[extra]
or old_pkg.extra_dependencies[extra][dep] != specs
):
is_dep_modified = True
break
if is_dep_modified:
is_modified = True
lst = array(
[
dep + " " + self.serialize_dep_specs(specs)
for dep, specs in extra_deps.items()
] # type: ignore
)
lst.multiline(True)
doc["project"]["optional-dependencies"][extra] = lst

if is_modified:
success = False
Expand Down Expand Up @@ -192,7 +207,7 @@ def install(
pkg: MaturinPackage,
include_dev: bool = False,
skip_deps: Optional[List[str]] = None,
additional_deps: Optional[Dict[str, DepConstraints]] = None,
additional_deps: Optional[dict[str, DepConstraints]] = None,
virtualenv: Optional[Path] = None,
):
skip_deps = skip_deps or []
Expand Down Expand Up @@ -253,7 +268,7 @@ def change_dependencies(
self,
pkg: Package,
skip_deps: List[str],
additional_deps: Dict[str, DepConstraints],
additional_deps: dict[str, DepConstraints],
disable: bool = False,
):
"""Temporary mask out selected dependencies of the package. This is usually used for installing the package.
Expand Down
Loading

0 comments on commit 1ca3d00

Please sign in to comment.