Skip to content

feat: unified package model with idempotent upgrades across all package managers#1594

Draft
wowi42 wants to merge 5 commits intopyinfra-dev:3.xfrom
KalvadTech:feat/unified-package-model
Draft

feat: unified package model with idempotent upgrades across all package managers#1594
wowi42 wants to merge 5 commits intopyinfra-dev:3.xfrom
KalvadTech:feat/unified-package-model

Conversation

@wowi42
Copy link
Copy Markdown
Collaborator

@wowi42 wowi42 commented Mar 10, 2026

Summary

Introduce a common PackageInfo data model (name, version, status) and build_package_map() helper so all package managers share a consistent representation of installed, upgradeable, and held packages. Operations like upgrade() are now idempotent — they check for available upgrades before running. The ensure_packages() function accepts both the old dict[str, set[str]] and new dict[str, PackageInfo] formats for backward compatibility.

Changes

  • Unified package model: Added PackageInfo dataclass and build_package_map() in facts.util.packages to normalize installed/outdated/held package data across all managers.
  • Migrated managers: apk, apt, brew, cargo, dnf, gem, npm, opkg, pacman, pip, pkg, pkgin, xbps, yum, zypper. Added upgradeable/held sub-facts for each manager that supports them.
  • New pkg operations: Added pkg.update() and pkg.upgrade().
  • Added portage and paludis: New package manager support for Gentoo (portage) and Exherbo (paludis), including facts, operations, and tests.
  • Removed choco (Chocolatey): Removed all choco facts, operations, tests, and metadata.
  • Test fix: Added missing NpmOutdatedPackages fact to npm directory quoting test.

Checklist

  • Pull request is based on the default branch (3.x at this time)
  • Pull request includes tests for any new/updated operations/facts
  • Pull request includes documentation for any new/updated operations/facts
  • Tests pass (see scripts/dev-test.sh)
  • Type checking & code style passes (see scripts/dev-lint.sh)

…ge managers

Introduce a common PackageInfo data model (name, version, status) and
build_package_map() helper so all package managers share a consistent
representation of installed, upgradeable, and held packages. Operations
like upgrade() are now idempotent — they check for available upgrades
before running. The ensure_packages() function accepts both the old
dict[str, set[str]] and new dict[str, PackageInfo] formats for backward
compatibility.

Migrated managers: apk, apt, brew, cargo, choco, dnf, gem, npm, opkg,
pacman, pip, pkg, pkgin, xbps, yum, zypper. Added pkg.update() and
pkg.upgrade() operations. Added upgradeable/held sub-facts for each
manager that supports them.
@wowi42 wowi42 marked this pull request as draft March 10, 2026 12:46
@wowi42
Copy link
Copy Markdown
Collaborator Author

wowi42 commented Mar 10, 2026

@Fizzadar

wowi42 added 4 commits March 10, 2026 15:23
Add facts and operations for two new package managers:

- Portage: PortagePackages (qlist), PortageUpgradeablePackages (emerge
  pretend), PortageMaskedPackages (package.mask). Operations: update
  (emerge --sync), upgrade (idempotent), packages (emerge/depclean).
- Paludis: PaludisPackages (cave print-ids). Operations: update
  (cave sync), upgrade (cave resolve), packages (cave resolve/uninstall).

Both support version pinning via category/name=version syntax, translated
to =category/name-version atoms for the respective package managers.
@Triquetra
Copy link
Copy Markdown

I was looking for Gentoo/portage support, so this PR is much anticipated. I hope it gets merged soon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants