Skip to content

v7.4.0

Latest

Choose a tag to compare

@kdeldycke kdeldycke released this 25 Jul 18:02
Immutable release. Only release title and notes can be modified.

Note

7.4.0 is available on 🐍 PyPI and πŸ™ GitHub.

  • [mpm] Raise the click-extra floor from 8.4.0 to 8.6.0, the release shipping the OperationTrail batch βœ“/βœ— trail upstreamed from mpm's own dispatch layer, which mpm now consumes from the published package instead of a git checkout.
  • [mpm] The Python and click-extra compatibility tables of the documentation read newest-first on both axes, following click-extra 8.6.0's {matrix} ordering defaults: the most recent compatibility information sits in the upper-left corner.
  • [mpm] Bump the packaging pins of click-extra to 8.6.0 and the Nix pin of extra-platforms to 13.3.1 across the Nix, MacPorts and Alpine overlays, to match mpm's dependency floors.
  • Breaking: [mpm] Remove the PackageManager.query_parts class method: Package.query_parts is the canonical query tokenizer.
  • Breaking: [mpm] The SBOM stats() dictionaries drop the components_in_document (CycloneDX) and relationships_total (SPDX) keys, which no consumer read.
  • Breaking: [mpm] Rename the manager deprecated flag to unmaintained and broaden it to cover abandoned or inactive upstreams (archived, years without a release, formally superseded, or a discontinued platform), not just officially retired projects. The deprecation_url attribute becomes an unmaintained_message markdown block rendered into the documentation, and the [mpm.managers.<id>] config override key deprecated is likewise renamed to unmaintained.
  • [mpm] Flag apt-cyg, pacaur and swupd as unmaintained, joining apm: their upstreams are archived, abandoned or belong to a discontinued platform, so they are hidden from default selection and dropped from the test matrices. Name them explicitly or pass --all-managers to still drive them.
  • [mpm] Add a maintenance_note attribute that renders a note admonition atop a manager's documentation page for still-maintained but slowing or superseded upstreams worth watching (cave, dnf, fink, sorcery, stew, sun-tools, tazpkg, yarn, yum).
  • [mpm] Drop the unmaintained pacapt, sysget and whohas tools from the benchmark comparison and add a note pointing their users to mpm as an actively-maintained replacement covering the same cross-manager operations.
  • [mpm] Package managers gain shared parse_regex_lines and parse_json_items engines on the base class: configuration-defined operations and built-in managers now parse their listings through the same code path.
  • [mpm] The action commands (install, remove, upgrade, restore) name failed packages uniformly as id@version in their end-of-run critical: summary, instead of a mix of raw purls and bare IDs.
  • [mpm] doctor singularizes its end-of-run summary when a single manager reports problems.
  • [mpm] dump --merge and dump --update-version no longer misreport an existing target file as about to be overwritten, and only disclose the inert --overwrite flag when it was actually passed.
  • [brew,cask] cleanup invokes the cache scrub with the long-form --scrub flag.
  • [mpm] Add a --plan/-p option that prints the exact package-manager commands each state-changing operation would run, without running them. Read-only queries (installed, outdated, search) still execute, so install, remove and upgrade --all resolve to the commands they would actually run; the plan prints to stdout, one copy-pasteable command per line.
  • [mpm] Add an --orphans option to remove that also drops the dependencies the package alone pulled in, mapped to each manager's native scoped cascade verb (apt remove --auto-remove, pacman --remove --recursive, dnf autoremove, xbps-remove --recursive, zypper remove --clean-deps). Managers with no such verb remove the package only. mpm builds no dependency graph: it delegates the reverse-dependency reasoning to the manager.
  • [mpm] cleanup decomposes into cumulative categories, each with a two-sided flag pair: --orphans/--skip-orphans (system-wide orphan sweep: apt autoremove, brew autoremove, flatpak uninstall --unused), --cache/--skip-cache (caches, downloads and left-over artifacts, the category a monolithic cleanup amounts to) and --repair/--skip-repair (local state verification, like flatpak repair). Positive flags narrow the run to the listed categories, skip flags subtract them, and a plain cleanup runs the cache and repair categories only: the orphan sweep is the one category removing packages, so it stays strictly behind --orphans, uniformly across managers, just as remove keeps its dependency cascade behind the same flag. The per-manager narration and the βœ“/βœ— trail name the categories dispatched to each manager (βœ“ brew (cache)). A manager with no native sweep verb but a native orphan listing gets the sweep synthesized from its orphans query, removing the listed orphans one by one until none are left (the in-process equivalent of Arch's pacman -Rns $(pacman -Qtdq) idiom, covering pacman, its AUR helpers and zypper); the synthesized sweep only engages on an explicit --orphans, so a skip flag can never remove packages a plain cleanup would have left alone.
  • [mpm] Add an orphans subcommand listing the packages installed as dependencies that nothing requires anymore, without removing them. Each manager reports through its native read-only query (pacman --query --deps --unrequired, brew autoremove --dry-run, dnf repoquery --unneeded, zypper packages --unneeded, pkg autoremove --dry-run, apt autoremove --simulate, xbps-query --list-orphans, emerge --depclean --pretend, cave purge in its default pretend mode, pkg_delete -a -n). Supports the same query filtering, table projection and serialization as installed.
  • [mpm] Add a doctor subcommand (aliases check and diagnose) running each manager's native self-diagnosis (brew doctor, pip check, pacman --database --check, npm doctor, dnf check, gem check, composer diagnose, mise doctor, apt-get check, pkg check --checksums, xbps-pkgdb --all, flatpak repair --dry-run, scoop checkup, port diagnose, tlmgr check all). Read-only: health is read from each command's exit code, the report (merging <stdout> and <stderr>) is relayed verbatim, and the run exits non-zero when any manager reports problems, so it can gate a CI job (-0/--zero-exit opts out).
  • [mpm] Configuration-defined managers can declare remove_orphan, cleanup_orphan, cleanup_cache, cleanup_repair, doctor and orphans operations, wiring them to remove --orphans, the cleanup category flags and the orphans subcommand.
  • Breaking: [mpm] cleanup is no longer an operation managers define: every manager now declares cleanup category methods only (cleanup_orphan, cleanup_cache, cleanup_repair), and PackageManager.cleanup() composes the natively implemented ones. Monolithic cleanups across the pool were reclassified as cleanup_cache, and a configuration-defined manager declaring the old cleanup operation is rejected with an error naming the category keys.
  • [cave,pkg-tools] Their cleanup commands, both orphan sweeps (cave purge, pkg_delete -a), are re-declared as cleanup_orphan: cleanup --orphans now reaches them and cleanup --cache leaves them alone.
  • [apt,apt-mint,brew,cask,cave,dnf,dnf5,emerge,pkg,pkg-tools,xbps,yum] Plain cleanup no longer removes orphaned packages: their native sweeps moved behind cleanup --orphans. This also stops emerge's cleanup from triggering its pre-depclean world upgrade unless --orphans is given.
  • [emerge] The cleanup steps split into cleanup_orphan (the safety upgrade plus --depclean) and cleanup_cache (eclean distfiles), giving emerge native cleanup --orphans support.
  • [uv] cleanup skips uv's cache commands when mpm itself was launched by uv run or uvx, whose parent process locks the cache for as long as mpm lives: each uv cache command would otherwise wait on its own ancestor for UV_LOCK_TIMEOUT (300 seconds by default) and fail, stalling the cleanup for ten minutes.
  • [dnf,dnf5,xbps,yum] remove no longer cascades to orphaned dependencies by default: a plain removal keeps them. Use the new remove --orphans to restore the previous behavior.
  • [mpm] Every supported package manager gets a dedicated documentation page detailing its platforms, operations and backfilled capabilities, CLI invocation and version probe, escalation and cooldown behaviors, purl types, selection and configuration examples and the captured native outputs its parsers were written against, all rendered live from the manager declarations at Sphinx build time. A new hub page indexes the 72 pages, and manager IDs in the readme's operation matrix, the benchmark table and the augmentations table now link to them.
  • [mpm] Each per-manager documentation page opens with a "What mpm adds to <id>" section, pitched at a reader who already knows the native tool: the capabilities mpm backfills for that manager (synthesized upgrade --all, orphan sweep, --exact/--extended search), the cross-manager reach naming its purl-ecosystem neighbors, and the universal augmentations. Derived live from the capability declarations, so it describes only what mpm does and never overstates a native limitation.
  • [winget] Documentation samples use the conventional > PowerShell prompt instead of PS C:\Users\kev>, reconnecting them to the corpus harvester: the documented commands are now validated against the constructed ones, the manager page gains its full Rosetta table and a clean version transcript, and the reference traces render under proper pwsh-session fences. The full and single-package upgrade samples show the exact winget update --all and winget install invocations mpm runs, and the agreement-prompt and different-install-technology illustrations move to non-fixture console fences.
  • [mpm] Each per-manager documentation page gains a Rosetta table mapping the manager's own commands (uv pip list, brew install, pacman --sync, …) to their one-to-one mpm equivalents, harvested from the operation methods' documented samples, and a recipes section with copy-paste snapshot/restore, SBOM export and CI-health-gate commands. The cooldown section now frames release-age gating as a supply-chain guard, the invocation section explains the forced arguments and environment as CI-friendly defaults, and the reference-traces section notes how the same raw output unifies through mpm.
  • [mpm] Add a MacPorts Portfile overlay under packaging/macports, carrying the port plus the dependency ports missing from the official tree, tested by a new macports-source job.
  • [macports] Meta Package Manager is now available in MacPorts upstream, installable with sudo port install meta-package-manager and tested by a new macports job.
  • [macports,pkg,snap] Mutating operations now escalate through sudo by default, matching each tool's canonical invocation (sudo port install, sudo pkg install, sudo snap install): MacPorts installs root-owned under /opt/local, the FreeBSD pkg frontend gains the markers its ports sibling already had, and snapd denies state changes from an unprivileged client. Opt out with --no-sudo or a per-manager sudo = false override. pkg passes IGNORE_OSVERSION as a command-line option now, which survives the sudo environment reset where the environment variable would be stripped.
  • [cpan,gem] The write operations carry dormant privileged markers like pip and npm: --sudo or a per-manager sudo = true override escalates installs into a system Perl or Ruby. Nothing escalates by default.
  • [fwupd] Mutating operations no longer escalate through sudo, aligning fwupd with the other polkit-native daemon clients (flatpak, pkcon): fwupdmgr hands firmware writes to the fwupd daemon over D-Bus, which authorizes them through polkit. Under a strict polkit policy, unattended mutations need a rule permitting them without interactive authentication, or an mpm run as root.
  • [pacstall,topgrade] Marked as internal escalators (internal_sudo): pacstall re-execs itself through sudo pacstall and topgrade runs each privileged step through its own sudo, so mpm never wraps them, keeps a warm credential cache alive for their mid-run escalations, and watches for hidden password prompts.
  • [pacman] sync now escalates through sudo like its other write commands: refreshing the sync databases writes root-owned state.
  • [dnf,dnf5] cleanup --cache now escalates through sudo: dnf clean all clears the root-owned package cache.
  • [mpm] Refresh the benchmark page operations table: new List orphaned dependencies row, the autoremove row re-scoped to the remove --orphans cascade, and mpm's new orphans and doctor capabilities credited. Every competitor column is re-audited at its current release (topgrade 17.8.0, pacaptr 0.23.1, brew 6.0.12): capabilities only reachable bundled inside another operation are downgraded to 🟑, Homebrew's concurrent-execution cell flips to supported (brew bundle install --jobs now installs across backends in parallel), and the negative-evidence links are re-verified, two of them pinned to the maintainer's exact comment.
  • [mpm] Add an Alpine Linux APKBUILD overlay under packaging/alpine, carrying the package plus the 4 dependency packages missing from the official aports tree, tested by a new apk-source job.
  • [mpm] Regroup all downstream packaging knowledge on a new packaging.md documentation page: the test-suite wiring for distribution packagers, the dependency graph, the click-extra compatibility matrix, and a per-channel catalog with the build-from-spec instructions previously spread across the install page tabs. The install page now targets end users only, and the binaries catalog moves to the development section of the documentation.
  • [mpm] Ship tests/, docs/ and the .github/ workflow files in the PyPI sdist (kept out of the wheel), so distribution packagers can build and run the suite straight from the sdist instead of fetching a GitHub tag tarball.
  • [mpm] Split the test suite with a new integration marker: writable-$HOME builders run the hermetic layer with pytest -m "not integration" instead of a per-module ignore list. Repo-maintenance sync guards skip outside a git checkout, and the SBOM test modules skip when their optional extras are absent, so a lean build no longer needs to ignore them.
  • Breaking: [mpm] Rename the --show-params introspection flag to --params, and its environment variable from MPM_SHOW_PARAMS to MPM_PARAMS, following click-extra's own rename.
  • [mpm] Manager invocations now run in their own POSIX session and process group: a timeout or Ctrl+C kills the whole process tree, so a wedged manager CLI leaves no orphaned grandchildren behind. The mutating call of an internal escalator on a cold sudo credential cache is the exception: it keeps the terminal, leaving its password prompt answerable.
  • [mpm] managers now honors the global --timeout for the version probes feeding its table: its selection bypassed the option plumbing, so the probes always ran at the 120-second read-only default and a wedged binary held its row for that long regardless of the option.
  • [mpm] The benchmark manager-support table and the augmentations table keep a generated copy in their Markdown sources, between <!-- mirror --> markers below their python:render blocks: reviewable in raw diffs and rendered on GitHub, refreshed by click-extra refresh-directives, while Sphinx builds keep rendering the live output.
  • [mpm] Convert every docstring and comment of the code base from reStructuredText to MyST markdown, rendered through click-extra's myst_docstrings Sphinx extension, which converts them back to reST at build time so autodoc keeps working. The CLI-session fixtures documented in manager docstrings now live in ```{code-block} shell-session fences, the corpus harvester reads the fence form, and the manager documentation pages inline the MyST class docstrings directly instead of wrapping them in an {eval-rst} block.
  • [mpm] The binaries download table of the install page is now generated from the binaries catalog at Sphinx build time, restoring working links after binary assets gained versioned filenames.
  • [bar-plugin] Fix a crash when probing an mpm invocation whose binary does not exist: the failed probe now reports the error instead of raising UnboundLocalError.
  • [bar-plugin] Version-diff colors now reach SwiftBar and Xbar: the highlighting introduced in 7.3.0 never rendered in the menu bar, because the plugin captures mpm outdated --plugin-output through a pipe, where the automatic color detection stripped every ANSI code. Plugin output now keeps its colors on any output stream, unless colorization is explicitly disabled (--color=never, NO_COLOR). ANSI codes captured inside relayed error messages are stripped instead, since error lines are marked ansi=false. The unchanged-version prefix also moves from bright-black to a theme-neutral xterm-256 mid-gray on menu lines only: SwiftBar maps bright-black to a fixed dark gray, near-invisible on dark-mode menus, while the mpm outdated table keeps the terminal-themed bright-black.
  • [bar-plugin] An outdated package whose manager provides no single-package upgrade command no longer crashes the rendering: its menu line simply carries no upgrade action.
  • [pacaur,paru,yay] The AUR helpers are no longer wrapped in sudo: they refuse or break under root (makepkg rejects root builds, paru aborts AUR transactions, pacaur aborts its sync operations) and escalate through their own internal sudo pacman calls, which mpm now tracks with the internal_sudo marker (warm credential-cache keepalive, hidden-prompt watchdog). This also lets yay's cooldown environment overlay reach the process, where the sudo wrap used to strip it.
  • [pkg] installed now lists every package registered in the pkg database instead of only explicitly-requested ones: the %a = 0 automatic-flag filter is dropped, and the query invocation loses the literal quote characters it carried, aligning it with the ports invocation reading the same database.
  • [mpm] A failed manager command now relays the tail of its captured <stderr> (or <stdout> when <stderr> is empty) as a warning: tagged with the manager ID, at the moment of failure and across every operation, instead of keeping it at DEBUG only. A successful command's <stderr> chatter stays at DEBUG, version probes and doctor are exempt, and the end-of-run error summary now points at --verbosity DEBUG for the full transcript only, no longer as the way to see why a command failed. Closes #1968.

Full changelog: v7.3.0...v7.4.0