fix: resolve actual package names

provides=... allows aliasing packages to others, and pacman -D only
takes the actual package names, so we need to resolve them.
This commit is contained in:
2 * r + 2 * t
2026-06-19 20:17:50 +10:00
parent 2e9a387951
commit 702baa117b
+19 -5
View File
@@ -185,10 +185,12 @@ class ArchInstaller(PackageInstaller):
# Force install reason to explicit install # Force install reason to explicit install
if explicit: if explicit:
# `-D` only accepts real installed names, so resolve any virtual/`provides` names (e.g. awk -> gawk)
resolved = [self._installed_name(pkg) for pkg in packages]
try: try:
subprocess.run([self.helper, "-D", "--asexplicit", *self.flags, *packages], check=True) subprocess.run([self.helper, "-D", "--asexplicit", *self.flags, *resolved], check=True)
except (subprocess.CalledProcessError, FileNotFoundError): except (subprocess.CalledProcessError, FileNotFoundError):
warn(f"failed to mark packages as explicitly installed: {', '.join(packages)}") warn(f"failed to mark packages as explicitly installed: {', '.join(resolved)}")
def remove(self, packages: list[str]) -> None: def remove(self, packages: list[str]) -> None:
if not packages: if not packages:
@@ -218,7 +220,9 @@ class ArchInstaller(PackageInstaller):
return names return names
def installed_version(self, package: str) -> str | None: def _query(self, package: str) -> tuple[str, str] | None:
"""Return the installed (name, version) of `package`, resolving `provides` (e.g. awk -> gawk), or None."""
result = subprocess.run( result = subprocess.run(
["pacman", "-Q", package], ["pacman", "-Q", package],
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@@ -227,9 +231,19 @@ class ArchInstaller(PackageInstaller):
) )
if result.returncode != 0: if result.returncode != 0:
return None return None
# `pacman -Q` prints "<name> <version>" # `pacman -Q` resolves provides and prints "<real name> <version>"
parts = result.stdout.split() parts = result.stdout.split()
return parts[1] if len(parts) >= 2 else None return (parts[0], parts[1]) if len(parts) >= 2 else None
def _installed_name(self, package: str) -> str:
"""Resolve `package` to its real installed name (handles provides), falling back to the given name."""
query = self._query(package)
return query[0] if query else package
def installed_version(self, package: str) -> str | None:
query = self._query(package)
return query[1] if query else None
def needs_rebuild(self, directory: Path, packages: list[str]) -> bool: def needs_rebuild(self, directory: Path, packages: list[str]) -> bool:
built = _srcinfo_version(_read_srcinfo(directory)) built = _srcinfo_version(_read_srcinfo(directory))