Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions fablib/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ def dctrls(self) -> dict[Dependency, deb822.Deb822]:

return dctrls

def resolve(self) -> tuple[Iterable[str], Iterable[str]]:
def resolve(self, bootstrap_provided: set[str] | None = None) -> tuple[Iterable[str], Iterable[str]]:
"""resolve plan dependencies recursively -> return spec"""
logger.debug("resolve")

Expand All @@ -364,7 +364,7 @@ def resolve(self) -> tuple[Iterable[str], Iterable[str]]:

resolved: set[Dependency] = set()
missing: set[Dependency] = set()
provided: set[str] = set()
provided: set[str] = set(bootstrap_provided or set())

def reformat2dep(pkg: str) -> str:
if "=" not in pkg:
Expand Down Expand Up @@ -402,8 +402,10 @@ def reformat2dep(pkg: str) -> str:
)
provided |= self._get_provided(pkg_control)

missing |= packages.missing
unresolved = new_deps - resolved
all_missing = set(map(str, (missing | packages.missing))) - provided

all_missing = set(map(str, missing)) - provided

if all_missing:

Expand All @@ -417,9 +419,7 @@ def get_origins(dep: Dependency) -> Generator[str, None, None]:
except KeyError:
depname = None

brokendeps = []
for dep in missing:
brokendeps.append(dep.name)
brokendeps = [dep.name for dep in missing if str(dep) in all_missing]

logger.debug(
f"could not find these packages in pool: {brokendeps!r}"
Expand Down
25 changes: 24 additions & 1 deletion fablib/resolve.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

from .plan import PackageOrigins, Plan

import re

logger = logging.getLogger("fab.resolve")


Expand All @@ -23,6 +25,25 @@ def iter_packages(root: str) -> Generator[str, None, None]:
control += line


def iter_provided(root: str) -> Generator[str, None, None]:
"""Yield virtual package names provided by installed bootstrap packages."""
control = ""
with open(join(root, "var/lib/dpkg/status")) as fob:
for line in fob:
if not line.strip():
deb = Deb822(control.splitlines())
if deb["Status"] == "install ok installed":
provides = deb.get("Provides", "")
if provides:
for p in re.split(r"\s*,\s*", provides.strip()):
name = p.split()[0].strip()
if name:
yield name
control = ""
else:
control += line


def annotate_spec(
repo_spec: Iterable[str],
pool_spec: Iterable[str],
Expand Down Expand Up @@ -54,8 +75,10 @@ def resolve_plan(
plans: list[str],
) -> None:
plan = Plan(pool_path=pool_path)
bootstrap_provided: set[str] = set()
if bootstrap_path:
bootstrap_packages = set(iter_packages(bootstrap_path))
bootstrap_provided = set(iter_provided(bootstrap_path))
plan |= bootstrap_packages

for package in bootstrap_packages:
Expand All @@ -72,7 +95,7 @@ def resolve_plan(
plan.add(plan_path)
plan.packageorigins.add(plan_path, "_")

spec, unresolved = plan.resolve()
spec, unresolved = plan.resolve(bootstrap_provided=bootstrap_provided)
logger.debug("unresolved" + "\n".join(unresolved))
spec = annotate_spec(unresolved, spec, plan.packageorigins)
logger.debug(spec)
Expand Down