meta_package_manager.managers package

Submodules

meta_package_manager.managers.am module

class meta_package_manager.managers.am.AM[source]

Bases: PackageManager

AppImage manager, covering the applications of its own catalog.

Note

am and appman are the same script under two names, and only this one is wrapped. AppMan’s repository holds no implementation at all, just a stub that replaces itself with this script, which then reads its own path to decide whether to run system-wide or under the user’s home. Wrapping both would double-count: am -fi renders AppMan’s applications in a second table of its own whenever AppMan is configured, so they are already reported here. See Unsupported managers for the recorded decision.

Caution

The listing’s column count depends on its contents: a fifth column appears between the name and the version whenever an application resolves to a third-party catalog. The version is therefore located by reading the header rather than by counting from the left, which is also what lets a listing carrying two tables be parsed in one pass.

Note

No install. am refuses to be run under sudo and escalates on its own instead, priming the credential cache before it installs anything, so an install blocks on a password prompt that no flag of its own can answer. Removal is unaffected, -R needing no confirmation and no escalation mpm has to arrange.

No outdated either: nothing reports a remote version without installing it, and the catalog carries no versions at all. Its maintainer declined to publish a machine-readable feed, so this is settled rather than pending, and upgrade --all is unaffected.

No search: results are folded to the terminal width before they are printed, so a record wraps across lines with no marker to rejoin it, and its description is unrecoverable once wrapped.

Documentation: AM.

Initialize cli_errors list.

name: str = 'AppImage Manager'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/ivan-hc/AM'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

sudo: bool | None = False

User escalation policy: run this manager’s privileged commands with sudo.

None (the default) means the user expressed no preference, so the built-in default_sudo decides. True/False force escalation on or off for every operation this manager marks privileged (a build_cli(..., sudo=True) call). Set globally by mpm --sudo / mpm --no-sudo and per manager by the [mpm.managers.<id>] sudo config key, the latter winning (see meta_package_manager.pool.ManagerPool._select_managers()).

Only privileged operations on UNIX are ever escalated. A manager that escalates internally (internal_sudo) has no such markers and is never wrapped in sudo by mpm: its own sudo reuses the credential cache when prime_sudo() finds it already warm, and is otherwise covered by the silent-call notice in run().

default_sudo: bool = False

am refuses outright to run under sudo, exiting rather than proceeding, and arranges its own escalation per privileged step instead.

internal_sudo: bool = True

It calls the escalation binary itself for the steps that need it, picking sudo or doas from what the host provides.

requirement: str | None = '>=10.4'

The release that added the flag answering its confirmation prompts, which is what makes the mutating operations here unattended.

extra_env: ClassVar = {'NO_COLOR': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_cli_options: tuple[str, ...] = ('--version',)

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

cli_names: tuple[str, ...] = ('am',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'am'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

version_regexes: tuple[str, ...] = ('(?m)^(?P<version>\\d+(?:\\.\\d+)+)$',)

Search a line holding nothing but the version.

$ am --version
10.4

Anchored to a whole line because am prepends a multi-line warning banner on hosts that restrict user namespaces, which is the default on recent Ubuntu: a pattern matching the first number anywhere would read that banner instead.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property installed: Iterator[Package]

Fetch installed packages.

-fi is the listing without the trailing table of unmanaged AppImages, and --byname fixes its order, which is otherwise by size.

$ am -fi --byname

 YOU HAVE INSTALLED 3 PROGRAMS MANAGED BY "AM"

 - APPNAME              | VERSION             | TYPE           | SIZE
 - -------              | -------             | ----           | ----
 ◆ code                 | 1.107.1             | dynamic-binary | 450 MiB
 ◆ krita                | 5.2.14              | appimage       | 322 MiB
 ◆ zoom                 | 6.4.3.827.glibc2.27 | appimage*      | 288 MiB

Note

A version is genuinely optional here: an application whose updater reports none renders an empty cell, and one is yielded without a version rather than with a placeholder.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

--apps confines the run to the installed applications. The bare form additionally refreshes the catalogs and rewrites the am script itself, which is not what upgrading packages should mean.

$ am -y -u --apps
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Naming an application genuinely restricts the run to it.

$ am -y -u firefox
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

-R is the unattended removal: unlike its lowercase counterpart it asks for no confirmation, so no flag is needed to answer one.

$ am -R firefox
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

Clears the download caches, the caches applications leave in the home directory, and the launchers left behind by removals.

$ am -c
Return type:

None

meta_package_manager.managers.antidote module

meta_package_manager.managers.antidote.antidote_source_path()[source]

Locate the antidote.zsh file every invocation sources.

Falls back to the documented clone location when none of the candidates exists, so the built command stays well-formed and simply fails to source, which is what makes the version probe double as Antidote’s presence check.

Return type:

Path

class meta_package_manager.managers.antidote.Antidote[source]

Bases: PackageManager

Antidote is a Zsh plugin manager, successor to antibody.

Antidote clones each bundle from GitHub or any other forge into $ANTIDOTE_HOME, and records it in the user’s .zsh_plugins.txt file. Packages are identified by the user/repo slug Antidote both reports and accepts, which is the id mpm keys them on.

Caution

antidote is a shell function, not a standalone binary: the antidote script shipped in the repository carries a Zsh shebang but is not executable, and Homebrew installs it as package data under share/antidote rather than linking it into bin. Every invocation is therefore wrapped in zsh -c 'source <antidote.zsh> && antidote <args>'. Zsh is the manager’s CLI, and Antidote’s own presence is established by the version probe: a host with Zsh but no Antidote fails to source and reports no version, which leaves the manager unavailable.

Note

No search: Antidote resolves bundles straight from forge URLs and indexes no registry to search.

Note

No upgrade_one: antidote update takes no bundle argument, only the --self and --bundles scope flags, so a single bundle cannot be targeted. mpm auto-skips the operation and upgrade --all still works.

Documentation: antidote.sh.

Initialize cli_errors list.

homepage_url: str | None = 'https://antidote.sh'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.2.0'

First release whose list --jsonl and update --dry-run are both sound.

Both landed in 2.0.0, but each carried a defect this implementation depends on being fixed: 2.1.1 repaired list --jsonl emitting invalid JSON whenever a value held a quote, backslash or control character, and 2.2.0 stopped update --dry-run deepening shallow clones, a permanent side effect that made a dry run something other than a query. 2.2.0 also fixed antidote update reporting success when a worker had failed, which is the exit code mpm reads to mark the operation.

cli_names: tuple[str, ...] = ('zsh',)

Zsh is the binary mpm actually executes.

Antidote is a shell function defined by an antidote.zsh file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable. Keying the manager on Zsh instead makes the version probe the presence check, since sourcing an absent antidote.zsh yields no version and leaves the manager unavailable.

extra_env: ClassVar = {'NO_COLOR': '1', 'SHELL_SESSIONS_DISABLE': '1'}

Antidote gives NO_COLOR precedence over every other color signal, so the parsers see clean text. SHELL_SESSIONS_DISABLE keeps macOS’ Zsh session bookkeeping from writing a session file on every query.

version_regexes: tuple[str, ...] = ('antidote version (?P<version>\\S+)',)

Antidote appends the short commit of its own checkout to the release it reports.

$ zsh -c 'source ~/.antidote/antidote.zsh && antidote --version'
antidote version 2.3.0 (9bb69ab)
id: str = 'antidote'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Antidote'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Zsh shell Antidote needs.

The version probe is guarded by a readability test that exits successfully when antidote.zsh is absent. Zsh is the default shell on macOS and near ubiquitous elsewhere, so an unguarded probe would turn every host that merely has Zsh into a manager reporting errors. An antidote.zsh that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the zsh -c wrapper and Antidote never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

Antidote emits one JSON object per line rather than a single array, so the listing is decoded line by line. The sha reported for a bundle is the Git commit its clone is checked out at, which is the only revision Antidote records: a bundle is tracked by branch unless the user pins it with a pin: annotation.

$ zsh -c 'source ~/.antidote/antidote.zsh && antidote list --jsonl'
{"url":"https://github.com/rupa/z","repo":"rupa/z","path":"/home/kev/.cache/antidote/github.com/rupa/z","sha":"d37a763a6a30e1b32766fecc3b8ffd6127f8a0fd"}
{"url":"https://github.com/zsh-users/zsh-completions","repo":"zsh-users/zsh-completions","path":"/home/kev/.cache/antidote/github.com/zsh-users/zsh-completions","sha":"729a2408fb129bcda7e8a21ae7bf349fe295b634"}
property outdated: Iterator[Package]

Fetch outdated packages.

--dry-run fetches each bundle’s remote and reports what an update would move, without touching a single working tree. Both revisions are the short commits Antidote prints, so an outdated bundle reads as a commit-to-commit move rather than a version bump: bundles are tracked by branch, and Antidote records no version of its own.

$ zsh -c 'source ~/.antidote/antidote.zsh && antidote update --dry-run'
Checking for bundle updates (dry run)...
antidote: checking for updates: rupa/z
antidote: checking for updates: zsh-users/zsh-completions
Waiting for bundle updates to complete...

Bundle rupa/z update check complete.
antidote: update available: rupa/z b82ac78 -> d37a763
d37a763 Escape calls for sed and awk in case someone aliased them (#264)
703bb54 avoid issues when ``date`` has been aliased
6ba0722 avoid issues when ``env`` has been aliased

Dry run complete. No changes were made.

antidote: skipping self-update (dry run)
install(package_id, version=None)[source]

Install one package.

install both clones the bundle and appends it to the user’s .zsh_plugins.txt, so a package installed through mpm is loaded by the next shell instead of sitting on disk unreferenced.

$ antidote install rupa/z
Adding bundle to '/home/kev/.zsh_plugins.txt':
rupa/z
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

Note

Scoped to --bundles so the update stays a package operation. A bare antidote update also updates Antidote itself, which is the manager rather than a package, and which would mean a Git pull inside a Homebrew keg on a host that installed it that way.

$ antidote update --bundles
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

purge is the exact counterpart of Antidote.install(): it drops the clone and comments the bundle out of the user’s .zsh_plugins.txt, so the next shell no longer loads it.

$ antidote purge rupa/z
Removed 'rupa/z'.
Bundle 'rupa/z' was commented out in '/home/kev/.zsh_plugins.txt'.
Return type:

str

meta_package_manager.managers.antigen module

meta_package_manager.managers.antigen.antigen_source_path()[source]

Locate the antigen.zsh file every invocation sources.

Antigen documents no install location of its own: its README has the user curl -L git.io/antigen > antigen.zsh into a directory of their choosing, then source /path-to-antigen/antigen.zsh. Discovery is therefore best-effort over the two conventional spots plus $ADOTDIR, and a user who keeps it anywhere else simply leaves the manager unavailable rather than seeing it misbehave.

Falls back to the first candidate when none exists, so the built command stays well-formed and fails to source, which is what makes the version probe double as Antigen’s presence check.

Return type:

Path

class meta_package_manager.managers.antigen.Antigen[source]

Bases: PackageManager

Antigen is a plugin manager for Zsh.

Bundles are declared in the user’s .zshrc with antigen bundle calls, then cloned under $ADOTDIR. Packages are identified by the short owner/repo name Antigen reports, which is the id mpm keys them on.

Caution

antigen is a shell function, not a standalone binary: it is defined by sourcing an antigen.zsh file, so it cannot serve as the manager’s CLI. Every invocation is therefore wrapped in zsh -c. Zsh is the binary mpm executes, and Antigen’s own presence is established by the version probe.

Unlike its siblings, Antigen documents no canonical install path, so antigen_source_path() can only guess at the conventional ones. A user who sources it from elsewhere leaves the manager unavailable.

Caution

No install: Antigen materializes exactly the bundle set the user’s own .zshrc declares. antigen bundle clones and loads a bundle for the current shell only, writing nothing back, so a package installed through mpm would vanish with the process. Installing one for real would mean mpm editing the user’s .zshrc, which is configuration mpm does not own.

Note

No outdated: Antigen compares nothing against its remotes short of performing the update. upgrade --all still works, and mpm auto-skips the operation.

Documentation: antigen.

Initialize cli_errors list.

name: str = 'Zsh Antigen'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/zsh-users/antigen'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.0.0'

The 2.x series is where list, purge and update settled as the subcommands this class drives, alongside the $ADOTDIR layout.

cli_names: tuple[str, ...] = ('zsh',)

Zsh is the binary mpm actually executes.

Antigen is a shell function defined by an antigen.zsh file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable. Keying the manager on Zsh instead makes the version probe the presence check.

extra_env: ClassVar = {'NO_COLOR': '1', 'SHELL_SESSIONS_DISABLE': '1'}

SHELL_SESSIONS_DISABLE keeps macOS’ Zsh session bookkeeping from writing a session file on every query, as for Antidote.

version_cli_options: tuple[str, ...] = ('version',)

Antigen spells it as a subcommand: it defines an antigen-version function reached as antigen version, and recognizes no --version flag.

id: str = 'antigen'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

version_regexes: tuple[str, ...] = ('Antigen\\s+v?(?P<version>\\S+)',)

Antigen prints its release followed by the short commit it was built from.

The optional v absorbs the tag prefix its release builds carry. A copy taken from the development branch reports the literal string develop there instead of a version, which parses to nothing and correctly leaves the manager unavailable.

$ zsh -c 'source ~/antigen.zsh && antigen version'
Antigen v2.2.3 (0554db1)
Revision date: 2026-07-14 16:52:45 +0100
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Zsh shell Antigen needs.

The version probe is guarded by a readability test that exits successfully when antigen.zsh is absent. Zsh is the default shell on macOS and near ubiquitous elsewhere, so an unguarded probe would turn every host that merely has Zsh into a manager reporting errors.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the zsh -c wrapper and Antigen never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

--simple is the listing format that prints one bare bundle name per line. Antigen’s default --short format appends @ <revision> to each, but that revision is the tracked branch (literally master for any bundle not pinned to one), not a version, so the simple form is what mpm parses.

$ zsh -c 'source ~/antigen.zsh && antigen list --simple'
zsh-users/zsh-syntax-highlighting
zsh-users/zsh-completions
zsh-users/zsh-history-substring-search
upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ antigen update
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

purge drops the bundle’s clone from the filesystem. It leaves the user’s .zshrc untouched, so a bundle still declared there is cloned again by the next shell: the removal is of the installed copy, not of the declaration.

$ antigen purge zsh-users/zsh-completions --force
Return type:

str

meta_package_manager.managers.apk module

class meta_package_manager.managers.apk.APK[source]

Bases: PackageManager

Alpine Package Keeper (apk) used by Alpine Linux.

Documentation: Alpine Package Keeper.

Note

installed and outdated both parse the list applet, so the version floor is 2.10.0: the release that introduced it. Progress output is disabled on every call to keep the parsed lines stable.

Caution

outdated reads the local repository cache rather than the remote, so sync must run first for an accurate upgrade list.

Initialize cli_errors list.

name: str = 'Alpine apk'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://gitlab.alpinelinux.org/alpine/apk-tools'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=2.10.0'

The list applet, used by installed() and outdated(), was introduced in version 2.10.0.

pre_args: tuple[str, ...] = ('--no-progress',)

Suppress progress indicators so log lines are stable when parsing.

Source: apk(8) global options.

version_regexes: tuple[str, ...] = ('apk-tools\\s+(?P<version>[^\\s,]+)',)
$ apk --version
apk-tools 2.14.10, compiled for x86_64.
property installed: Iterator[Package]

Fetch installed packages.

$ apk --no-progress list --installed
acl-2.2.53-r0 x86_64 {acl} (LGPL-2.1-or-later AND GPL-2.0-or-later) [installed]
alpine-baselayout-3.4.3-r1 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]
apk-tools-2.14.0-r5 x86_64 {apk-tools} (GPL-2.0-only) [installed]
busybox-1.36.1-r5 x86_64 {busybox} (GPL-2.0-only) [installed]
python3-3.11.6-r0 x86_64 {python3} (PSF-2.0) [installed]
property outdated: Iterator[Package]

Fetch outdated packages.

Caution

Reads from the local repository cache. Run sync() first to refresh the index.

$ apk --no-progress list --upgradable
acl-2.3.1-r0 x86_64 {acl} (LGPL-2.1-or-later) [upgradable from: acl-2.2.53-r0]
python3-3.11.7-r0 x86_64 {python3} (PSF-2.0) [upgradable from: python3-3.11.6-r0]
search(query, extended, exact)[source]

Fetch matching packages.

Caution

apk search matches package names with case-insensitive substring globbing. Exact matching is not supported and is handled by meta_package_manager.manager.PackageManager.refiltered_search(). Extended search adds the --description flag so the query is also matched against package descriptions.

$ apk --no-progress search --verbose firefox
firefox-120.0-r0
firefox-esr-115.5.0-r0
firefox-langpack-de-120.0-r0
$ apk --no-progress search --verbose --description ntp
chrony-4.4-r1
ntp-4.2.8_p17-r0
openntpd-6.8_p1-r1
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo apk --no-progress add firefox
Return type:

str

cli_names: tuple[str, ...] = ('apk',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'apk'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ sudo apk --no-progress upgrade
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ sudo apk --no-progress upgrade firefox
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo apk --no-progress del firefox
Return type:

str

sync()[source]

Synchronize the local package index from remote repositories.

$ sudo apk --no-progress update
Return type:

None

cleanup_cache()[source]

Drop the local package cache.

$ sudo apk --no-progress cache clean
Return type:

None

meta_package_manager.managers.apm module

class meta_package_manager.managers.apm.APM[source]

Bases: PackageManager

Atom’s package manager, from the sunset Atom editor.

apm installed packages and themes for GitHub’s Atom editor, exposing an npm-style CLI whose queries mpm parses from --json output.

Atom was sunset on December 15, 2022, so apm is flagged unmaintained here. mpm keeps the wrapper while doing so stays cheap: the community fork atom-community/apm has been floated but never produced a usable drop-in, and per the project’s stability policy an unmaintained manager may be dropped without notice once it becomes a burden to maintain.

Initialize cli_errors list.

unmaintained: bool = True

A manager whose upstream project is no longer maintained.

Covers projects that are officially retired and those we infer are abandoned: archived on their forge, left without a release or commit for years, formally superseded by a successor, or part of a discontinued platform. See the stability policy in CLAUDE.md for the full criteria.

An unmaintained manager is hidden from package selection by default (you can still use it by explicitly calling for it on the command line), and is exempt from the project stability policy: it may be dropped, in part or in full, in any release and without notice, once keeping it working becomes too burdensome.

Unmaintained managers are kept out of the functional and integration test matrices, so an unreliable or flaky one never blocks a release and we save CI resources. The commitment is to keep the wrapper for as long as that stays cheap: the cheap static invariants (ID format, attribute ordering, …) still apply for as long as the manager’s code lives in the source tree, to keep that code valid.

Every unmaintained manager must document itself through unmaintained_message.

unmaintained_message: str | None = 'Atom was [sunset on 2022-12-15](https://github.blog/2022-06-08-sunsetting-atom/); `apm` is archived and no community fork (such as [atom-community/apm](https://github.com/atom-community/apm)) has produced a usable drop-in.'

Evidence and rationale for the unmaintained flag, as a MyST markdown block.

Rendered into the documentation (the manager’s page, and a ⚠️ marker in the manager tables). May embed markdown links to the archival notice, the successor project, or the discontinuation announcement. Required for every manager whose unmaintained flag is set, and only meaningful on such managers. Enforced by test_unmaintained.

name: str = 'Atom apm'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://atom.io/packages'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

version_regexes: tuple[str, ...] = ('apm\\s+(?P<version>\\S+)',)
$ apm --version
apm  2.6.2
npm  6.14.13
node 12.14.1 x64
atom 1.58.0
python 2.7.16
git 2.33.0
property installed: Iterator[Package]

Fetch installed packages.

$ apm list --json
{
  "core": [
    {
      "name": "background-tips",
      "version": "0.26.1",
      "description": "Displays tips about Atom in the background."
    }
  ],
  "user": [
    {
      "name": "file-icons",
      "version": "2.0.9",
      "description": "Assign file extension icons"
    }
  ]
}
property outdated: Iterator[Package]

Fetch outdated packages.

$ apm outdated --compatible --json
[
  {
    "name": "file-icons",
    "version": "2.0.9",
    "latestVersion": "2.0.10",
    "description": "Assign file extension icons"
  }
]
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports exact matching.

$ apm search --json python | jq
[
  {
    "name": "atom-python-run",
    "main": "./lib/atom-python-run.js",
    "version": "0.7.3",
    "description": "Run a python source file.",
    "keywords": [
      "python"
    ],
    "repository": "https://github.com/foreshadow/atom-python-run",
    "license": "MIT",
    "engines": {
      "atom": ">=1.0.0 <2.0.0"
    },
    "dependencies": {},
    "readme": "Blah blah",
    "downloads": 41379,
    "stargazers_count": 16
  },
  {
    "name": "build-python",
    "version": "0.6.3",
    "description": "Atom Build provider for python/python3",
    "repository": "https://github.com/idleberg/atom-build-python",
    "license": "MIT",
    "keywords": [
      "buildprovider",
      "compile",
      "python",
      "python3",
      "linter",
      "lint"
    ],
    "main": "lib/provider.js",
    "engines": {
      "atom": ">=1.0.0 <2.0.0"
    },
    "providedServices": {
      "builder": {
        "description": "Compiles Python",
        "versions": {
          "2.0.0": "provideBuilder"
        }
      }
    },
    "package-deps": [
      "build"
    ],
    "dependencies": {
      "atom-package-deps": "^4.3.1"
    },
    "devDependencies": {
      "babel-eslint": "^7.1.1",
      "coffeelint-stylish": "^0.1.2",
      "eslint": "^3.13.1",
      "eslint-config-atom-build": "^4.0.0",
      "gulp": "github:gulpjs/gulp#4.0",
      "gulp-coffeelint": "^0.6.0",
      "gulp-debug": "^3.0.0",
      "gulp-jshint": "^2.0.4",
      "gulp-jsonlint": "^1.2.0",
      "gulp-lesshint": "^2.1.0",
      "jshint": "^2.9.4"
    },
    "scripts": {
      "test": "gulp lint"
    },
    "readme": "Blah blah",
    "downloads": 2838,
    "stargazers_count": 0
  },
  (...)
]
$ apm search --no-description --json python | jq
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ apm install image-view
The image-view package is bundled with Atom and should not be explicitly
installed. You can run ``apm uninstall image-view`` to uninstall it and then
the version bundled with Atom will be used.
Installing image-view to /Users/kde/.atom/packages ✓
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ apm update --no-confirm
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ apm update --no-confirm image-view
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ apm uninstall image-view
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

$ apm clean
Return type:

None

cli_names: tuple[str, ...] = ('apm',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'apm'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.apt module

class meta_package_manager.managers.apt.APT[source]

Bases: PackageManager

Base class for Debian’s apt front-end and its variants.

Documentation: apt(8) man page.

Command equivalences with other managers are listed in Pacman/Rosetta.

mpm drives the high-level apt binary, not apt-get or apt-cache, over system-wide packages. Mutations escalate through sudo and force --yes to stay non-interactive. APT_Mint retargets Linux Mint’s same-named but differently-behaved apt.

Note

apt’s listing and search commands emit Listing..., Sorting... and Full Text Search... preambles plus progress indicators. --quiet drops the progress bars, and each parser anchors on the name/suite version arch row shape, so the preamble lines fall through.

Note

search matches names only by default. An exact query is wrapped as the ^query$ regex apt supports natively; an extended query switches to --full to pull descriptions into the output for mpm to post-filter.

Initialize cli_errors list.

name: str = 'Debian apt'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://wiki.debian.org/AptCLI'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=1.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('--quiet',)
version_regexes: tuple[str, ...] = ('apt\\s+(?P<version>\\S+)',)
$ apt --version
apt 2.0.6 (amd64)
property installed: Iterator[Package]

Fetch installed packages.

$ apt --quiet list --installed
Listing...
adduser/xenial,now 3.113+nmu3ubuntu4 all [installed]
bc/xenial,now 1.06.95-9build1 amd64 [installed]
bsdmainutils/xenial,now 9.0.6ubuntu3 amd64 [installed,automatic]
ca-certificates/xenial,now 20160104ubuntu1 all [installed]
cron/xenial,now 3.0pl1-128ubuntu2 amd64 [installed]
debconf/xenial,now 1.5.58ubuntu1 all [installed]
debianutils/xenial,now 4.7 amd64 [installed]
diffutils/xenial,now 1:3.3-3 amd64 [installed]
e2fsprogs/xenial,now 1.42.13-1ubuntu1 amd64 [installed]
ethstatus/xenial,now 0.4.3ubuntu2 amd64 [installed]
file/xenial,now 1:5.25-2ubuntu1 amd64 [installed]
findutils/xenial,now 4.6.0+git+20160126-2 amd64 [installed]
libidn2-0/jammy,now 2.3.2-2build1 amd64 [installed,automatic]
libidn2-0/jammy,now 2.3.2-2build1 i386 [installed,automatic]
property outdated: Iterator[Package]

Fetch outdated packages.

$ apt --quiet list --upgradable
Listing...
apt/xenial-updates 1.2.19 amd64 [upgradable from: 1.2.15ubuntu0.2]
nano/xenial-updates 2.5.3-2ubuntu2 amd64 [upgradable from: 2.5.3-2]
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

--simulate turns autoremove into a read-only report of the would-be-removed packages, printed as Remv <name> [<version>] lines. It needs no root: apt only prints a notice that the run is a simulation.

$ apt --quiet autoremove --simulate
NOTE: This is only a simulation!
      apt needs root privileges for real execution.
      Keep also in mind that locking is deactivated,
      so don't depend on the relevance to the real current situation!
Reading package lists...
Building dependency tree...
Reading state information...
The following packages will be REMOVED:
  libx11-dev libxcb1-dev
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
Remv libx11-dev [2:1.8.7-1]
Remv libxcb1-dev [1.15-1]
search(query, extended, exact)[source]

Fetch matching packages.

$ apt --quiet search abc --names-only
Sorting...
Full Text Search...
abcde/xenial 2.7.1-1 all
  A Better CD Encoder

abcmidi/xenial 20160103-1 amd64
  converter from ABC to MIDI format and back

berkeley-abc/xenial 1.01+20150706hgc3698e0+dfsg-2 amd64
  ABC - A System for Sequential Synthesis and Verification

fuse-overlayfs/jammy,now 1.7.1-1 amd64 [installed]
  implementation of overlay+shiftfs in FUSE for rootless containers

grabcd-rip/xenial 0009-1 all
  rip and encode audio CDs - ripper

libakonadi-kabc4/xenial 4:4.14.10-1ubuntu2 amd64
  Akonadi address book access library
$ apt --quiet search ^sed$ --names-only
Sorting...
Full Text Search...
sed/xenial 2.1.9-3 all
  Blah blah blah
$ apt --quiet search abc --full
Sorting...
Full Text Search...
abcde/xenial 2.7.1-1 all
  This package contains the essential basic system utilities.
  .
  Specifically, this package includes:
  basename cat chgrp chmod chown chroot cksum comm cp csplit cut
  dircolors dirname du echo env expand expr factor false fmt
  hostid id install join link ln logname ls md5sum mkdir mkfifo
  nohup od paste pathchk pinky pr printenv printf ptx pwd
  sha1sum seq shred sleep sort split stat stty sum sync tac tail
  tr true tsort tty uname unexpand uniq unlink users vdir wc who

(...)

midi/xenial 20160103-1 amd64
  converter from ABC to MIDI format and back
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo apt --quiet --yes install git
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo apt --quiet --yes upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo apt --quiet --yes install --only-upgrade git
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo apt --quiet --yes remove git
Return type:

str

remove_orphan(package_id)[source]

Remove one package, then drop dependencies it alone pulled in.

--auto-remove clears the packages that were installed as dependencies and are no longer needed after the removal.

$ sudo apt --quiet --yes remove --auto-remove git
Return type:

str

sync()[source]

Sync package metadata.

$ sudo apt --quiet --yes update
Hit:1 http://archive.ubuntu.com xenial InRelease
Get:2 http://archive.ubuntu.com xenial-updates InRelease [102 kB]
Get:3 http://archive.ubuntu.com xenial-security InRelease [102 kB]
Get:4 http://archive.ubuntu.com xenial/main Translation-en [568 kB]
Fetched 6,868 kB in 2s (2,680 kB/s)
Reading package lists...
Building dependency tree...
Reading state information...
Return type:

None

cleanup_orphan()[source]

Remove every package installed as a dependency and no longer required.

$ sudo apt --quiet --yes autoremove
Return type:

None

cleanup_cache()[source]

Clear out the local repository of retrieved package files.

$ sudo apt --quiet --yes clean
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

apt itself has no stable check verb, so the diagnosis goes through the apt-get sibling: check verifies the package cache and dependency integrity, prints the broken state and exits non-zero on problems. Runs unprivileged.

$ apt-get --quiet check
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('apt',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'apt'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.apt.APT_Mint[source]

Bases: APT

Linux Mint’s apt, a wrapper script that shadows Debian’s apt.

Mint ships its own apt command reusing the name but not the behavior of APT, so only version probing and search parsing are overridden here; every other operation is inherited.

Note

Mint’s apt --version prints no apt <version> line, so the version is read from apt version apt: the version of the apt package itself.

Caution

Search rows are <status> <name> - <description> with no version column and no --full mode, so extended matching is unsupported and results carry no version.

Initialize cli_errors list.

name: str = 'Linux Mint apt'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/kdeldycke/meta-package-manager/issues/52'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

cli_names: tuple[str, ...] = ('apt',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'apt-mint'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

version_cli_options: tuple[str, ...] = ('version', 'apt')
$ apt version apt
1.6.11
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports extended matching.

$ /usr/local/bin/apt --quiet search sed
v   librust-slog-2.5+erased-serde-dev  -
p   python3-blessed                    - Practical wrapper
i   sed                                - GNU stream editor
p   sed:i386                           - GNU stream editor
$ /usr/local/bin/apt --quiet search ^sed$
i   sed              - GNU stream editor
p   sed:i386         - GNU stream editor
Return type:

Iterator[Package]

meta_package_manager.managers.asdf module

class meta_package_manager.managers.asdf.ASDF[source]

Bases: PackageManager

asdf manages parallel versions of multiple developer tools (Node.js, Ruby, Python, Erlang, …) through a plugin ecosystem, exposing all of them behind a single CLI.

mpm targets the 0.16.0 Go rewrite and later: it calls the space-separated subcommands (asdf list all, asdf plugin add) that replaced the hyphenated forms (list-all, plugin-add) of the older Bash asdf, which is unsupported.

Note

asdf is plugin-driven: every tool the user can install is gated behind a plugin (asdf plugin add nodejs). mpm install does not auto-add plugins; the user is expected to register them first with asdf plugin add.

Note

Each (plugin, installed_version) pair is reported as a distinct package, so a tool installed at multiple versions yields multiple entries sharing the same ID.

Caution

mpm outdated only reports tools that have a currently-active version (marked with * in asdf list) different from their latest stable release. A tool installed without being activated through a .tool-versions file does not surface as outdated.

Initialize cli_errors list.

name: str = 'asdf'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://asdf-vm.com'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.16.0'

The Go rewrite shipped in 0.16.0 on 2025-01-30 replaced the hyphenated subcommands (asdf list-all, asdf plugin-add, …) with their space-separated equivalents this wrapper depends on (asdf list all, asdf plugin add, …). Older Bash-based releases are not supported.

version_cli_options: tuple[str, ...] = ('version',)

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('v?(?P<version>\\d+\\.\\d+\\.\\d+)',)
$ asdf version
v0.19.0-83adfe6
property installed: Iterator[Package]

Fetch installed packages.

Emits one meta_package_manager.package.Package per (plugin, installed_version) pair, so a tool installed at multiple versions yields multiple entries sharing the same ID.

$ asdf list
nodejs
  18.20.4
 *20.10.0
ruby
 *3.2.0
property outdated: Iterator[Package]

Fetch outdated packages.

Cross-references the currently-active version per plugin (the entry marked with * in asdf list) with the latest stable version (asdf latest --all). Only plugins whose active version differs from the latest are yielded.

$ asdf latest --all
nodejs    20.10.0    missing
ruby      3.3.0      missing
search(query, extended, exact)[source]

Fetch matching packages.

asdf plugin list all enumerates the entire short-name plugin catalogue. The framework’s meta_package_manager.manager.PackageManager.refiltered_search() narrows the listing down to entries that contain the query.

$ asdf plugin list all
1password-cli   https://github.com/NeoHsu/asdf-1password-cli.git
act             https://github.com/grimoh/asdf-act.git
nodejs          https://github.com/asdf-vm/asdf-nodejs.git
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

asdf install <plugin> requires the plugin to have been added beforehand with asdf plugin add <plugin>. This wrapper does not auto-add plugins.

$ asdf install nodejs 20.10.0
Return type:

str

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

asdf has no native upgrade verb: installing the latest alias downloads the newest stable release alongside any older versions already on disk. The user is responsible for switching the active version with asdf set if desired.

$ asdf install nodejs latest
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('asdf',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'asdf'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package.

asdf plugin remove deletes the plugin and every version of the tool installed through it, which matches mpm’s “remove this package” contract more cleanly than iterating asdf uninstall per installed version.

$ asdf plugin remove nodejs
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Refresh plugin metadata.

$ asdf plugin update --all
Return type:

None

meta_package_manager.managers.bin module

meta_package_manager.managers.bin.DRY_RUN_UPDATES_FOUND = 3

Exit code bin update --dry-run uses to report that updates exist.

A dry run finding nothing exits 0, and finding something exits this instead, so neither is a failure. Anything else is.

class meta_package_manager.managers.bin.Bin[source]

Bases: PackageManager

Installer of binaries straight from GitHub releases and similar sources.

Caution

The package identifier is the absolute path of the installed binary, which is what list reports and what remove and update accept. That choice is forced rather than preferred: bin names a package differently depending on the verb. Installing takes a source spec (github.com/junegunn/fzf, a release-tag URL, goinstall://…, docker://…, a vendor host), while everything afterwards is keyed on the installed path. Handing a source spec back to remove does not resolve, and a bare basename resolves through $PATH first, so a managed binary shadowed by another copy on $PATH fails outright. The absolute path is the only identifier every non-installing operation accepts.

Note

That asymmetry is also why install is not implemented: no identifier list reports can be handed to it, so mpm could never install what it had just listed. Installing through bin stays a bin install <spec> the user runs themselves, and mpm reports and maintains the result.

No search: bin has no registry to search, only sources the user names. No sync: there is no index to refresh. bin prune is left alone too, since it drops configuration entries whose file has vanished rather than cleaning up packages.

Caution

A bin that has never been configured prompts for its download directory on every command, the listing included, and cannot be driven until someone answers once interactively. mpm sees that as a failed version probe and treats the manager as unavailable, which is the right outcome: an uninitialised bin has no inventory to report, and reporting zero packages would be a lie.

No escalation: bin installs into a directory it picked from $PATH for being writable, and never needs root.

Documentation: bin.

Initialize cli_errors list.

name: str = 'bin'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/marcosnils/bin'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.27.0'

The release whose listing layout installed() reproduces: it reserves a leading column of the version field for the pin marker. The parser tolerates the older unreserved layout too, but the floor tracks what is verified.

extra_env: ClassVar = {'NO_COLOR': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_regexes: tuple[str, ...] = ('^bin version (?P<version>\\S+)',)

Search the version on the first line.

$ bin --version
bin version 0.29.1
commit: c24db4aced89c855062fe8e2907ae0deb3fb9f53
built at: 2026-08-02T13:37:10Z
built by: goreleaser

Four lines are printed and the version is the third word of the first, bare and without a v. There is no version subcommand.

cli_names: tuple[str, ...] = ('bin',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'bin'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property installed: Iterator[Package]

Fetch installed packages.

$ bin list
/home/user/.local/bin/fzf         v0.74.2  github.com/junegunn/fzf                                    OK
/home/user/.local/bin/rg          14.1.1   https://github.com/BurntSushi/ripgrep/releases/tag/14.1.1  OK
/home/user/.local/bin/terraform  *1.5.7    releases.hashicorp.com/terraform                           OK
property outdated: Iterator[Package]

Fetch outdated packages.

This is the operation that keeps bin a class rather than a definition, on two counts a fixed argument list cannot express.

Important

The report is written to stderr while stdout stays empty, and the run exits 3 when it finds anything to update. Both are deliberate on bin’s side: 0 means everything is current, so a zero exit is the empty answer here and only a code that is neither means the check itself failed. The entries the failing exit records are discarded, since this one is a result rather than an error.

$ bin update --dry-run
• /home/user/.local/bin/fzf v0.40.0 -> v0.74.2 (https://github.com/junegunn/fzf/releases/tag/v0.74.2)
• /home/user/.local/bin/gh v2.40.0 -> v2.97.0 (https://github.com/cli/cli/releases/tag/v2.97.0)
⨯ command failed                                   error=Updates found, exit (dry-run mode).

Note

A pinned binary is reported as pinned and skipped before its version is ever checked, so it never appears here. That matches the listing, which marks it with a *.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

--yes answers the single batch confirmation update asks before applying, and --continue-on-error keeps one failing binary from abandoning the rest of the run.

$ bin update --yes --continue-on-error
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Unlike some whole-system upgraders, naming a binary genuinely restricts the run to it.

$ bin update --yes --continue-on-error /home/user/.local/bin/fzf
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

Warning

remove reports a name it could not resolve on stderr and still exits 0, so a zero exit here means the command ran, not that anything was removed. Confirm a removal by listing again.

$ bin remove /home/user/.local/bin/fzf
Return type:

str

meta_package_manager.managers.composer module

class meta_package_manager.managers.composer.Composer[source]

Bases: PackageManager

Dependency manager for PHP, driven in global mode.

Every operation is prefixed with global so it targets the user-wide Composer project under COMPOSER_HOME ($XDG_CONFIG_HOME/composer on XDG systems, ~/.composer on macOS and other Unixes, %APPDATA%\Composer on Windows) rather than a working tree. installed and outdated parse Composer’s --format=json output, while search reads its plain-text listing; --no-ansi is forced on every call to strip color codes.

Initialize cli_errors list.

name: str = 'PHP Composer'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://getcomposer.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.4.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('global', '--no-ansi')
version_regexes: tuple[str, ...] = ('Composer\\s+version\\s+(?P<version>\\S+)',)
$ composer --version
Composer version 2.1.8 2021-09-15 13:55:14
property installed: Iterator[Package]

Fetch installed packages.

$ composer global show --format=json
{
  "installed": [
    {
      "name": "carbondate/carbon",
      "version": "1.33.0",
      "description": "A simple API extension for DateTime."
    },
    {
      "name": "guzzlehttp/guzzle",
      "version": "6.3.3",
      "description": "Guzzle is a PHP HTTP client library"
    },
    {
      "name": "guzzlehttp/promises",
      "version": "v1.3.1",
      "description": "Guzzle promises library"
    },
    {
      "name": "guzzlehttp/psr7",
      "version": "1.4.2",
      "description": "PSR-7 message implementation"
    }
  ]
}
property outdated: Iterator[Package]

Fetch outdated packages.

$ composer global outdated --format=json
{
    "installed": [
        {
            "name": "illuminate/contracts",
            "version": "v5.7.2",
            "latest": "v5.7.3",
            "latest-status": "semver-safe-update",
            "description": "The Illuminate Contracts package."
        },
        {
            "name": "illuminate/support",
            "version": "v5.7.2",
            "latest": "v5.7.3",
            "latest-status": "semver-safe-update",
            "description": "The Illuminate Support package."
        }
    ]
}
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports exact matching.

$ composer global search symfony
symfony/symfony The Symfony PHP framework
symfony/yaml Symfony Yaml Component
symfony/var-dumper Symfony (...) dumping PHP variables
symfony/translation Symfony Translation Component
symfony/routing Symfony Routing Component
symfony/process Symfony Process Component
symfony/polyfill-php70 Symfony (...) features to lower PHP versions
symfony/polyfill-mbstring Symfony (...) Mbstring extension
symfony/polyfill-ctype Symfony polyfill for ctype functions
symfony/http-kernel Symfony HttpKernel Component
symfony/http-foundation Symfony HttpFoundation Component
symfony/finder Symfony Finder Component
symfony/event-dispatcher Symfony EventDispatcher Component
symfony/debug Symfony Debug Component
symfony/css-selector Symfony CssSelector Component
$ composer global search --only-name python
hiqdev/hidev-python
aanro/pythondocx
laravel-admin-ext/python-editor
pythonphp/pythonphp
blyxxyz/python-server
nim-development/python-domotics
rakshitbharat/pythoninphp
tequilarapido/python-bridge
$ search global --only-name pythonphp/pythonphp
pythonphp/pythonphp
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ composer global --no-ansi require illuminate/contracts
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ composer global --no-ansi update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ composer global --no-ansi update illuminate/contracts
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ composer global --no-ansi remove illuminate/contracts
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

See clear-cache.

$ composer global --no-ansi clear-cache
Return type:

None

cli_names: tuple[str, ...] = ('composer',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

diagnose checks the platform, the connectivity to the repositories and the composer setup, exiting non-zero on failures.

$ composer global --no-ansi diagnose
Return type:

tuple[str, ...]

id: str = 'composer'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.conda module

class meta_package_manager.managers.conda.Conda[source]

Bases: PackageManager

Conda cross-language package and environment manager.

Reads go through conda’s --json mode: installed packages come from conda list --json and search from conda search "*query*" --json. conda has no dedicated outdated command, so the upgrade the solver would perform is simulated with conda update --all --dry-run --json and its UNLINK (current) and LINK (candidate) sets are diffed by name: a name in both is an in-place upgrade, while a LINK-only entry is a freshly pulled dependency and is not reported.

Note

Every operation targets conda’s currently active environment, which is base when none is activated. mpm neither activates nor switches environments: it inspects and mutates whatever environment conda resolves from the inherited CONDA_PREFIX / CONDA_DEFAULT_ENV, exactly as a bare conda call in the same shell would. Per-environment targeting is not supported yet.

Note

The >=4.6.0 floor is the release where update --dry-run --json settled on an actions mapping whose LINK / UNLINK values are package dicts, the shape the outdated diff parses. Much older conda wrapped actions in a list and emitted bare channel::name-version-build strings instead.

Initialize cli_errors list.

name: str = 'Conda'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://conda.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=4.6.0'

4.6.0 is a conservative floor. By this release conda update --dry-run --json``reports``actions``as a single mapping whose``LINK / UNLINK values are lists of package dicts: the exact shape outdated() parses. Much older conda wrapped actions in a list and emitted bare channel::name-version-build strings instead of dicts, which the parser below does not handle. The --json output of list and search predates this floor by years.

See 4.6.0 release.

version_regexes: tuple[str, ...] = ('conda\\s+(?P<version>\\S+)',)
$ conda --version
conda 24.5.0
property installed: Iterator[Package]

Fetch installed packages.

$ conda list --json
[
  {
    "base_url": "https://repo.anaconda.com/pkgs/main",
    "build_number": 0,
    "build_string": "py312hca03da5_0",
    "channel": "pkgs/main",
    "dist_name": "pip-24.0-py312hca03da5_0",
    "name": "pip",
    "platform": "osx-arm64",
    "version": "24.0"
  },
  {
    "base_url": "https://repo.anaconda.com/pkgs/main",
    "build_number": 0,
    "build_string": "py312_0",
    "channel": "pkgs/main",
    "dist_name": "pytz-2024.1-py312_0",
    "name": "pytz",
    "platform": "osx-arm64",
    "version": "2024.1"
  }
]
property outdated: Iterator[Package]

Fetch outdated packages.

There is no dedicated conda outdated command, so the upgrade the solver would perform is simulated with --dry-run and the UNLINK (current) / LINK (candidate) sets are diffed by name. A package appearing in both is an in-place upgrade; one appearing in only LINK is a freshly-pulled dependency and one in only UNLINK is a removal, so neither is reported.

$ conda update --all --dry-run --json
{
  "actions": {
    "FETCH": [],
    "LINK": [
      {
        "base_url": "https://repo.anaconda.com/pkgs/main",
        "build_number": 0,
        "build_string": "py312_0",
        "channel": "pkgs/main",
        "dist_name": "pytz-2024.2-py312_0",
        "name": "pytz",
        "platform": "osx-arm64",
        "version": "2024.2"
      }
    ],
    "UNLINK": [
      {
        "base_url": "https://repo.anaconda.com/pkgs/main",
        "build_number": 0,
        "build_string": "py312_0",
        "channel": "pkgs/main",
        "dist_name": "pytz-2024.1-py312_0",
        "name": "pytz",
        "platform": "osx-arm64",
        "version": "2024.1"
      }
    ],
    "PREFIX": "/opt/conda"
  },
  "dry_run": true,
  "prefix": "/opt/conda",
  "success": true
}

When the environment is already current, conda omits the actions key entirely:

$ conda update --all --dry-run --json
{
  "message": "All requested packages already installed.",
  "success": true
}
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. The query is wrapped in * wildcards to get the broadest substring match conda offers, and meta_package_manager.manager.PackageManager.refiltered_search() narrows the results down. conda exposes no package description in its search output, so extended matching has nothing to match against.

conda returns every available build of every matching package, grouped by name and sorted by ascending version, so the last record of each group carries the latest version.

$ conda search "*pytz*" --json
{
  "pytz": [
    {
      "arch": null,
      "build": "py27_0",
      "build_number": 0,
      "channel": "https://repo.anaconda.com/pkgs/main/osx-arm64",
      "name": "pytz",
      "version": "2013b"
    },
    {
      "arch": null,
      "build": "py312_0",
      "build_number": 0,
      "channel": "https://repo.anaconda.com/pkgs/main/osx-arm64",
      "name": "pytz",
      "version": "2024.1"
    }
  ]
}
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package, optionally pinned to a version.

conda accepts a MatchSpec so the version is appended with =.

$ conda install --yes pytz

## Package Plan ##

  environment location: /opt/conda

  added / updated specs:
    - pytz

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
$ conda install --yes pytz=2024.1
Return type:

str

upgrade_all_cli()[source]

Generate the CLI to upgrade all packages.

$ conda update --all --yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generate the CLI to upgrade a single package, optionally to a version.

$ conda update --yes pytz
$ conda update --yes pytz=2024.2
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('conda',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'conda'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package.

$ conda remove --yes pytz

## Package Plan ##

  environment location: /opt/conda

  removed specs:
    - pytz

Preparing transaction: done
Verifying transaction: done
Executing transaction: done
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Removes tarballs, unused packages and index caches.

$ conda clean --all --yes
Will remove 42 (123.4 MB) tarball(s).
Will remove 1 index cache(s).
Will remove 7 (45.6 MB) package(s).
Return type:

None

meta_package_manager.managers.deb_get module

class meta_package_manager.managers.deb_get.Deb_Get[source]

Bases: PackageManager

deb-get installs third-party software on Debian and Ubuntu via .deb packages sourced from GitHub releases, direct URLs, and PPAs.

Note

deb-get wraps apt under the hood for actual package installation and removal, so all operations that modify the system require sudo.

Caution

deb-get list --installed prints bare package names with no versions, so the installed inventory carries no version. search is likewise version-less and offers no exact or extended mode, so mpm refilters its results.

Note

There is no read-only outdated: detection runs deb-get update, which also refreshes the package index, so the probe escalates through sudo like a sync.

Initialize cli_errors list.

name: str = 'deb-get'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/wimpysworld/deb-get'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

version_cli_options: tuple[str, ...] = ('version',)
$ deb-get version
0.4.5
version_regexes: tuple[str, ...] = ('(?P<version>\\d+\\.\\d+\\.\\d+)',)

Regular expressions used to extract the version number.

This property must be a tuple of strings, each of which is a valid regular expression that must contain a group named <version>.

The first of these regexes producing a match and returning non-empty <version> group will be used as the version string of the package manager.

That version string will then be sanitized and normalized by meta_package_manager.execution.CLIExecutor.version.

By default match the first part that is space-separated.

Caution

These regexes are compiled with re.MULTILINE only. They are not compiled with re.VERBOSE, so literal whitespace in the pattern is significant and matches whitespace in the CLI output.

property installed: Iterator[Package]

Fetch installed packages.

$ deb-get list --installed
activitywatch
anydesk
bitwarden
deb-get
freeplane
google-chrome-stable
ipscan
protonvpn
zoom

Note

deb-get list --installed only outputs bare package names without version information.

property outdated: Iterator[Package]

Fetch outdated packages.

$ sudo deb-get update
Checking for updates to deb-get installed packages
  [+] ipscan (3.9.2) has an update pending. 3.9.3 is available.

Note

Outdated detection piggybacks on deb-get update which also refreshes the package index.

search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching, and does not provide version information. Returns the best subset of results and lets meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ deb-get search zoom
zoom
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo deb-get install ipscan
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ sudo deb-get upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package by reinstalling it.

$ sudo deb-get install ipscan
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo deb-get remove ipscan
Return type:

str

sync()[source]

Sync package metadata.

$ sudo deb-get update
Return type:

None

cleanup_cache()[source]

Remove cached downloads.

$ sudo deb-get clean
Return type:

None

cli_names: tuple[str, ...] = ('deb-get',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'deb-get'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.dnf module

class meta_package_manager.managers.dnf.DNF[source]

Bases: PackageManager

Fedora’s RPM package manager.

mpm reads the inventory through repoquery rather than the human-facing listing: --userinstalled for packages installed on request (dependencies pulled in automatically are skipped) and --upgrades for pending updates, both with a --queryformat that joins the fields on a private ___MPM___ delimiter so summaries containing spaces stay splittable. Every call is forced --color=never and --quiet for parseable output.

Note

remove runs autoremove, so removing a package also drops the dependencies it leaves orphaned. search matches names only, with no exact or extended mode.

The DNF5 and YUM subclasses reuse everything here, differing only in the binary and forced arguments.

Documentation:

Initialize cli_errors list.

maintenance_note: str | None = "DNF 4 is superseded by [dnf5](https://github.com/rpm-software-management/dnf5) (Fedora's default since Fedora 41) but stays maintained for the RHEL 8/9 family; mpm wraps `dnf5` as a separate manager."

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

name: str = 'Fedora DNF'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/rpm-software-management/dnf'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=4.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cli_names: tuple[str, ...] = ('dnf', 'dnf4')
$ dnf --version
4.9.0
pre_args: tuple[str, ...] = ('--color=never', '--quiet')
DELIMITER = '___MPM___'
property installed: Iterator[Package]

Fetch installed packages.

$ dnf repoquery --userinstalled --qf FORMAT
acl___MPM___2.2.53-1.el8___MPM___Access control list utilities___MPM___x86_64
audit___MPM___3.0.7-4.el9___MPM___User space auditing tools___MPM___x86_64
audit-libs___MPM___3.0.7-4.el9___MPM___Dynamic auditing library___MPM___x86_64
property outdated: Iterator[Package]

Fetch outdated packages.

$ dnf repoquery --upgrades --qf FORMAT
acl___MPM___2.2.53-1.el8___MPM___2.6.53-1.el8___MPM___Access control list utilities___MPM___x86_64
audit___MPM___2.2.53-1.el8___MPM___2.5.53-1.el8___MPM___User space auditing tools___MPM___x86_64
audit-libs___MPM___2.2.53-1.el8___MPM___2.6.53-1.el8___MPM___Dynamic auditing library___MPM___x86_64
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

$ dnf --color=never --quiet repoquery --unneeded
libfoo-1.0.2-3.el9.x86_64
python3-extra-0:3.9.18-3.el9.noarch
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ dnf --color=never search usd
Last metadata expiration check: 0:06:37 ago on Sun 03 Apr 2022.
=================== Name Exactly Matched: usd =====================
usd.aarch64 : 3D VFX pipeline interchange file format
=================== Name & Summary Matched: usd ===================
python3-usd.aarch64 : Development files for USD
usd-devel.aarch64 : Development files for USD
======================= Name Matched: usd =========================
lvm2-dbusd.noarch : LVM2 D-Bus daemon
usd-libs.aarch64 : Universal Scene Description library
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo dnf --color=never --quiet --assumeyes install pip
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo dnf --color=never --quiet --assumeyes upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo dnf --color=never --quiet --assumeyes upgrade pip
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package and one only.

$ sudo dnf --color=never --quiet --assumeyes remove pip
Return type:

str

remove_orphan(package_id)[source]

Remove one package, dropping dependencies it alone pulled in.

autoremove targets the package plus the dependencies that were installed to satisfy it and are no longer required by anything else.

$ sudo dnf --color=never --quiet --assumeyes autoremove pip
Return type:

str

sync()[source]

Sync package metadata.

$ dnf --color=never --quiet check-update
Return type:

None

cleanup_orphan()[source]

Remove every package installed as a dependency and no longer required.

$ sudo dnf --color=never --quiet --assumeyes autoremove
Return type:

None

cleanup_cache()[source]

Clear the cached packages and repository metadata.

$ sudo dnf --color=never --quiet clean all
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

check examines the rpm database for problems (duplicates, obsoleted packages, unsatisfied dependencies) and exits non-zero when any is found.

$ dnf --color=never --quiet check
Return type:

tuple[str, ...]

id: str = 'dnf'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.dnf.DNF5[source]

Bases: DNF

The dnf5 rewrite of DNF, Fedora’s reference package manager since Fedora 41.

Inherits every operation and parser from DNF. Its forced arguments drop --color=never (dnf5 rejects that option), keeping only --quiet.

Initialize cli_errors list.

maintenance_note: str | None = None

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

name: str = 'Fedora DNF5'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/rpm-software-management/dnf5'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

requirement: str | None = '>=5.0.0'

dnf5 is the new reference package manager as of Fedora 41.

cli_names: tuple[str, ...] = ('dnf5',)
$ dnf --version
4.9.0
pre_args: tuple[str, ...] = ('--quiet',)

Reset global options inherited from the DNF above.

dnf5 does not support --color=never parameter.

id: str = 'dnf5'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.dnf.YUM[source]

Bases: DNF

YUM, the package manager DNF superseded.

On current Fedora and RHEL the yum binary is a wrapper around dnf. mpm drives it exactly as DNF, only the binary name differs.

Initialize cli_errors list.

maintenance_note: str | None = 'The standalone [yum project is archived](https://github.com/rpm-software-management/yum); on modern RHEL and Fedora the `yum` command is a maintained compatibility alias for [dnf](https://github.com/rpm-software-management/dnf).'

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

id: str = 'yum'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Fedora YUM'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

homepage_url: str | None = 'http://yum.baseurl.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

cli_names: tuple[str, ...] = ('yum',)
$ dnf --version
4.9.0

meta_package_manager.managers.dotnet module

class meta_package_manager.managers.dotnet.DotNet[source]

Bases: PackageManager

.NET global tools, the CLI programs the .NET SDK installs from NuGet.

Every operation goes through the dotnet tool subcommand group, forced by DotNet.pre_args, and targets the user-wide scope with --global. Global tools land under ~/.dotnet/tools and are never shared between users, so no operation escalates: elevation is only ever needed for the separate --tool-path scenario, which this wrapper does not drive.

Documentation: .NET global tools.

Note

The listing and the search results are column tables whose headers are localized resource strings, translated into thirteen languages. Rather than match English literals, DotNet.extra_env pins the CLI language and both parsers key on the shape of the row: a package ID, two or more spaces, then a version starting with a digit. That skips the header, the dashed rule and any diagnostic prose the SDK prints above the table, such as the broken-tool warning of dotnet/sdk#4111.

Note

dotnet tool list also speaks JSON, through an undocumented --format json that landed in the 9.0.100 SDK (dotnet/sdk#37394). mpm deliberately parses the table instead: the three columns of the global listing are all whitespace-free, so nothing is gained, while keying on JSON would raise the floor past 8.0.4xx, the oldest SDK band still supported.

Caution

No outdated operation is declared: the SDK ships no way to compare installed tools against NuGet without mutating them. A spec for dotnet tool list --outdated was written by an SDK maintainer in dotnet/sdk#22853, which was then closed as not planned. upgrade --all is unaffected and maps to the native dotnet tool update --all.

Note

No cleanup either. The obvious candidate, dotnet nuget locals all –clear, empties the machine-wide NuGet package folder every .NET project restores against, so a tool-scoped cleanup would invalidate unrelated builds. Nothing clears only what the global tools pulled.

Initialize cli_errors list.

name: str = 'dotnet tool'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://learn.microsoft.com/dotnet/core/tools/global-tools'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=8.0.400'

--all on dotnet tool update first shipped in the 8.0.400 SDK, the opening release of the 8.0.4xx feature band (dotnet/sdk#38996, merged onto release/8.0.4xx). It was never backported to 8.0.3xx, so that is the binding floor: every other operation this wrapper drives predates it by years, dotnet tool search being the youngest at 5.0.100.

extra_env: ClassVar = {'DOTNET_CLI_TELEMETRY_OPTOUT': '1', 'DOTNET_CLI_UI_LANGUAGE': 'en-us', 'DOTNET_NOLOGO': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

pre_args: tuple[str, ...] = ('tool',)

Every operation is a dotnet tool subcommand, so the group is forced onto each call. The version probe is exempt: it runs with auto_pre_args=False, which is what leaves it as a bare dotnet --version.

version_regexes: tuple[str, ...] = ('^(?P<version>\\d+\\.\\d+\\.\\d+\\S*)',)

dotnet --version prints the SDK version alone, on a single unlabelled line.

It is deliberately preferred over dotnet --info as the probe: on a machine carrying the .NET runtime but no SDK, --version fails while --info still exits 0 and reports its inventory. Since dotnet tool needs the SDK, the failure is the correct availability signal.

$ dotnet --version
9.0.306
property installed: Iterator[Package]

Fetch installed packages.

$ dotnet tool list --global
Package Id      Version      Commands
--------------------------------------
dotnet-ef       2.1.11       dotnet-ef
search(query, extended, exact)[source]

Fetch matching packages.

dotnet tool search queries NuGet’s search endpoint with packageType=dotnettool, so only .NET tools come back. NuGet offers no flag to restrict or widen that match, so both refinements are left to meta_package_manager.manager.PackageManager.refiltered_search().

Only the first two columns are captured: Authors and Downloads have no package field to land in, and Verified is a marker rather than a value.

Caution

NuGet matches the query against descriptions and tags as well as package IDs, but the default table prints no description column, so mpm cannot see why a row matched. --extended is therefore declared unsupported rather than claimed: refiltering keeps only the ID and name matches, and a package that matched on its description alone is dropped. Widening this means parsing dotnet tool search --detail, whose per-package blocks do carry a Description: line, at the cost of keying the parser on localized field labels instead of on the row shape.

$ dotnet tool search format
Package ID                              Latest Version      Authors                                                                     Downloads      Verified
---------------------------------------------------------------------------------------------------------------------------------------------------------------
dotnet-format                           4.1.131201          Microsoft                                                                   496746
bsoa.generator                          1.0.0               Microsoft                                                                   533
Return type:

Iterator[Package]

cli_names: tuple[str, ...] = ('dotnet',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'dotnet'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

install(package_id, version=None)[source]

Install one package.

$ dotnet tool install --global dotnetsay
$ dotnet tool install --global dotnetsay --version 2.1.7
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ dotnet tool update --global --all
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

dotnet tool update is implemented upstream as an uninstall followed by a reinstall, and refuses to move a tool backwards: a version older than the installed one needs a remove first.

$ dotnet tool update --global dotnetsay
$ dotnet tool update --global dotnetsay --version 2.1.7
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ dotnet tool uninstall --global dotnetsay
Return type:

str

meta_package_manager.managers.emerge module

class meta_package_manager.managers.emerge.Emerge[source]

Bases: PackageManager

Portage’s emerge, Gentoo’s source-based package manager.

Documentation: emerge(1) man page.

Command equivalences with other managers are listed in Pacman/Rosetta.

The outdated listing and the whole-system upgrade operate against the @world set. The progress spinner and ANSI coloring are disabled on every call, leaving output the regexes can parse.

Note

Two operations lean on companion Portage tools rather than emerge itself: installed reads the package list through qlist and cleanup trims distfiles through eclean. Neither is resolved through cli_path the way the reference emerge binary is; both are expected on the PATH.

Warning

cleanup forces a full @world upgrade before running --depclean: Portage refuses to remove packages until every dependency is resolved, so depcleaning a partially-upgraded system could drop still-needed packages.

Initialize cli_errors list.

name: str = 'Gentoo emerge'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://wiki.gentoo.org/wiki/Portage#emerge'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=3.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('--quiet', '--color', 'n', '--nospinner')
version_regexes: tuple[str, ...] = ('Portage\\s+(?P<version>\\S+)',)
$ emerge --version
Portage 3.0.30 (python 3.9.9-final-0, gcc-11.2.1, 5.15.32-gentoo-r1 x86_64)
property installed: Iterator[Package]

Fetch installed packages.

Warning

This suppose the qlist binary is available and present on the system. We do not search for it or try to resolves its canonical path with cli_path, as we do for the reference emerge binary.

$ qlist --installed --verbose --nocolor
acct-group/audio-0-r1
acct-group/cron-0
app-admin/hddtemp-0.3_beta15-r29
app-admin/perl-cleaner-2.30
app-admin/system-config-printer-1.5.16-r1
app-arch/p7zip-16.02-r8
property outdated: Iterator[Package]

Fetch outdated packages.

$ emerge --update --deep --pretend --columns --color n --nospinner @world
[blocks  B     ] app-text/dos2unix
[ebuild   N    ] app-games/qstat   [25c]
[ebuild    R   ] sys-apps/sed      [2.4.7-r6]
[ebuild       U] net-fs/samba      [2.2.8_pre1]      [2.2.7a]
[ebuild       U] sys-devel/distcc  [2.16]            [2.13-r1] USE=ip6* -gtk
[ebuild r     U] dev-libs/icu      [50.1.1:0/50.1.1] [50.1-r2:0/50.1]
[ebuild r  R   ] dev-libs/libxml2  [2.9.0-r1:2]       USE=icu
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

--pretend turns --depclean into a read-only report of the packages it would unmerge, summarized on its All selected packages: line as =<category/name>-<version> atoms. Runs without root, and without the pre-depclean world upgrade cleanup_orphan() performs before a real sweep.

$ emerge --quiet --color n --nospinner --depclean --pretend
Calculating dependencies... done!
>>> These are the packages that would be unmerged:

 dev-libs/libpcre
    selected: 8.45-r1
   protected: none
     omitted: none

 app-misc/tmux
    selected: 3.3a
   protected: none
     omitted: none

All selected packages: =dev-libs/libpcre-8.45-r1 =app-misc/tmux-3.3a

>>> 'Selected' packages are slated for removal.
>>> 'Protected' and 'omitted' packages will not be removed.
search(query, extended, exact)[source]

Fetch matching packages.

$ emerge --search --color n --nospinner blah

[ Results for search key : blah ]
Searching...

*  sys-process/htop
    Latest version available: 1.0.2-r1
    Latest version installed: [ Not Installed ]
    Size of files: 380 KiB
    Homepage:      http://htop.sourceforge.net
    Description:   interactive process viewer
    License:       BSD GPL-2

*  x11-drivers/nvidia-drivers
    Latest version available: 455.45.01-r1
    Latest version installed: [ Not Installed ]
    Size of files: 180.214 KiB
    Homepage:      https://www.nvidia.com/Download/Find.aspx
    Description:   NVIDIA Accelerated Graphics Driver
    License:       GPL-2 NVIDIA-r2

[ Applications found : 2 ]
$ emerge --search --color n --nospinner %^sed$
$ emerge --searchdesc --color n --nospinner sed
$ emerge --searchdesc --color n --nospinner %^sed$
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo emerge --quiet --color n --nospinner dev-vcs/git
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo emerge --quiet --color n --nospinner --update --newuse --deep @world
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo emerge --quiet --color n --nospinner --update dev-vcs/git
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo emerge --quiet --color n --nospinner --unmerge dev-vcs/git
Return type:

str

sync()[source]

Sync package metadata.

$ sudo emerge --quiet --color n --nospinner --sync
Return type:

None

cleanup_orphan()[source]

Remove every package not required by the world set anymore.

An update is forced before depcleaning, as pointed to by the emerge documentation:

> As a safety measure, depclean will not remove any packages unless all > required dependencies have been resolved. As a consequence, it is often > necessary to run emerge --update --newuse --deep @world prior to depclean.

$ sudo emerge --quiet --color n --nospinner --update --newuse --deep @world
$ sudo emerge --quiet --color n --nospinner --depclean
Return type:

None

cli_names: tuple[str, ...] = ('emerge',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'emerge'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Trim the source distfiles through eclean.

Warning

This suppose the eclean binary is available and present on the system. We do not search for it or try to resolves its canonical path with cli_path, as we do for the reference emerge binary.

$ sudo eclean distfiles
Return type:

None

meta_package_manager.managers.eopkg module

class meta_package_manager.managers.eopkg.EOPKG[source]

Bases: PackageManager

Solus’ eopkg package manager, a PiSi fork.

installed and outdated parse eopkg’s fixed-width, |-delimited status table; the column regex requires that pipe structure, so the header and === separator rows fall through. --no-color is forced to keep the output free of ANSI escapes.

Mutating operations pass --yes-all to auto-confirm eopkg’s prompts so they run unattended.

Initialize cli_errors list.

name: str = 'Solus eopkg'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/getsolus/eopkg/'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=3.2.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('--no-color',)
version_regexes: tuple[str, ...] = ('eopkg\\s+(?P<version>\\S+)',)
$ eopkg --version
eopkg 3.2.0
property installed: Iterator[Package]

Fetch installed packages.

$ eopkg --no-color list-installed --install-info
Package Name          |St|        Version|  Rel.|  Distro|       Date
=====================================================================
aalib                 | i|        1.4.0_5|     8|   Solus|14 Oct 2024
abseil-cpp            | i|     20240116.2|    10|   Solus|14 Oct 2024
accountsservice       | i|        23.13.9|    36|   Solus|14 Oct 2024
acl                   | i|          2.3.2|    21|   Solus|14 Oct 2024
adwaita-icon-theme    | i|           46.2|    28|   Solus|14 Oct 2024
adwaita-icon-theme-legacy  | i|           46.2|     2|   Solus|14 Oct 2024
alsa-firmware         | i|          1.2.4|     7|   Solus|14 Oct 2024
alsa-lib              | i|         1.2.12|    38|   Solus|14 Oct 2024
alsa-plugins          | i|         1.2.12|    26|   Solus|14 Oct 2024
alsa-utils            | i|         1.2.12|    28|   Solus|14 Oct 2024
aom                   | i|         3.10.0|    24|   Solus|14 Oct 2024
appstream             | i|          1.0.1|     9|   Solus|14 Oct 2024
appstream-data        | i|             49|    51|   Solus|14 Oct 2024
appstream-glib        | i|          0.8.2|    13|   Solus|14 Oct 2024
argon2                | i|       20190702|     6|   Solus|14 Oct 2024
at-spi2               | i|         2.52.0|    44|   Solus|14 Oct 2024
atkmm                 | i|         2.28.4|    19|   Solus|14 Oct 2024
attr                  | i|          2.5.2|    25|   Solus|14 Oct 2024
audit                 | i|          4.0.2|    19|   Solus|14 Oct 2024
avahi                 | i|            0.8|    27|   Solus|14 Oct 2024
baobab                | i|           46.0|    27|   Solus|14 Oct 2024
property outdated: Iterator[Package]

Fetch outdated packages.

$ eopkg --no-color list-upgrades --install-info
Package Name          |St|        Version|  Rel.|  Distro|       Date
=====================================================================
adwaita-icon-theme   | i|           46.2|    28|   Solus|14 Oct 2024
appstream-data       | i|             49|    51|   Solus|14 Oct 2024
at-spi2              | i|         2.52.0|    44|   Solus|14 Oct 2024
baobab               | i|           46.0|    27|   Solus|14 Oct 2024
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports exact matching.

Naked search without parameters is the same as extended search with all filtering parameters (i.e. --name --summary --description):

$ eopkg --no-color search firefox
gjs-dbginfo                 - Debug symbols for gjs
bleachbit                   - BleachBit frees disk space and maintains privacy
firefox                     - Firefox web browser
eid-mw-firefox              - Belgian eID add-on for Mozilla Firefox
gjs                         - GNOME JavaScript
font-fira-ttf               - Mozilla's new typeface, used in Firefox OS
geckodriver                 - WebDriver for Firefox
firefox-dbginfo             - Debug symbols for firefox
nvidia-vaapi-driver-dbginfo - Debug symbols for nvidia-vaapi-driver
font-clear-sans-ttf         - Clear Sans Fonts - TrueType
gjs-devel                   - Development files for gjs
geckodriver-dbginfo         - Debug symbols for geckodriver

$ eopkg --no-color search firefox --name --summary --description
gjs-dbginfo                 - Debug symbols for gjs
bleachbit                   - BleachBit frees disk space and maintains privacy
firefox                     - Firefox web browser
eid-mw-firefox              - Belgian eID add-on for Mozilla Firefox
gjs                         - GNOME JavaScript
font-fira-ttf               - Mozilla's new typeface, used in Firefox OS
geckodriver                 - WebDriver for Firefox
firefox-dbginfo             - Debug symbols for firefox
nvidia-vaapi-driver-dbginfo - Debug symbols for nvidia-vaapi-driver
font-clear-sans-ttf         - Clear Sans Fonts - TrueType
gjs-devel                   - Development files for gjs
geckodriver-dbginfo         - Debug symbols for geckodriver

For default search on package name only, we rescript filtering to --name only:

$ eopkg --no-color search firefox --name
firefox         - Firefox web browser
eid-mw-firefox  - Belgian eID add-on for Mozilla Firefox
firefox-dbginfo - Debug symbols for firefox
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo eopkg --no-color install --yes-all 0ad
Warning: Updates available, checking reverse dependencies of runtime dependencies for safety.
Following packages will be installed:
0ad          0ad-data         assimp           at-spi2             baobab             breeze-icons      budgie-control-center  budgie-desktop      dav1d                  enet                   evolution-data-server       ffmpeg
file-roller  firefox          fmt              fontconfig          gcr-4              gloox             gnome-calculator       gnome-calendar      gnome-online-accounts  gnome-settings-daemon  gnome-system-monitor        gnome-terminal
gvfs         harfbuzz         ibus             kf6-karchive        kf6-kauth          kf6-kbookmarks    kf6-kcodecs            kf6-kcolorscheme    kf6-kcompletion        kf6-kconfig            kf6-kconfigwidgets          kf6-kcoreaddons
kf6-kcrash   kf6-kdbusaddons  kf6-kded         kf6-kdoctools       kf6-kglobalaccel   kf6-kguiaddons    kf6-ki18n              kf6-kiconthemes     kf6-kio                kf6-kitemviews         kf6-kjobwidgets             kf6-knotifications
kf6-kparts   kf6-kservice     kf6-kwallet      kf6-kwidgetsaddons  kf6-kwindowsystem  kf6-kxmlgui       kf6-solid              kpmcore             ldb                    libadwaita             libarchive                  libass
libcheese    libgtk-4         libgtkmm-4       libgtksourceview5   libheif            libpng            libportal              libportal-gtk4      libreoffice-common     librsvg                libsodium                   libtiff
libtool      libvte           libwebkit-gtk41  libwebkit-gtk6      lzo                mesalib           miniupnpc              nautilus-extension  nemo                   network-manager        networkmanager-openconnect  openconnect
pipewire     pipewire-lib     pixman           poppler             poppler-utils      postgresql-libpq  python-pysmbc          qt6-base            qt6-declarative        qt6-multimedia         qt6-quick3d                 qt6-quicktimeline
qt6-wayland  rav1e            rhythmbox        samba               sdl2               svt-av1           thunderbird            wayland             xapp                   xmlsec1                xorg-server                 xorg-xwayland
xreader      xviewer          zenity
Total size of package(s): 1.94 GB
Downloading 1 / 111
Package ldb found in repository Solus
ldb-2.8.2-31-1-x86_64.eopkg    (137.0 KB)100%      0.00 --/- [--:--:--] [complete]
(...)
Package 0ad-data found in repository Solus
0ad-data-0.0.26a-10-1-x86_64.eopkg (1.4 GB) 39%
(...)
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo eopkg --no-color upgrade --yes-all
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo eopkg --no-color upgrade --yes-all xz
Updating repositories
Updating repository: Solus
eopkg-index.xml.xz.sha1sum     (40.0  B)100%      0.00 --/- [--:--:--] [complete]
Solus repository information is up-to-date.
Warning: Safety switch forces the installation of following packages:
os-release
Warning: Safety switch forces the upgrade of following packages:
bash    bash-completion  brotli   eopkg    gawk            glib2    glibc         gobject-introspection  hwdata  json-c   libcap2  libdw
libelf  libjson-glib     libnspr  libnss   libpipeline     libssh2  libunistring  lvm2                   lzip    ncurses  nghttp2  nghttp3
pisi    readline         sqlite3  systemd  wireless-regdb  xz
Total size of package(s): 55.40 MB
Warning: There are extra packages due to dependencies.
Downloading 1 / 32
Package ncurses found in repository Solus
ncurses-6.5.20241006-29-1-x86_64.eopkg (767.0 KB)100%      0.00 --/- [--:--:--] [complete]
(...)
[✓] Syncing filesystems                                                success
[✓] Updating dynamic library cache                                     success
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[✓] Updating hwdb                                                      success
[✓] Updating system users                                              success
[✓] Updating systemd tmpfiles                                          success
[✓] Reloading systemd configuration                                    success
[ ] Re-starting vendor-enabled .socket units                           skipped
[ ] Re-executing systemd                                               skipped
[✓] Compiling glib-schemas                                             success
[✓] Creating GIO modules cache                                         success
[✓] Updating manpages database                                         success
[✓] Reloading udev rules                                               success
[✓] Applying udev rules                                                success
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo eopkg --no-color remove --yes-all firefox
The following list of packages will be removed
in the respective order to satisfy dependencies:
firefox
Removing package firefox
Rebuilding the FilesDB...
Adding packages to FilesDB /var/lib/eopkg/info/files.db:
................
847 packages added in total.
Done rebuilding FilesDB (version: 3)
Removed firefox
[✓] Syncing filesystems                                                success
[✓] Updating dynamic library cache                                     success
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Updating clr-boot-manager                                          skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Registering QoL migration on next boot                             skipped
[ ] Re-starting vendor-enabled .socket units                           skipped
[ ] Re-executing systemd                                               skipped
[✓] Updating icon theme cache: hicolor                                 success
[✓] Updating desktop database                                          success
[✓] Updating manpages database                                         success
Return type:

str

sync()[source]

Sync package metadata.

$ sudo eopkg --no-color update-repo
Updating repository: Solus
eopkg-index.xml.xz.sha1sum  (40.0  B)100%   0.00 --/- [--:--:--] [complete]
eopkg-index.xml.xz           (3.1 MB)100%  87.40 KB/s [00:00:34] [complete]
Package database updated.
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore: - orphaned packages, - outdated package locks - package cache and package manager cache

$ sudo eopkg --no-color remove-orphans --yes-all
$ sudo eopkg --no-color clean
$ sudo eopkg --no-color delete-cache
Return type:

None

cli_names: tuple[str, ...] = ('eopkg',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'eopkg'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.fisher module

class meta_package_manager.managers.fisher.Fisher[source]

Bases: PackageManager

Fisher is a plugin manager for the Fish shell.

Fisher clones each plugin from GitHub or any other forge into $fisher_path, and records the set in the user’s fish_plugins file. Plugins are identified by the lower-cased owner/repo slug Fisher both reports and accepts, which is the id mpm keys them on. A plugin may carry an @ref suffix pinning it to a Git tag or branch, and that suffix is what mpm surfaces as the installed version.

Caution

fisher is a Fish function, not a standalone binary: it ships as a functions/fisher.fish file that Fish autoloads, so it cannot serve as the manager’s CLI. Every invocation is therefore wrapped in fish -c. Fish is the binary mpm executes, and Fisher’s own presence is established by the version probe: a host with Fish but no Fisher autoloads nothing, reports no version, and leaves the manager unavailable.

Note

No outdated: Fisher exposes no dry run and no upstream comparison. It tracks a branch rather than a release, so “behind” is not a question it answers. upgrade --all still works, and mpm auto-skips the operation.

Note

No search: Fisher resolves plugins straight from forge URLs and indexes no registry to search.

Documentation: fisher.

Initialize cli_errors list.

name: str = 'Fish fisher'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/jorgebucaran/fisher'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=4.0.0'

The 4.x rewrite is where this CLI settled.

4.0.0 is the release that introduced the $_fisher_plugins inventory list prints, the fish_plugins file install and remove maintain, and the plugin-scoped update this class builds. Fisher 3.x had a different command set entirely, keyed on a fishfile.

cli_names: tuple[str, ...] = ('fish',)

Fish is the binary mpm actually executes.

Fisher is a shell function that Fish autoloads from its functions path, and is never executed as a program, so it cannot be the manager’s CLI: mpm requires an executable. Keying the manager on Fish instead makes the version probe the presence check.

extra_env: ClassVar = {'NO_COLOR': '1'}

Fisher prints its progress through Fish’s own coloring, which NO_COLOR disables so the listing parses as clean text.

version_regexes: tuple[str, ...] = ('fisher, version (?P<version>\\S+)',)
$ fish -c 'functions --query fisher; or exit 0; fisher --version'
fisher, version 4.4.8
build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Fish shell Fisher needs.

The version probe is guarded by functions --query, which exits successfully when Fisher is not on the functions path. Fish is a general-purpose shell, so an unguarded probe would turn every host that merely has Fish into a manager reporting errors. A Fisher that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the fish -c wrapper and Fisher never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

Fisher prints one plugin per line, exactly as recorded: the lower-cased owner/repo slug, optionally suffixed with the @ref it was pinned to. A plugin installed from a local directory is listed by its absolute path instead, and is yielded under that path as its id.

The @ref is a Git tag or branch, which is the only revision Fisher records: an unpinned plugin tracks its default branch and so reports no version at all.

$ fish -c 'fisher list'
jorgebucaran/fisher
ilancosman/tide@v5
jorgebucaran/nvm.fish
id: str = 'fisher'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

install(package_id, version=None)[source]

Install one package.

install both clones the plugin and appends it to the user’s fish_plugins file, so a package installed through mpm is loaded by the next shell instead of sitting on disk unreferenced.

A version is passed straight through as Fisher’s @ref suffix. That round-trips exactly: the ref installed() reports is the one Fisher accepts back here.

$ fish -c 'fisher install ilancosman/tide@v5'
fisher installing ilancosman/tide@v5
         Fetching https://codeload.github.com/ilancosman/tide/tar.gz/v5
         Installing ilancosman/tide@v5
         12 functions, 2 completions, 3 conf.d scripts
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

A bare fisher update re-reads the user’s fish_plugins file and updates every plugin listed in it.

$ fish -c 'fisher update'
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ fish -c 'fisher update jorgebucaran/nvm.fish'
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

remove is the exact counterpart of Fisher.install(): it drops the plugin’s files and its line from the user’s fish_plugins file, so the next shell no longer loads it.

$ fish -c 'fisher remove jorgebucaran/nvm.fish'
fisher removing jorgebucaran/nvm.fish
         5 functions, 1 completion, 1 conf.d script
Return type:

str

meta_package_manager.managers.flatpak module

class meta_package_manager.managers.flatpak.Flatpak[source]

Bases: PackageManager

Flatpak manages sandboxed desktop applications pulled from remotes like Flathub.

mpm covers applications only: every listing passes --app, so runtimes and SDKs stay out of scope. Listings are requested with --columns=name,application,version --ostree-verbose and parsed as tab-separated rows.

Note

All operations target the system-wide scope except cleanup which only repairs the user installation. Per-scope targeting (system vs user) is tracked in #1725.

Note

Escalation is polkit’s job, so no operation is marked sudo: flatpak hands system-scope mutations to its privileged system helper over D-Bus, which authorizes them through polkit (Flathub documents plain flatpak install). Under a strict polkit policy, unattended mutations need a rule permitting them without interactive authentication.

Caution

outdated reads each pending update’s latest version from remote-ls --updates, then runs one flatpak info per package to recover its installed version: a follow-up CLI call for every outdated app.

Note

A --brewfile dump emits the bare flatpak "id" form, mpm capturing no origin remote per app. See Snapshot and export, section “Flatpak remote”.

Initialize cli_errors list.

homepage_url: str | None = 'https://flatpak.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'flatpak'

Mapped to Homebrew Bundle’s flatpak extension.

Its with: ["remote"] keyword goes unused, installed() capturing no origin remote to fill it with. See Snapshot and export, section “Flatpak remote”.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.2.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

version_regexes: tuple[str, ...] = ('Flatpak\\s+(?P<version>\\S+)',)
$ flatpak --version
Flatpak 1.4.2
property installed: Iterator[Package]

Fetch installed packages.

$ flatpak list --app --columns=name,application,version         > --ostree-verbose
Peek    com.uploadedlobster.peek        1.3.1
Fragments       de.haeckerfelix.Fragments       1.4
GNOME MPV       io.github.GnomeMpv      0.16
Syncthing GTK   me.kozec.syncthingtk    v0.9.4.3
Builder org.flatpak.Builder
property outdated: Iterator[Package]

Fetch outdated packages.

$ flatpak remote-ls --app --updates --columns=name,application,version             --ostree-verbose
GNOME Dictionary        org.gnome.Dictionary    3.26.0
Files   org.gnome.Nautilus      42.2
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ flatpak search gitg --ostree-verbose
gitg    GUI for git        org.gnome.gitg  3.32.1  stable  flathub
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ flatpak install --noninteractive org.gnome.Dictionary
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ flatpak update --noninteractive
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ flatpak update --noninteractive org.gnome.Dictionary
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ flatpak uninstall --noninteractive org.gnome.Dictionary
Return type:

str

cleanup_orphan()[source]

Uninstall runtimes and extensions no longer used by any installed app.

$ flatpak uninstall --unused --noninteractive
Return type:

None

cleanup_repair()[source]

Verify and repair the per-user installation.

See the flatpak repair reference.

$ flatpak repair --user
Return type:

None

cli_names: tuple[str, ...] = ('flatpak',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'flatpak'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Flatpak'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

The read-only twin of cleanup_repair(): --dry-run reports what a repair of the per-user installation would fix without touching it.

$ flatpak repair --user --dry-run
Return type:

tuple[str, ...]

meta_package_manager.managers.fwupd module

class meta_package_manager.managers.fwupd.FWUPD[source]

Bases: PackageManager

fwupd manages device firmware, treating each updatable device as a package.

Firmware inventory and updates come from the LVFS (Linux Vendor Firmware Service). Each package is keyed by its fwupd DeviceId, carrying the device name and current firmware version. mpm drives fwupdmgr in JSON mode (get-devices --json, get-updates --json), which sets the version floor at 1.9.5: the first release to emit JSON for get-devices.

Note

installed and outdated report only devices carrying the updatable flag: fixed or unsupported hardware is skipped even though fwupdmgr still lists it.

Note

No search (firmware has no name catalog to query) and no remove (firmware cannot be uninstalled). Flashing is forced non-interactive: no confirmation prompt, no reboot check, no device-selection prompt.

Note

Escalation is polkit’s job, so no operation is marked sudo: fwupdmgr is an unprivileged client handing requests to the fwupd daemon over D-Bus, which authorizes firmware writes through polkit, like pkcon and flatpak. Under a strict polkit policy, unattended mutations need a rule permitting them without interactive authentication.

Initialize cli_errors list.

name: str = 'Linux fwupd'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://fwupd.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.9.5'

Version 1.9.5 is the first supporting –json parameter for get-devices command.

cli_names: tuple[str, ...] = ('fwupdmgr',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('--assume-yes', '--no-reboot-check', '--no-device-prompt')
version_regexes: tuple[str, ...] = ('compile\\s+org\\.freedesktop\\.fwupd\\s+(?P<version>\\S+)\\s+',)
$ fwupdmgr --version
compile   com.hughsie.libxmlb           0.3.18
compile   com.hughsie.libjcat           0.2.0
compile   org.freedesktop.fwupd         1.9.24
runtime   org.freedesktop.fwupd-efi     1.4
compile   org.freedesktop.gusb          0.4.8
runtime   com.hughsie.libxmlb           0.3.x
runtime   org.freedesktop.gusb          0.4.8
runtime   com.hughsie.libjcat           0.2.0
runtime   org.freedesktop.fwupd         1.9.24
runtime   org.kernel                    6.8.0-48-generic
property installed: Iterator[Package]

Fetch installed packages.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt get-devices --json
{
  "Devices": [
    {
      "Name": "USB2.0 Hub",
      "DeviceId": "7622d5fdbf1d1e08138156da7d83bf693986ad16",
      "ParentDeviceId" : "b5540761dfe33d9abccd3bb21f1d725f9e69f541",
      "CompositeId" : "b5540761dfe33d9abccd3bb21f1d725f9e69f541",
      "InstanceIds": [
        "USB\VID_17EF&PID_3080",
        "USB\VID_17EF&PID_3080&REV_5163",
        "USB\VID_17EF&PID_3080&HUB_20",
        "USB\VID_17EF&PID_3080&SPI_C220",
        "USB\VID_17EF&PID_3080&SPI_C220&REV_5163",
        "USB\VID_17EF&PID_3080&DEV_VL820Q7"
      ],
      "Guid": [
        "8ee94f0e-9b44-596a-bdd9-6f90401664cc",
        "35199e34-cf82-5b09-9287-622d225056e4",
        "0987e3c9-b1ee-5763-ac6e-51329b034e4b",
        "163cea66-5a78-58af-80ba-21be960aae5c",
        "c7def18d-66ae-5531-924b-2020c3638181"
      ],
      "Summary": "USB 3.x hub",
      "Plugin": "vli",
      "Protocol" : "com.vli.usbhub",
      "Flags": [
        "updatable",
        "registered",
        "can-verify",
        "can-verify-image",
        "dual-image",
        "self-recovery",
        "add-counterpart-guids",
        "unsigned-payload"
      ],
      "Vendor": "VIA Labs, Inc.",
      "VendorId" : "USB:0x17EF",
      "Version": "51.63",
      "VersionFormat" : "bcd",
      "VersionRaw": 20835,
      "Icons": [
        "usb-hub"
      ],
      "InstallDuration" : 15,
      "Created": 1686048073
    },
    {
      "DeviceId" : "20de1d77d0d1787bc56ef62f7d05de49361e1e07",
      "InstanceIds" : [
        "DRM\VEN_RHT&DEV_1234"
      ],
      "Guid" : [
        "90b1437c-86da-5374-a9a7-ceca8b0afd5e"
      ],
      "Plugin" : "linux_display",
      "Flags" : [
        "registered"
      ],
      "Created" : 1731659840
    },
    {
      "Name" : "UEFI dbx",
      "DeviceId" : "362301da643102b9f38477387e2193e57abaa590",
      "InstanceIds" : [
        "UEFI\CRT_E1FFABB40A30D9EE750BDA8BAF36ACA304FF20526138129247576B3339C54537&ARCH_AA64",
        "UEFI\CRT_A1117F516A32CEFCBA3F2D1ACE10A87972FD6BBE8FE0D0B996E09E65D802A503&ARCH_AA64"
      ],
      "Guid" : [
        "a9b31b16-b184-560f-97cb-1aa25e418c7d",
        "67d35028-ca5b-5834-834a-f97380381082"
      ],
      "Summary" : "UEFI revocation database",
      "Plugin" : "uefi_dbx",
      "Protocol" : "org.uefi.dbx",
      "Flags" : [
        "internal",
        "updatable",
        "supported",
        "registered",
        "needs-reboot",
        "usable-during-update",
        "only-version-upgrade",
        "signed-payload"
      ],
      "Checksums" : [
        "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      ],
      "VendorId" : "UEFI:Linux Foundation",
      "Version" : "0",
      "VersionLowest" : "0",
      "VersionFormat" : "number",
      "Icons" : [
        "computer"
      ],
      "InstallDuration" : 1,
      "Created" : 1731659840,
      "Releases" : [
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "35289",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>Insecure versions of the Microsoft Windows boot manager affected by Black Lotus were added to the list of forbidden signatures due to a discovered security problem.This updates the dbx to the latest release from Microsoft.</p><p>Before installing the update, fwupd will check for any affected executables in the ESP and will refuse to update if it finds any boot binaries signed with any of the forbidden signatures.Applying this update may also cause some Windows install media to not start correctly.</p>",
          "Version" : "26",
          "Filename" : "DBXUpdate-20230509-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2022-21894"
          ],
          "Checksum" : [
            "46a42362cd34c0d103cf534ca431508d24715e51",
            "3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4610,
          "Created" : 1683590400,
          "Locations" : [
            "https://fwupd.org/downloads/3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6-DBXUpdate-20230509-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6-DBXUpdate-20230509-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        },
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "28503",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>An insecure version of software from vmware has been added to the list of forbidden signatures due to a discovered security problem.This updates the dbx to the latest release from Microsoft.</p><p>Before installing the update, fwupd will check for any affected executables in the ESP and will refuse to update if it finds any boot binaries signed with any of the forbidden signatures.</p>",
          "Version" : "22",
          "Filename" : "DBXUpdate-20230314-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2023-28005"
          ],
          "Checksum" : [
            "611e745638f05e9a11c2998cfba38f0bad651141",
            "533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4418,
          "Created" : 1678752000,
          "Locations" : [
            "https://fwupd.org/downloads/533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3-DBXUpdate-20230314-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3-DBXUpdate-20230314-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        },
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "15180",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>This updates the dbx to the latest release from Microsoft which adds insecure versions of grub and shim to the list of forbidden signatures due to multiple discovered security updates.</p>",
          "Version" : "21",
          "Filename" : "DBXUpdate-20220812-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2022-34303",
            "309662",
            "CVE-2022-34302",
            "CVE-2022-34301"
          ],
          "Checksum" : [
            "4032a1d8734e6085f4a6e4bb26a038eb639603b9",
            "bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4370,
          "Created" : 1595980800,
          "Locations" : [
            "https://fwupd.org/downloads/bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999-DBXUpdate-20220812-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999-DBXUpdate-20220812-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        }
      ]
    },
    {
      "Name" : "Virtio network device",
      "DeviceId" : "17076870bcf7a84a9c8e999d7e54e39b446032bb",
      "InstanceIds" : [
        "PCI\VEN_1AF4&DEV_1000",
        "PCI\VEN_1AF4&DEV_1000&SUBSYS_1AF40001"
      ],
      "Guid" : [
        "21c85fac-5270-576f-a84e-04969f8cf75a",
        "b93ef629-0df1-5505-9fee-6992b8b9abd8"
      ],
      "Plugin" : "optionrom",
      "Flags" : [
        "internal",
        "registered",
        "can-verify",
        "can-verify-image"
      ],
      "Vendor" : "Red Hat, Inc.",
      "VendorId" : "PCI:0x1AF4",
      "Created" : 1731659840
    }
  ]
}
property outdated: Iterator[Package]

Fetch outdated packages.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt get-updates --json
{
  "Devices" : [
    {
      "Name" : "UEFI dbx",
      "DeviceId" : "362301da643102b9f38477387e2193e57abaa590",
      "InstanceIds" : [
        "UEFI\CRT_E1FFABB40A30D9EE750BDA8BAF36ACA304FF20526138129247576B3339C54537&ARCH_AA64",
        "UEFI\CRT_A1117F516A32CEFCBA3F2D1ACE10A87972FD6BBE8FE0D0B996E09E65D802A503&ARCH_AA64"
      ],
      "Guid" : [
        "a9b31b16-b184-560f-97cb-1aa25e418c7d",
        "67d35028-ca5b-5834-834a-f97380381082"
      ],
      "Summary" : "UEFI revocation database",
      "Plugin" : "uefi_dbx",
      "Protocol" : "org.uefi.dbx",
      "Flags" : [
        "internal",
        "updatable",
        "supported",
        "registered",
        "needs-reboot",
        "usable-during-update",
        "only-version-upgrade",
        "signed-payload"
      ],
      "Checksums" : [
        "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
      ],
      "VendorId" : "UEFI:Linux Foundation",
      "Version" : "0",
      "VersionLowest" : "0",
      "VersionFormat" : "number",
      "Icons" : [
        "computer"
      ],
      "InstallDuration" : 1,
      "Created" : 1731659840,
      "Releases" : [
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "35289",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>Insecure versions of the Microsoft Windows boot manager affected by Black Lotus were added to the list of forbidden signatures due to a discovered security problem.This updates the dbx to the latest release from Microsoft.</p><p>Before installing the update, fwupd will check for any affected executables in the ESP and will refuse to update if it finds any boot binaries signed with any of the forbidden signatures.Applying this update may also cause some Windows install media to not start correctly.</p>",
          "Version" : "26",
          "Filename" : "DBXUpdate-20230509-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2022-21894"
          ],
          "Checksum" : [
            "46a42362cd34c0d103cf534ca431508d24715e51",
            "3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4610,
          "Created" : 1683590400,
          "Locations" : [
            "https://fwupd.org/downloads/3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6-DBXUpdate-20230509-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/3ff3f17a9e5d372e51503803f22294f32ca90d1fe570b0bef4088c3a542617e6-DBXUpdate-20230509-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        },
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "28503",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>An insecure version of software from vmware has been added to the list of forbidden signatures due to a discovered security problem.This updates the dbx to the latest release from Microsoft.</p><p>Before installing the update, fwupd will check for any affected executables in the ESP and will refuse to update if it finds any boot binaries signed with any of the forbidden signatures.</p>",
          "Version" : "22",
          "Filename" : "DBXUpdate-20230314-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2023-28005"
          ],
          "Checksum" : [
            "611e745638f05e9a11c2998cfba38f0bad651141",
            "533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4418,
          "Created" : 1678752000,
          "Locations" : [
            "https://fwupd.org/downloads/533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3-DBXUpdate-20230314-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/533ce4ac028585925268d9e39079b71730a7abd94f611bc532707938d4271ad3-DBXUpdate-20230314-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        },
        {
          "AppstreamId" : "org.linuxfoundation.dbx.aa64.firmware",
          "ReleaseId" : "15180",
          "RemoteId" : "lvfs",
          "Name" : "Secure Boot dbx",
          "NameVariantSuffix" : "aa64",
          "Summary" : "UEFI Secure Boot Forbidden Signature Database",
          "Description" : "<p>This updates the dbx to the latest release from Microsoft which adds insecure versions of grub and shim to the list of forbidden signatures due to multiple discovered security updates.</p>",
          "Version" : "21",
          "Filename" : "DBXUpdate-20220812-aa64.cab",
          "Protocol" : "org.uefi.dbx",
          "Categories" : [
            "X-Configuration",
            "X-System"
          ],
          "Issues" : [
            "CVE-2022-34303",
            "309662",
            "CVE-2022-34302",
            "CVE-2022-34301"
          ],
          "Checksum" : [
            "4032a1d8734e6085f4a6e4bb26a038eb639603b9",
            "bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999"
          ],
          "License" : "LicenseRef-proprietary",
          "Size" : 4370,
          "Created" : 1595980800,
          "Locations" : [
            "https://fwupd.org/downloads/bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999-DBXUpdate-20220812-aa64.cab"
          ],
          "Uri" : "https://fwupd.org/downloads/bf56092de6586604d2b41d5bb4c9b7787a07adde408fd4134a3f3606f7fda999-DBXUpdate-20220812-aa64.cab",
          "Homepage" : "https://uefi.org/revocationlistfile",
          "Vendor" : "Linux Foundation",
          "Flags" : [
            "trusted-metadata",
            "is-upgrade"
          ],
          "InstallDuration" : 1
        }
      ]
    }
  ]
}
install(package_id, version=None)[source]

Install one package.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt install 362301da643102b9f38477387e2193e57abaa590
WARNING: UEFI capsule updates not available or enabled in firmware setup
See https://github.com/fwupd/fwupd/wiki/PluginFlag:capsules-unsupported for more information.
0.      Cancel
1.      26
2.      22
3.      21
Choose release [0-3]: 3
Scheduling…              [***************************************]
Successfully installed firmware

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt install 362301da643102b9f38477387e2193e57abaa590 21
WARNING: UEFI capsule updates not available or enabled in firmware setup
See https://github.com/fwupd/fwupd/wiki/PluginFlag:capsules-unsupported for more information.
Scheduling…              [***************************************]
362301da643102b9f38477387e2193e57abaa590 is already scheduled to be updated
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt update
Return type:

tuple[str, ...]

id: str = 'fwupd'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt update 362301da643102b9f38477387e2193e57abaa590
WARNING: UEFI capsule updates not available or enabled in firmware setup
See https://github.com/fwupd/fwupd/wiki/PluginFlag:capsules-unsupported for more information.
Scheduling…              [ -                                     ]
362301da643102b9f38477387e2193e57abaa590 is already scheduled to be updated
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Sync package metadata.

$ fwupdmgr --assume-yes --no-reboot-check --no-device-prompt refresh --force
Updating lvfs
Downloading…             [***************************************]
Successfully downloaded new metadata: 1 local device supported
Return type:

None

meta_package_manager.managers.gem module

class meta_package_manager.managers.gem.Gem[source]

Bases: PackageManager

The RubyGems package manager.

gem emits no machine-readable format, so installed, outdated and search listings are parsed from its text output. A gem can keep several versions installed side by side (molinillo (0.5.4, 0.4.5, 0.2.3)); mpm reports the highest as the installed version.

Note

All operations target the default gem scope (controlled by GEM_HOME). On system Ruby this means system-level gems, which may require elevated privileges for write operations: those carry dormant privileged markers, so mpm --sudo or a [mpm.managers.gem] sudo = true override escalates them, while nothing escalates by default. On recent macOS that default scope lives on the sealed, read-only system volume, so the gems Ruby bundles there surface as outdated yet cannot be upgraded in place, not even with sudo: point mpm at a writable, user-controlled Ruby earlier on your PATH instead. Per-scope targeting (system vs user gems) is tracked in #1725.

Tip

Installs require sudo on system ruby. I (@tresni) recommend doing something like:

$ sudo dseditgroup -o edit -a -t user wheel

And then do visudo to make it so the wheel group does not require a password. There is a line already there for it, you just need to uncomment it and save.

Initialize cli_errors list.

name: str = 'RubyGems'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://rubygems.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.5.0'
$ gem --version
3.0.3
post_args: tuple[str, ...] = ('--quiet',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

property installed: Iterator[Package]

Fetch installed packages.

$ gem list --quiet
bigdecimal (default: 1.4.1)
bundler (default: 1.17.2)
CFPropertyList (2.3.6)
cmath (default: 1.0.0)
csv (default: 3.0.9)
date (default: 2.0.0)
fileutils (1.4.1, default: 1.1.0)
io-console (0.5.6, default: 0.4.7)
ipaddr (default: 1.2.2)
molinillo (0.5.4, 0.4.5, 0.2.3)
nokogiri (1.5.6)
psych (2.0.0)
rake (0.9.6)
rdoc (4.0.0)
sqlite3 (1.3.7)
test-unit (2.0.0.0)
property outdated: Iterator[Package]

Fetch outdated packages.

$ gem outdated --quiet
did_you_mean (1.0.0 < 1.0.2)
io-console (0.4.5 < 0.4.6)
json (1.8.3 < 2.0.1)
minitest (5.8.3 < 5.9.0)
power_assert (0.2.6 < 0.3.0)
psych (2.0.17 < 2.1.0)
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports extended mode.

$ gem search python --versions --quiet
at_coder_friends-generator-python_ref (0.2.0)
bee_python (0.2.3)
dependabot-python (0.117.5)
logstash-filter-python (0.0.1 java)
python (0.0.1)
python-generator (1.1.0)
python_with_git_test (2.499.8)
rabbit-slide-niku-erlangvm-for-pythonista (2015.09.12)
RubyToPython (0.0)
$ gem search python --versions --exact --quiet
python (0.0.1)
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ gem install --quiet markdown
Fetching kramdown-2.3.1.gem
Fetching concurrent-ruby-1.1.9.gem
(...)
Fetching rubyzip-2.3.2.gem
Fetching logutils-0.6.1.gem
Fetching markdown-1.2.0.gem
Successfully installed kramdown-2.3.1
Successfully installed rubyzip-2.3.2
(...)
Successfully installed markdown-1.2.0
(...)
Parsing documentation for markdown-1.2.0
Installing ri documentation for markdown-1.2.0
Done installing documentation for (...) markdown after 19 seconds
12 gems installed
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ gem update --quiet
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ gem update --quiet markdown
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ gem uninstall left-pad --quiet
Successfully uninstalled left-pad-1.1.0
Return type:

str

sync()[source]

Sync package metadata.

$ gem sources --update --quiet
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore.

$ gem cleanup --quiet
Cleaning up installed gems...
Attempting to uninstall test-unit-3.2.9
Unable to uninstall test-unit-3.2.9:
    Gem::FilePermissionError: You don't have write permissions             for the /Library/Ruby/Gems/2.6.0 directory.
Attempting to uninstall did_you_mean-1.3.0
Unable to uninstall did_you_mean-1.3.0:
    Gem::FilePermissionError: You don't have write permissions             for the /Library/Ruby/Gems/2.6.0 directory.
Clean up complete
Return type:

None

cli_names: tuple[str, ...] = ('gem',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

check verifies the integrity of every installed gem, exiting non-zero on problems.

$ gem check --quiet
Return type:

tuple[str, ...]

id: str = 'gem'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.gext module

meta_package_manager.managers.gext.DRY_RUN_UPDATES_FOUND = 17

Exit code gext update --dry-run uses to report that updates exist.

A dry run finding nothing exits 0, and finding something raises SystemExit(17) after printing its report, so neither is a failure. Anything else is.

class meta_package_manager.managers.gext.Gext[source]

Bases: PackageManager

Manager of GNOME Shell extensions, from extensions.gnome.org.

Note

GNOME ships an official gnome-extensions tool, which is deliberately not what this wraps. That one installs from a local bundle and never reaches the extension registry, has no search, and offers no upgrade verb at all; its list --updates filters on a boolean carrying no available version, so it could not report an outdated package even in principle. gext reaches the registry, and every operation below rests on that.

Caution

An extension is identified by its UUID (caffeine@patapon.info), which is what the listing reports and what every other operation accepts. The human-readable name printed beside it is decoration and is never a valid argument.

Important

A running GNOME is required, whichever backend is in play. gext talks to GNOME Shell over D-Bus when a session is there and falls back to reading the filesystem otherwise, but even that fallback shells out to gsettings for the enabled-extension list, so a host without GNOME’s schemas fails rather than reporting an empty inventory. mpm leaves the backend choice to gext rather than forcing one, so a desktop session and a plain shell each get the path that works there.

Warning

The inventory forces --all. Left off, gext list reports only the enabled extensions, silently omitting every installed-but-disabled one: that is the tool’s own default and it would make the inventory a lie rather than a shorter list.

No sync: the registry is queried per operation and there is no index to refresh. No cleanup: nothing prunes anything.

No escalation: extensions install under the user’s own data directory.

Documentation: gnome-extensions-cli.

Initialize cli_errors list.

name: str = 'GNOME Shell extensions'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/essembeh/gnome-extensions-cli'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.11.0'

The release every format below was captured from.

The parser most likely tolerates the 0.10.x series, whose output is not known to differ, but the floor tracks what was verified rather than what was assumed: the dry run’s exit code in particular is load-bearing here and was only observed on this release.

cli_names: tuple[str, ...] = ('gext',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

extra_env: ClassVar = {'NO_COLOR': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_regexes: tuple[str, ...] = ('^gext\\s+(?P<version>\\S+)$',)

Search the version right after the program name.

$ gext --version
gext 0.11.0
property installed: Iterator[Package]

Fetch installed packages.

$ gext list --all
🔵 Dash to Dock (dash-to-dock@micxgx.gmail.com) v92 /user
🔵 Version Free (no-version@example.org)  /user
⚪ Caffeine (caffeine@patapon.info) v58 /user
id: str = 'gext'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property outdated: Iterator[Package]

Fetch outdated packages.

Important

The dry run exits 17 once it has something to report, so a non-zero exit is the populated answer here and 0 is the empty one. Only a third code means the check itself failed. The entry that failing exit records is discarded, this one being a result rather than an error.

Caution

Only enabled extensions carrying a version are checked, which is gext’s own rule rather than a filter applied here: a disabled extension appears in the inventory above but never in this report.

$ gext update --dry-run
[1] Found extension Caffeine (caffeine@patapon.info) v60 : outdated
[2] Found extension Dash to Dock (dash-to-dock@micxgx.gmail.com) v105 : outdated

📦 Extensions to update:
   caffeine@patapon.info
   dash-to-dock@micxgx.gmail.com
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search supports neither extended nor exact matching: the registry decides what the query matches, so meta_package_manager.manager.PackageManager.refiltered_search() narrows whatever comes back.

$ gext search caffeine
⚪ [1/6] Caffeine (caffeine@patapon.info)
   link : https://extensions.gnome.org/extension/517/caffeine/
   screenshot : https://extensions.gnome.org/extension-data/screenshots/screenshot_517.png
   creator : eon
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

gext picks the release matching the running GNOME Shell on its own, so there is no version to pin.

$ gext install caffeine@patapon.info
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

--yes answers the single confirmation update asks before applying; without it the command blocks on a prompt.

$ gext update --yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Naming an extension genuinely restricts the run to it.

$ gext update --yes caffeine@patapon.info
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ gext uninstall caffeine@patapon.info
Return type:

str

meta_package_manager.managers.ghcup module

class meta_package_manager.managers.ghcup.GHCup[source]

Bases: PackageManager

Haskell toolchain installer, covering GHC and the tools built around it.

ghcup installs several kinds of tool side by side: GHC itself, plus cabal, hls, stack and whatever else its metadata offers. All of them are packages here, because ghcup list reports every kind in one flat listing whose every line names its own kind, and because install, rm, set and whereis all take the same <tool> <version> pair. Reporting only GHC versions would hide from the inventory tools mpm remains perfectly able to install and remove.

A package is therefore identified as <tool>-<version>, and split back on its first hyphen to rebuild the pair. First rather than last is load-bearing: a cross-compiling GHC renders its target into the version cell, so ghc-aarch64-unknown-linux-gnu-9.4.8 has to split into ghc and aarch64-unknown-linux-gnu-9.4.8, and that remainder is exactly the token ghcup’s own version parser accepts. No tool name contains a hyphen today.

Note

Every listing forces --show-revisions none. ghcup otherwise appends a -rN metadata-revision suffix to versions that have one, and that suffixed string is not a version ghcup rm will match: the inventory would then report packages that cannot be removed. The suffix appears only while a revision is pending, so the corruption is intermittent, which is worse than a consistent one.

Caution

Neither upgrade operation is declared, and neither is an oversight. ghcup upgrade upgrades the ghcup binary itself, not the tools it installs, so mapping it onto upgrade --all would replace the user’s package manager when they asked to upgrade their packages. And ghcup has no in-place upgrade for a tool at all: a newer GHC is a fresh side-by-side install that leaves the old one in place, which is what install already does.

Note

No outdated either, for a reason that follows from the package identity above rather than from any missing command. Since the version is part of the id, a package having a newer version is a contradiction: the newer version is a different package, installed alongside rather than over. A report pairing ghc-9.6.7 with a latest of 9.10.1 would also name an upgrade mpm cannot perform, both upgrade operations being absent. ghcup’s own new-version notice is no help here: it is prose on stderr, it deduplicates itself against a cache file so a second run prints nothing, and it fires as a side effect of unrelated commands.

Documentation: ghcup user guide.

Initialize cli_errors list.

name: str = 'Haskell ghcup'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.haskell.org/ghcup/'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.2.1.0'

First release accepting --show-revisions, which every listing needs to keep the -rN suffix out of versions that must round-trip to ghcup rm.

Higher than the release the parsers themselves would need, and deliberately so: ghcup is installed by its own bootstrap script and upgrades itself rather than being carried by distributions, so a recent floor costs little.

extra_env: ClassVar = {'GHCUP_SKIP_UPDATE_CHECK': '1', 'NO_COLOR': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_cli_options: tuple[str, ...] = ('--numeric-version',)

Preferred over --version, which wraps the number in a sentence and interpolates a build-time git description. This prints the bare version.

version_regexes: tuple[str, ...] = ('^(?P<version>\\d+(?:\\.\\d+)+)',)

Search the bare version this option prints on its own.

$ ghcup --numeric-version
0.2.6.2
static split_package_id(package_id)[source]

Split a package id back into the <tool> <version> pair ghcup takes.

Splits on the first hyphen, which is what keeps a cross-compiling GHC intact: its target triple lives in the version cell, so everything after the tool name belongs to the version.

Return type:

tuple[str, str]

property installed: Iterator[Package]

Fetch installed packages.

--show-criteria installed filters upstream, so the installed marker never has to be read back off the glyph column, which --raw-format drops anyway.

$ ghcup list --raw-format --show-revisions none --show-criteria installed
cabal 3.14.2.0 recommended
ghc 9.6.7 recommended,base-4.18.3.0
ghcup 0.2.6.2  stray
cli_names: tuple[str, ...] = ('ghcup',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'ghcup'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

search(query, extended, exact)[source]

Fetch matching packages.

ghcup has no search command: the full listing is its catalog, and a small one, so mpm filters it itself.

Caution

Search does not support extended or exact matching.

$ ghcup list --raw-format --show-revisions none
cabal 3.14.2.0 recommended
ghc 9.6.7 recommended,base-4.18.3.0
ghc 9.8.1  2023-10-09
Return type:

Iterator[Package]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

install(package_id, version=None)[source]

Install one package.

The version is already carried by the id, which is why this takes no version of its own.

$ ghcup install ghc 9.6.7
Return type:

str

remove(package_id)[source]

Removes a package.

Removing the version currently set neither fails nor warns: ghcup drops the symlinks and the set marker, leaving the tool simply unset.

$ ghcup rm ghc 9.6.7
Return type:

str

sync()[source]

Sync package metadata.

$ ghcup prefetch metadata
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore.

Confined to the download cache and the temporary directories. ghcup gc also offers switches that delete installed tools, which is not cleanup as mpm means it, and they are deliberately not passed.

$ ghcup gc --cache --tmpdirs
Return type:

None

meta_package_manager.managers.guix module

class meta_package_manager.managers.guix.Guix[source]

Bases: PackageManager

GNU Guix, GNU’s functional package manager.

Note

All operations target the current user’s default profile. Declarative system configuration (Guix System config.scm) is not covered.

Guix is a rolling release with no upstream semver to pin against: guix --version reports a release tag, a git describe string, or the bare commit hash of an in-tree checkout. No requirement floor is enforced, since any working guix will do.

Warning

search evaluates every package definition to match the query, so its cost scales with the size of the package set, not the result count: tens of seconds on a freshly pulled Guix, longer still from an in-tree development checkout. The call is bounded by mpm --timeout (120s by default), past which it is killed with no results returned, so a slow search can look like a hang.

Initialize cli_errors list.

name: str = 'GNU Guix'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://guix.gnu.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

version_regexes: tuple[str, ...] = ('guix \\(GNU Guix\\) (?P<version>\\d[\\w.\\-+]*)', 'guix \\(GNU Guix\\) (?P<version>[0-9a-f]{7,40})\\b')
$ guix --version
guix (GNU Guix) 1.4.0
property installed: Iterator[Package]

Fetch installed packages.

Output is tab-separated: name, version, output, store path.

$ guix package --list-installed
hello   2.10    out     /gnu/store/k74skdjjb9c9zqjv9nmgd6zi92wpf3q0-hello-2.10
python  3.10.7  out     /gnu/store/2n3g8n7d5xkp6h4qz1v8m0rjc9wf5aby-python-3.10.7
property outdated: Iterator[Package]

Fetch outdated packages.

Relies on guix upgrade --dry-run which lists every package that would be upgraded without modifying the user profile.

$ guix upgrade --dry-run
The following packages would be upgraded:
   hello 2.12.1 → 2.12.3
   sed   4.8 → 4.9
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

Caution

guix search loads and evaluates every package definition to match the query against each package’s name, synopsis, and description, so it is inherently slow: its cost scales with the size of the package set, not the number of results. A single search runs for tens of seconds on a freshly pulled Guix, and far longer from an in-tree dev checkout that recompiles modules on the fly. The call is bounded by mpm --timeout; when that is unset, search uses the 120s read-only default, past which the process is killed and no results are returned, so a slow search can look like a hang.

Results are printed in recutils format with records separated by blank lines.

$ guix search hello
name: hello
version: 2.10
outputs: out
systems: x86_64-linux i686-linux
dependencies: glibc@2.35 ...
location: gnu/packages/base.scm:86:2
homepage: https://www.gnu.org/software/hello/
license: GPL 3+
synopsis: Hello, GNU world: an example GNU package
description: GNU Hello prints the message "Hello, world!"
+ and then exits.  It serves as an example of standard
+ GNU coding practices.
relevance: 10
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ guix install hello
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ guix upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ guix upgrade hello
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('guix',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'guix'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package.

$ guix remove hello
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Fetch the latest Guix channel revisions.

$ guix pull
Return type:

None

cleanup_cache()[source]

Collect garbage in the store.

$ guix gc
Return type:

None

meta_package_manager.managers.homebrew module

class meta_package_manager.managers.homebrew.Homebrew[source]

Bases: PackageManager

Virtual base shared by the Brew and Cask managers.

Homebrew is the umbrella project behind the brew CLI. mpm exposes it as two managers over that single binary: Brew for formulae built from recipes, and Cask for pre-built macOS applications, each pinning its half with a --formula or --cask selector. This base holds the shared query, mutation and metadata logic; the concrete classes carry the manager-level narrative.

Initialize cli_errors list.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

Homebrew core is now compatible with Linux and Windows Subsystem for Linux (WSL) 2.

requirement: str | None = '>=6.0.0'

Vanilla brew and cask CLIs now shares the same version.

2.7.0 was the first release to enforce the use of --cask option.

6.0.0 is the first release in which ask mode is the default for brew install and brew upgrade, and the first to ship the --yes opt-out flag that mpm relies on for non-interactive upgrades.

virtual: bool = True

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

extra_env: ClassVar = {'HOMEBREW_NO_ANALYTICS': '1', 'HOMEBREW_NO_AUTO_UPDATE': '1', 'HOMEBREW_NO_ENV_HINTS': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_regexes: tuple[str, ...] = ('Homebrew\\s+(?P<version>\\S+)',)
$ brew --version
Homebrew 1.8.6-124-g6cd4c31
Homebrew/homebrew-core (git revision 533d; last commit 2018-12-28)
Homebrew/homebrew-cask (git revision 5095b; last commit 2018-12-28)
property installed: Iterator[Package]

Fetch installed packages.

$ brew list --versions --formula
ack 2.14
apg 2.2.3
audacity (!) 2.1.2
apple-gcc42 4.2.1-5666.3
atk 2.22.0
bash 4.4.5
bash-completion 1.3_1
boost 1.63.0
c-ares 1.12.0
graphviz 2.40.1 2.40.20161221.0239
quicklook-json latest
$ brew list --versions --cask
aerial 1.2beta5
android-file-transfer latest
audacity (!) 2.1.2
firefox 49.0.1
flux 37.7
gimp 2.8.18-x86_64
java 1.8.0_112-b16
tunnelblick 3.6.8_build_4625 3.6.9_build_4685
virtualbox 5.1.8-111374 5.1.10-112026

Todo

Use the removed variable to detect removed packages (which are reported with a (!) flag). See #17.

package_metadata_batch(packages)[source]

Enrich installed packages with Homebrew’s API + per-formula data.

Runs brew info --json=v2 --installed in a single shell-out and joins the result back onto the inventory list by package ID. For each formula that has <prefix>/Cellar/<name>/<version>/sbom.spdx.json on disk (the file Homebrew writes when installed under HOMEBREW_SBOM=1), the metadata’s external_sbom_path points at it so the SPDX renderer can splice the upstream document into the aggregate.

Casks reuse the same JSON payload through the casks array but do not get the SBOM-file treatment (Homebrew does not emit one for casks).

Return type:

Iterator[tuple[Package, PackageMetadata]]

property outdated: Iterator[Package]

Fetch outdated packages.

$ brew outdated --json=v2 --formula | jq
{
  "formulae": [
    {
      "name": "pygobject3",
      "installed_versions": [
        "3.36.1"
      ],
      "current_version": "3.38.0",
      "pinned": false,
      "pinned_version": null
    },
    {
      "name": "rav1e",
      "installed_versions": [
        "0.3.3"
      ],
      "current_version": "0.3.4",
      "pinned": false,
      "pinned_version": null
    }
  ],
  "casks": []
}
$ brew outdated --json=v2 --cask | jq
{
  "formulae": [],
  "casks": [
    {
      "name": "electrum",
      "installed_versions": "4.0.2",
      "current_version": "4.0.3"
    },
    {
      "name": "qlcolorcode",
      "installed_versions": "3.0.2",
      "current_version": "3.1.1"
    }
  ]
}
$ brew outdated --json=v2 --greedy --cask | jq
{
  "formulae": [],
  "casks": [
    {
      "name": "amethyst",
      "installed_versions": "0.14.3",
      "current_version": "0.15.3"
    },
    {
      "name": "balenaetcher",
      "installed_versions": "1.5.106",
      "current_version": "1.5.108"
    },
    {
      "name": "caldigit-thunderbolt-charging",
      "installed_versions": "latest",
      "current_version": "latest"
    },
    {
      "name": "electrum",
      "installed_versions": "4.0.2",
      "current_version": "4.0.3"
    },
    {
      "name": "lg-onscreen-control",
      "installed_versions": "5.33,cV8xqv5TSZA.upgrading, 5.47,yi5XuIZw6hg",
      "current_version": "5.48,uYXSwyUCNFBbSch9PFw"
    }
  ]
}

Note

Both the formula and cask payloads also carry pinned and pinned_version fields. The formula payload has always emitted them; the cask payload has emitted them since at least 5.1.15 but they only became meaningful with Homebrew 6.0.0, which added brew pin <cask> so casks can now actually be pinned. mpm discards both fields today: pinned packages still appear in mpm outdated output, and brew upgrade silently skips them at upgrade time. Track this gap if a future mpm release wants to surface or filter on pin state.

search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports extended mode.

$ brew search sed
==> Formulae
gnu-sed ✔                    libxdg-basedir
==> Casks
eclipse-dsl                       marsedit
focused                           physicseditor
google-adwords-editor             prefs-editor
licensed                          subclassed-mnemosyne
$ brew search sed --formulae
==> Formulae
gnu-sed ✔                    libxdg-basedir
$ brew search sed --cask
==> Casks
eclipse-dsl                       marsedit
focused                           physicseditor
google-adwords-editor             prefs-editor
licensed                          subclassed-mnemosyne
$ brew search python --formulae
==> Formulae
app-engine-python   boost-python3   python ✔          python-yq
boost-python        gst-python      python-markdown   python@3.8 ✔
$ brew search "/^ssed$/" --formulae
==> Formulae
ssed
$ brew search "/^sed$/" --formulae
Error: No formula or cask found for "/^sed$/".
$ brew search tetris --formulae --desc
==> Formulae
bastet: Bastard Tetris
netris: Networked variant of tetris
vitetris: Terminal-based Tetris clone
yetris: Customizable Tetris for the terminal
$ brew search tetris --cask --desc
==> Casks
not-tetris: (Not Tetris) [no description]
tetrio: (TETR.IO) Free-to-play Tetris clone

More doc in brew search.

Return type:

Iterator[Package]

trust_tap(package_id)[source]

Trust the tap a third-party package_id belongs to.

Homebrew 6.0.0 rejects code from third-party taps until the tap (or each formula or cask) has been explicitly trusted. Vanilla brew install would otherwise abort with a tap trust is required warning when the snapshot pins a user/tap/name package.

Only fully-qualified package IDs (user/tap/name) need this step: core formulae and casks live on the trusted homebrew/core and homebrew/cask taps. The tap itself is registered first (idempotent if already tapped) so brew trust can resolve the formula or cask. The --formula and --cask flag is supplied by the subclass’s post_args.

$ brew tap gromgit/fuse
$ brew trust gromgit/fuse/ntfs-3g-mac --formula
Return type:

None

install(package_id, version=None)[source]

Install one package.

Tap-qualified IDs (user/tap/name) are routed through trust_tap() first so the install isn’t rejected by Homebrew 6.0.0’s tap-trust gate.

$ brew install jpeginfo --formula
==> Downloading https://ghcr.io/core/jpeginfo/manifests/1.6.1_1-1
############################################################## 100.0%
==> Downloading https://ghcr.io/core/jpeginfo/blobs/sha256:27bb35884368b83
==> Downloading from https://pkg.githubcontent.com/ghcr1/blobs/sha256:27bb3
############################################################## 100.0%
==> Pouring jpeginfo--1.6.1_1.big_sure.bottle.1.tar.gz
🍺  /usr/local/Cellar/jpeginfo/1.6.1_1: 7 files, 77.6KB
$ brew install pngyu --cask
==> Downloading https://nukesaq.github.io/Pngyu/download/Pngyu_mac_101.zip
################################################################## 100.0%
==> Installing Cask pngyu
==> Moving App 'Pngyu.app' to '/Applications/Pngyu.app'
🍺  pngyu was successfully installed!
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

brew and cask share the same command, but cask overrides this method to append --greedy when auto-updating packages are included.

$ brew upgrade --formula
==> Upgrading 2 outdated packages:
node 13.11.0 -> 13.12.0
sdl2 2.0.12 -> 2.0.12_1
==> Upgrading node 13.11.0 -> 13.12.0
==> Downloading https://homebrew.bintray.com/bottles/node-13.tar.gz
==> Downloading from https://akamai.bintray.com/fc/fc0bfb42fe23e960
############################################################ 100.0%
==> Pouring node-13.12.0.catalina.bottle.tar.gz
==> Caveats
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
==> Summary
🍺  /usr/local/Cellar/node/13.12.0: 4,660 files, 60.3MB
Removing: /usr/local/Cellar/node/13.11.0... (4,686 files, 60.4MB)
==> Upgrading sdl2 2.0.12 -> 2.0.12_1
==> Downloading https://homebrew.bintray.com/bottles/sdl2-2.tar.gz
==> Downloading from https://akamai.bintray.com/4d/4dcd635465d16372
############################################################ 100.0%
==> Pouring sdl2-2.0.12_1.catalina.bottle.tar.gz
🍺  /usr/local/Cellar/sdl2/2.0.12_1: 89 files, 4.7MB
Removing: /usr/local/Cellar/sdl2/2.0.12... (89 files, 4.7MB)
==> Checking for dependents of upgraded formulae...
==> No dependents found!
==> Caveats
==> node
Bash completion has been installed to:
  /usr/local/etc/bash_completion.d
$ brew upgrade --cask
==> Casks with ``auto_updates`` or ``version :latest`` will not be upgraded
==> Upgrading 1 outdated packages:
aerial 2.0.7 -> 2.0.8
==> Upgrading aerial
==> Downloading https://github.com/Aerial/download/v2.0.8/Aerial.saver.zip
==> Downloading from https://65be.s3.amazonaws.com/44998092/29eb1e0
==> Verifying SHA-256 checksum for Cask 'aerial'.
==> Backing Screen Saver up to '/usr/local/Caskroom/Aerial.saver'.
==> Removing Screen Saver '/Users/kde/Library/Screen Savers/Aerial.saver'.
==> Moving Screen Saver to '/Users/kde/Library/Screen Savers/Aerial.saver'.
==> Purging files for version 2.0.7 of Cask aerial
🍺  aerial was successfully upgraded!

--yes skips the interactive confirmation prompt that brew shows by default since ask mode became the default behaviour.

Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

brew and cask share the same command.

$ brew upgrade dupeguru --cask
==> Upgrading 1 outdated package:
dupeguru 4.2.0 -> 4.2.1
==> Upgrading dupeguru
==> Downloading https://github.com/(...)/4.2.1/dupeguru_macOS_Qt_4.2.1.zip
==> Downloading from https://githubusercontent.com/production-release-asset
##################################################################### 100.0%
==> Backing App 'dupeguru.app' up to '/opt/homebrew/.../4.2.0/dupeguru.app'
==> Removing App '/Applications/dupeguru.app'
==> Moving App 'dupeguru.app' to '/Applications/dupeguru.app'
==> Purging files for version 4.2.0 of Cask dupeguru
🍺  dupeguru was successfully upgraded!

--yes skips the interactive confirmation prompt that brew shows by default since ask mode became the default behaviour.

Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ brew uninstall bat
Uninstalling /usr/local/Cellar/bat/0.21.0... (14 files, 5MB)
Return type:

str

sync()[source]

Sync package metadata.

$ brew update --quiet
Already up-to-date.
Return type:

None

cleanup_orphan()[source]

Uninstall every formula installed as a dependency and no longer needed.

$ brew autoremove
==> Uninstalling 17 unneeded formulae:
gtkmm3
highlight
lua@5.1
nasm
nghttp2
texi2html
Uninstalling /usr/local/Cellar/nghttp2/1.41.0_1... (26 files, 2.7MB)
Uninstalling /usr/local/Cellar/highlight/3.59... (558 files, 3.5MB)

Warning: The following highlight configuration files have not been removed!
If desired, remove them manually with ``rm -rf``:
  /usr/local/etc/highlight
  /usr/local/etc/highlight/filetypes.conf
  /usr/local/etc/highlight/filetypes.conf.default
Uninstalling /usr/local/Cellar/gtkmm3/3.24.2_1... (1,903 files, 173.7MB)
Uninstalling /usr/local/Cellar/texi2html/5.0... (279 files, 6.2MB)
Uninstalling /usr/local/Cellar/lua@5.1/5.1.5_8... (22 files, 245.6KB)
Uninstalling /usr/local/Cellar/nasm/2.15.05... (29 files, 2.9MB)
Return type:

None

cleanup_cache()[source]

Scrub the cache, including latest version’s downloads.

Downloads for all installed formulae and casks will not be deleted.

$ brew cleanup --quiet --scrub --prune=all
Removing: ~/Library/Caches/Homebrew/node--1.bottle.tar.gz... (9MB)
Warning: Skipping sdl2: most recent version 2.0.12_1 not installed
Removing: ~/Library/Caches/Homebrew/Cask/aerial--1.8.1.zip... (5MB)
Removing: ~/Library/Caches/Homebrew/Cask/prey--1.9.pkg... (19.9MB)
Removing: ~/Library/Logs/Homebrew/readline... (64B)
Removing: ~/Library/Logs/Homebrew/libfido2... (64B)
Removing: ~/Library/Logs/Homebrew/libcbor... (64B)

More doc in brew cleanup.

Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

brew doctor exits non-zero when it finds anything to warn about, and prints its findings on <stderr>. Like autoremove and cleanup, it takes no --formula/--cask selector.

$ brew doctor
Your system is ready to brew.
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('homebrew',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'homebrew'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Homebrew'

Return package manager’s common name.

Default value is based on class name.

class meta_package_manager.managers.homebrew.Brew[source]

Bases: Homebrew

The formula half of Homebrew: command-line tools built from recipes.

Homebrew is the umbrella project behind the brew CLI. mpm splits it into two managers over the same binary, this one for formulae and Cask for macOS applications; a forced --formula selector keeps every call on the formula side. Homebrew core runs on macOS and on Linux and WSL.

mpm drives brew non-interactively and pins its environment: analytics and setup hints are silenced, and HOMEBREW_NO_AUTO_UPDATE keeps brew from folding a metadata refresh into every command, since mpm runs that as a separate sync (asked for since mpm’s early days). Outdated packages come from --json=v2; the installed and search listings are parsed from their plain-text columns.

Note

The >=6.0.0 requirement is the release where ask mode became the default for brew install and brew upgrade, and where the --yes opt-out mpm relies on for unattended runs first shipped. It is also where Homebrew began rejecting third-party taps until trusted, so installing a fully-qualified user/tap/name package taps and trusts it first (see Homebrew.trust_tap()).

Caution

A pinned formula still appears in mpm outdated output, yet brew upgrade silently skips it: mpm discards Homebrew’s pinned fields today.

Initialize cli_errors list.

name: str = 'Homebrew Formulae'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://brew.sh'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'brew'

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

cli_names: tuple[str, ...] = ('brew',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

post_args: tuple[str, ...] = ('--formula',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

property orphans: Iterator[Package]

Fetch formulae installed as dependencies that nothing requires anymore.

--dry-run turns autoremove into a read-only report of the would-be-removed formulae. Defined on the formula manager only: casks are never installed as dependencies, so they cannot be orphaned. Like autoremove itself, the call drops the --formula selector the other formula operations force.

$ brew autoremove --dry-run --quiet
==> Would autoremove 3 unneeded formulae:
libpng
little-cms2
openjpeg
id: str = 'brew'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.homebrew.Cask[source]

Bases: Homebrew

The cask half of Homebrew: pre-built macOS applications.

Homebrew is the umbrella project behind the brew CLI. mpm splits it into two managers over the same binary, this one for casks and Brew for formulae; a forced --cask selector keeps every call on the cask side. Casks ship macOS .app bundles and .pkg installers, so this manager is macOS-only.

mpm drives brew non-interactively with the same environment pins as Brew (analytics and hints off, HOMEBREW_NO_AUTO_UPDATE so the metadata refresh stays a separate sync) and the same >=6.0.0 floor (ask mode default, the --yes opt-out, and the tap-trust gate that Homebrew.trust_tap() clears for user/tap/name packages).

Note

Casks self-escalate: their artifacts (.pkg installers, kernel extensions) invoke sudo from inside brew, so mpm never wraps a cask command in its own sudo.

Caution

Casks flagged auto_updates true or version :latest update themselves, and brew upgrade skips them unless --greedy is passed. mpm supplies --greedy (to outdated and to upgrade --all) unless auto-updating packages are being ignored. --greedy conflicts with --formula, so this handling is cask-only and cannot fold into the base shared with Brew.

Initialize cli_errors list.

name: str = 'Homebrew Cask'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/Homebrew/homebrew-cask'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'cask'

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='macos', name='macOS')})

Casks are only available on macOS, not Linux or WSL.

id: str = 'cask'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

internal_sudo: bool = True

Cask artifacts (.pkg installers, kernel extensions) run sudo from inside brew.

cli_names: tuple[str, ...] = ('brew',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

post_args: tuple[str, ...] = ('--cask',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

Adds --greedy to the shared brew upgrade command when auto-updating packages are included, mirroring Homebrew.outdated(). Without it, brew upgrade skips casks flagged auto_updates true or version :latest, so mpm --include-auto-updates upgrade --all would report them as outdated but never upgrade them.

Note

This override is cask-only by necessity: brew upgrade declares --greedy and --formula mutually exclusive, while brew outdated accepts the pair. The conflict is intentional: --formula has conflicted with --greedy ever since the selector switch was added to brew upgrade in August 2020, and a request to tolerate --greedy as a no-op in formula-only contexts was declined as invalid usage. This method can therefore never fold back into the base class shared with brew.

A cask explicitly passed to brew upgrade is always evaluated greedily, so Homebrew.upgrade_one_cli() needs no counterpart.

Return type:

tuple[str, ...]

meta_package_manager.managers.lazy module

meta_package_manager.managers.lazy.LAZY_ROOT = 'vim.fn.stdpath("data") .. "/lazy/lazy.nvim"'

Lua expression resolving lazy.nvim’s own checkout.

lazy.nvim manages itself, and its bootstrap snippet clones it under the lazy directory of Neovim’s data path. That is where a --clean process, which loads none of the user’s configuration, has to look to find it.

meta_package_manager.managers.lazy.LOCKFILE = 'vim.fn.stdpath("config") .. "/lazy-lock.json"'

Lua expression resolving the lock file lazy.nvim writes after every install or update, which is the inventory mpm reads.

meta_package_manager.managers.lazy.lua_command(body)[source]

Wrap a Lua body into the -c argument handed to Neovim.

The trailing os.exit(0) is the success path: it terminates Neovim before the failure gate in Lazy.post_args can run.

Return type:

str

class meta_package_manager.managers.lazy.Lazy[source]

Bases: PackageManager

lazy.nvim is a modern plugin manager for Neovim.

lazy.nvim is a Lua plugin, not a standalone binary: each operation below is a Lua one-liner evaluated by a throw-away Neovim process. Plugins are Git clones under stdpath('data')/lazy, pinned by a lazy-lock.json lock file in stdpath('config') that records the exact commit of each one.

Caution

Neovim is the binary mpm executes, and mpm already wraps Neovim’s built-in Vim_Pack, which legitimately keys on the same nvim. The two are told apart by the version probe: it reports a version only when lazy.nvim’s own checkout is found and its version constant reads back, so a host running Neovim without lazy.nvim leaves this manager unavailable instead of shadowing every editor on every machine.

Note

This manager is deliberately limited to inventorying and updating, the two operations lazy.nvim can carry out with nobody at the keyboard. That is already more than the coarse, whole-category upgrade a tool like topgrade performs for the same plugins, since the inventory comes with it.

Caution

No install and no remove: lazy.nvim materializes exactly the plugin set declared in the user’s own Lua configuration. :Lazy install clones what that configuration already names and :Lazy clean drops what it no longer names, so neither takes a plugin of mpm’s choosing. Installing one would mean mpm editing the user’s init.lua, which is configuration mpm does not own. The two operations are therefore not implemented rather than faked, and mpm auto-skips them.

Note

No outdated: :Lazy check does fetch each remote without touching a working tree, but the pending revisions it computes are only readable through a plugin’s private _.updates field, which lazy.nvim documents no contract for. mpm auto-skips the operation and upgrade --all still works.

Documentation: lazy.folke.io.

Initialize cli_errors list.

name: str = 'Neovim lazy-nvim'

Spelled with a dash: manager names are restricted to letters, digits, spaces, apostrophes and dashes, so the lazy.nvim project name cannot be used verbatim.

homepage_url: str | None = 'https://lazy.folke.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=11.0.0'

Current major series of lazy.nvim.

Both pieces this implementation depends on are older than that: the version constant the probe reads and the wait/show manager options the upgrade passes are present as far back as 10.0.0. The floor is held at the current major anyway, which is the series the implementation was exercised against.

cli_names: tuple[str, ...] = ('nvim',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('--headless',)
id: str = 'lazy'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

post_args: tuple[str, ...] = ('-c', 'cquit')

Failure gate, only reached when the Lua payload raised before reaching its own os.exit(0).

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

version_cli_options: tuple[str, ...] = ('--clean', '--headless', '-c', 'lua local p = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if (vim.uv or vim.loop).fs_stat(p) then vim.opt.rtp:prepend(p) io.write("lazy.nvim " .. require("lazy.core.config").version) end os.exit(0)')

Self-contained probe: version detection skips Lazy.pre_args and Lazy.post_args, so this carries its own --headless and exits on its own.

The checkout is tested before being put on the runtime path, so a Neovim without lazy.nvim prints nothing and exits successfully rather than raising. That silence is what leaves the manager unavailable on a host that merely has an editor installed.

version_regexes: tuple[str, ...] = ('lazy\\.nvim (?P<version>\\S+)',)
$ nvim --clean --headless     > -c 'lua local p = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" if (vim.uv or vim.loop).fs_stat(p) then vim.opt.rtp:prepend(p) io.write("lazy.nvim " .. require("lazy.core.config").version) end os.exit(0)'
lazy.nvim 11.17.5
property installed: Iterator[Package]

Fetch installed packages.

The lock file is read straight off disk by a --clean process, so the inventory costs no plugin loading and cannot be perturbed by the user’s configuration. stdpath() is XDG-derived and --clean does not move it, so the file still resolves.

Packages are keyed on the short name lazy.nvim derives from each plugin’s source, which is what the lock file records. The commit is the Git revision the plugin is checked out at, the only revision lazy.nvim tracks: a plugin follows a branch unless its spec pins a version.

Note

lazy.nvim manages itself, so it appears in its own inventory.

$ nvim --headless --clean \
> -c 'lua local f = io.open(vim.fn.stdpath("config") .. "/lazy-lock.json") if f then io.write(f:read("a")) end os.exit(0)' \
> -c 'cquit'
{
  "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
  "vim-sensible": { "branch": "master", "commit": "0ce2d843d6f588bb0c8c7eec6449171615dc56d9" },
  "z": { "branch": "master", "commit": "d37a763a6a30e1b32766fecc3b8ffd6127f8a0fd" }
}
upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

This is the one operation that lets the user’s configuration load: lazy.nvim only exists once init.lua has bootstrapped it, so --clean is deliberately absent here. wait blocks until every Git task has finished, which is what makes the run usable unattended, and show keeps the interactive floating window from being drawn.

$ nvim --headless \
> -c 'lua require("lazy").update({wait = true, show = false}) os.exit(0)' \
> -c 'cquit'
Return type:

tuple[str, ...]

meta_package_manager.managers.luarocks module

class meta_package_manager.managers.luarocks.LuaRocks[source]

Bases: PackageManager

LuaRocks, the package manager for Lua modules.

A package is a rock, identified by the bare name every listing prints. Its version carries a packaging revision after a dash (3.1.2-0), kept verbatim because that is the form luarocks install accepts back.

Note

Every read passes --porcelain, which replaces the default grouped display with one tab-separated record per line.

Note

Search is what makes this a class rather than a bundled definition. luarocks search prints one row per (rock, version, kind) triple, so a single rock comes back a dozen times over: once per published version, and again for each of the rockspec and src forms it ships in. mpm keys a package on its id alone, so the rows are reduced here to one entry per rock. The installed and outdated listings get the same treatment, LuaRocks being able to hold several versions of a rock in one tree.

Caution

--no-project is load-bearing. LuaRocks walks up from the working directory looking for a project tree and silently switches to it when one is found, so without the flag the inventory would answer for whichever directory mpm happened to be invoked from instead of for the machine. haxelib forces --global against the same hazard.

The flag is a global one, placed before the subcommand, which is why it is declared as pre_args rather than repeated per operation. The version probe skips pre_args entirely and so runs bare.

Caution

Reads and writes disagree about scope, and deliberately so. list reports every configured tree at once, which is the right answer for an inventory of the machine: the system tree and the user’s ~/.luarocks both show up, each row naming the tree holding it. install and remove act on one tree only, the default one, so removing a rock that lives in the other tree fails with Error: Could not find rock 'say' in /opt/homebrew.

That asymmetry is left as LuaRocks defines it rather than papered over. Forcing --local would make the user tree writable at the cost of the system one, and forcing --global the reverse; neither is right for every host, and the failure is loud, immediate and names the tree it searched.

Note

No upgrade --all: LuaRocks has no command updating every installed rock, install being what upgrades a named one in place. mpm backfills the bulk case from outdated plus the per-rock upgrade.

No sync either, nothing refreshing the manifest without also downloading, and no cleanup: luarocks purge empties an entire tree rather than reclaiming anything, which is a mass removal and not a cleanup.

Documentation: LuaRocks documentation.

Initialize cli_errors list.

name: str = 'LuaRocks'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://luarocks.org'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=3.9.1'

The release adding --no-project, which is what pins every read to the machine instead of to the working directory’s project tree.

pre_args: tuple[str, ...] = ('--no-project',)

Ignore any project tree found by walking up from the working directory, so the inventory describes the machine and not the current directory.

version_regexes: tuple[str, ...] = ('luarocks(?:\\.exe)?[ \\t]+(?P<version>\\d+\\.\\d+(?:\\.\\d+)?)',)

Search the version right after the binary path LuaRocks echoes back.

$ luarocks --version
/opt/homebrew/bin/luarocks 3.13.0
LuaRocks main command-line interface

The path is printed in full and varies per host, so the pattern anchors on the binary name rather than on the start of the line.

cli_names: tuple[str, ...] = ('luarocks',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'luarocks'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property installed: Iterator[Package]

Fetch installed packages.

$ luarocks --no-project list --porcelain
inspect 3.1.2-0 installed       /Users/kde/.luarocks/lib/luarocks/rocks-5.5
say     1.4.1-3 installed       /Users/kde/.luarocks/lib/luarocks/rocks-5.5
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property outdated: Iterator[Package]

Fetch outdated packages.

$ luarocks --no-project list --outdated --porcelain
inspect 3.1.2-0 3.1.3-0 https://luarocks.org
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching.

$ luarocks --no-project search say --porcelain
say     1.4.1-3 rockspec        https://luarocks.org
say     1.4.1-3 src     https://luarocks.org
say     1.4.0-1 rockspec        https://luarocks.org
say     1.4.0-1 src     https://luarocks.org
say     1.3-1   rockspec        https://luarocks.org
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ luarocks --no-project install inspect
inspect 3.1.3-0 depends on lua >= 5.1 (5.5-1 provided by VM: success)
No existing manifest. Attempting to rebuild...
inspect 3.1.3-0 is now installed in /opt/homebrew (license: MIT <http://opensource.org/licenses/MIT>)
Return type:

str

upgrade_one_cli(package_id, version=None)[source]

Generate the CLI to upgrade one package.

LuaRocks has no upgrade verb: installing a rock that is already present replaces it with the newer build, which is the upgrade.

$ luarocks --no-project install inspect
inspect 3.1.3-0 depends on lua >= 5.1 (5.5-1 provided by VM: success)
No existing manifest. Attempting to rebuild...
inspect 3.1.3-0 is now installed in /opt/homebrew (license: MIT <http://opensource.org/licenses/MIT>)
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

Acts on the default tree, so a rock held in another one is refused by name rather than removed, as covered in the class notes above.

$ luarocks --no-project remove inspect
Checking stability of dependencies in the absence of
inspect 3.1.3-0...

Removing inspect 3.1.3-0...
Removal successful.
Return type:

str

meta_package_manager.managers.mamba module

class meta_package_manager.managers.mamba.Mamba[source]

Bases: PackageManager

Conda-compatible package manager, reimplemented in C++.

Reaches the same channels conda does, resolving with libsolv behind a command line of its own rather than delegating to conda. It is wrapped on the same grounds as nala over apt: same archives, separate implementation. Since 2.0 it shares no code with conda at all, the Python executable of the 1.x line having been replaced by a dynamically linked build of micromamba.

Important

Every operation targets mamba’s currently active environment, which is base when none is activated. mpm neither activates nor switches environments: it inspects and mutates whatever mamba resolves from the inherited CONDA_PREFIX / CONDA_DEFAULT_ENV, exactly as a bare mamba call in the same shell would, and exactly as the conda wrapper does. Per-environment targeting is not supported yet.

Caution

Sharing that prefix with conda is why the two are serialized against each other. mamba takes a real lock on the environment and on every package cache directory for the length of a transaction, and conda honors none of them: its own locking covers the repodata cache alone. Running them at once corrupts rather than blocks, which upstream has closed as not planned (conda/conda#13037).

Note

No sync. Nothing in the command set refreshes the index on its own, the closest being clean --index-cache, which only forces a refetch on the next operation. The conda wrapper implements none either, so this is parity rather than a gap.

Warning

mamba upgrade does not exist: unlike conda, mamba never aliased it, and calling it exits non-zero on an unexpected argument. Upgrades go through update.

Documentation: mamba user guide.

Initialize cli_errors list.

name: str = 'Mamba'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://mamba.readthedocs.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.0.0'

The release that made mamba a standalone C++ program.

Chosen over the newer 2.9.0, where the inventory settled on one shape, so the floor does not exclude every release a user is realistically running: 2.9.0 is days old. installed() reads both shapes instead.

version_regexes: tuple[str, ...] = ('^(?P<version>\\d+\\.\\d+\\.\\d+\\S*)$',)

Search the bare version mamba reports.

$ mamba --version
2.9.0

Anchored at both ends because the output is the version and nothing else: mamba prints no program name to key on, unlike conda’s conda 24.5.0. The patterns are applied in multiline mode, so the anchors bind to the line.

property installed: Iterator[Package]

Fetch installed packages.

$ mamba list --json
{
    "log_history": [],
    "packages": [
        {
            "base_url": "https://conda.anaconda.org/conda-forge",
            "build_number": 2,
            "build_string": "h23cfdf5_2",
            "channel": "conda-forge",
            "dist_name": "libiconv-1.18-h23cfdf5_2",
            "md5": "4d5a7445f0b25b6a3ddbb56e790f5251",
            "name": "libiconv",
            "platform": "osx-arm64",
            "url": "https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.18-h23cfdf5_2.conda",
            "version": "1.18"
        }
    ]
}

Caution

Two payload shapes are accepted, and reading the wrong one is silent. 2.9.0 wrapped this array in an envelope carrying a log_history sibling, where every release before it printed the array bare, the way conda still does. Neither shape raises on the other’s reader: it simply finds no list and reports an empty inventory, so the array is located by shape rather than by a fixed path.

That same envelope is why success is read from the exit code and the presence of packages, never from the output parsing. Pointed at a prefix that does not exist, 2.9.0 exits non-zero with an empty stderr and tens of kilobytes of trace on stdout, as JSON that parses perfectly and holds no packages.

property outdated: Iterator[Package]

Fetch outdated packages.

mamba inherits conda’s lack of a dedicated outdated command, and its dry-run reports the same actions mapping, so the upgrade the solver would perform is simulated and its UNLINK (current) and LINK (candidate) sets are diffed by name. A package in both is an in-place upgrade; one in only LINK is a freshly pulled dependency and one in only UNLINK is a removal, so neither is reported.

$ mamba update --all --dry-run --json
{
    "actions": {
        "LINK": [
            {
                "build": "h23cfdf5_2",
                "fn": "libiconv-1.18-h23cfdf5_2.conda",
                "name": "libiconv",
                "version": "1.18"
            }
        ],
        "PREFIX": "/opt/conda",
        "UNLINK": [
            {
                "build": "h23cfdf5_1",
                "fn": "libiconv-1.17-h23cfdf5_1.conda",
                "name": "libiconv",
                "version": "1.17"
            }
        ]
    },
    "dry_run": true,
    "log_history": [],
    "prefix": "/opt/conda",
    "success": true
}

When the environment is already current, the actions key is omitted exactly as conda omits it:

$ mamba update --all --dry-run --json
{
    "dry_run": true,
    "log_history": [],
    "message": "All requested packages already installed",
    "prefix": "/opt/conda",
    "success": true
}

Note

repoquery was assessed for this and cannot answer it: it reads channels and installed metadata but never solves, so it cannot say what a transaction would do. Entries here also carry libmamba’s wider field set instead of conda’s, and no FETCH key, neither of which is read.

search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended matching, mamba exposing no package description to match against. Exact matching is native: a bare query resolves against the package name alone, where wrapping it in * widens it to a substring match.

$ mamba search "*zstd*" --json
{
    "log_history": [],
    "query": {
        "query": "*zstd*",
        "type": "search"
    },
    "result": {
        "msg": "",
        "pkgs": [
            {
                "build": "py313h7208f8c_0",
                "name": "backports.zstd",
                "version": "1.6.0"
            }
        ],
        "status": "OK"
    }
}

Caution

Results are a flat list under result.pkgs, not conda’s mapping of name to builds, so they are grouped here by name. The newest build of each group is picked by comparing versions rather than by position: mamba sorts descending where conda sorts ascending, and that order was a string comparison before 2.6.0, which misplaces 1.10 against 1.9. Comparing parsed versions is right whatever the release does.

A query matching nothing exits zero with an empty pkgs, unlike conda’s non-zero PackagesNotFoundError payload.

Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package, optionally pinned to a version.

mamba accepts a MatchSpec, so the version is appended with =.

$ mamba install --yes zstd
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ mamba update --all --yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ mamba update --yes zstd
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ mamba remove --yes zstd
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

$ mamba clean --all --yes
Return type:

None

cli_names: tuple[str, ...] = ('mamba',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'mamba'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.mamba.Micromamba[source]

Bases: Mamba

mamba’s statically linked build, shipped as a single self-contained binary.

The same program as mamba, built the other way: upstream’s build declares “mamba is a dynamic build of micromamba” and compiles both executables from one source list. Every operation, parser and forced argument is therefore inherited unchanged.

Note

The two are separate managers rather than one manager naming both binaries, because they resolve different root prefixes: mamba takes the conda installation it ships inside, while micromamba takes ~/micromamba or its XDG data directory. mpm resolves a manager to the first of its CLI names found while walking the search path, so a host carrying both would silently report whichever came first on PATH and hide the other’s packages entirely.

Note

Their command sets differ by exactly one entry: micromamba adds self-update, which the dynamic build rejects. It maps to no mpm operation, so nothing here uses it.

Initialize cli_errors list.

id: str = 'micromamba'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Micromamba'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://mamba.readthedocs.io/en/latest/user_guide/micromamba.html'

Home page of the project, only used in documentation for reference.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cli_names: tuple[str, ...] = ('micromamba',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

meta_package_manager.managers.mas module

class meta_package_manager.managers.mas.MAS[source]

Bases: PackageManager

mas drives the Mac App Store from the command line.

Packages are Mac App Store applications, keyed by the numeric adamID Apple assigns each title (the id in an App Store link). mpm reads and writes that ID; the display name rides along only as a label.

Every query reads --json output, the supported programmatic interface since the >=7.0.0 floor added --json to list, outdated and search. It sidesteps the column-alignment ambiguities of the tabular listing, where an app name carrying parentheses or padding whitespace would derail a positional parser.

Note

mas prints one JSON object per app, concatenated rather than wrapped in an array, and leaves control characters (embedded newlines, U+2028) unescaped inside name and description strings (mas-cli/mas#1248). mpm decodes the buffer one object at a time with strict=False so each object ends at its own closing brace instead of splitting on those bytes. The bug is fixed upstream for the (still unreleased) 7.1.0, so this workaround can be retired once the requirement floor rises to >=7.1.0.

Note

mas self-escalates: it asks for root itself when a store mutation needs it, so mpm never wraps install, upgrade or uninstall in its own sudo.

Initialize cli_errors list.

name: str = 'Mac App Store'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/mas-cli/mas'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'mas'

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='macos', name='macOS')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=7.0.0'

7.0.0 introduces the --json flag on config, list, lookup/info, outdated & search. Parsing structured JSON output is the supported programmatic interface: it sidesteps the column-alignment ambiguities of the tabular output (app names containing parentheses or extra whitespace would break the previous regex-based parser).

version_cli_options: tuple[str, ...] = ('version',)
$ mas version
7.0.0
brewfile_entry(package)[source]

Emit the app’s display name, with its numeric adamID as the id: keyword brew bundle installs from.

Returns None (silently skip) for any package whose ID is not such a number: without it the entry cannot round-trip, and a half-broken mas "Name" line would error at install time. See Snapshot and export, section “mas entries”.

property installed: Iterator[Package]

Fetch installed packages.

$ mas list --json
{"adamID":1569813296,"bundleID":"com.1password.1password-safari","name":"1Password for Safari","version":"2.3.5"}
{"adamID":1295203466,"bundleID":"com.microsoft.rdc.macos","name":"Microsoft Remote Desktop","version":"10.7.6"}
{"adamID":409183694,"bundleID":"com.apple.iWork.Keynote","name":"Keynote","version":"12.0"}
property outdated: Iterator[Package]

Fetch outdated packages.

$ mas outdated --json
{"adamID":409183694,"name":"Keynote","newVersion":"12.0","version":"11.0"}
{"adamID":1176895641,"name":"Spark","newVersion":"2.11.21","version":"2.11.20"}
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ mas search python --json
{"adamID":689176796,"name":"Python Runner","version":"1.3"}
{"adamID":630736088,"name":"Learning Python","version":"1.0"}
{"adamID":945397020,"name":"Run Python","version":"1.0"}
{"adamID":1164498373,"name":"PythonGames","version":"1.0"}
{"adamID":1400050251,"name":"Pythonic","version":"1.0.0"}
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ mas install 945397020
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ mas upgrade
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('mas',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'mas'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ mas upgrade 945397020
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Removes a package.

mas 4.1.0+ requests root privileges itself when not already running as root, so we don’t pre-wrap the call in sudo. This matches how install and upgrade are already invoked.

$ mas uninstall 1494051017
Password:
Uninstalled '/Applications/SimpleLogin.app' to '/Users/kde/.Trash/SimpleLogin.app'
Return type:

str

meta_package_manager.managers.miktex module

class meta_package_manager.managers.miktex.MiKTeX[source]

Bases: PackageManager

TeX package manager of the MiKTeX distribution.

Reaches MiKTeX’s own package repositories, which are distinct from the catalog tlmgr reaches for TeX Live: two distributions, two managers, rather than one wrapped twice.

Note

Linux and Windows only, and that follows the tool rather than a choice. The packages command arrived in MiKTeX 22.3, while the newest macOS build MiKTeX publishes is 22.1, which predates it. The only package surface on macOS is the standalone binary that happens to share this project’s name, which is reason enough never to reach for it.

Caution

--admin is deliberately never passed, and the reasoning inverts what its name suggests. Left alone, MiKTeX reports the packages installed for the user and those installed system-wide; the flag narrows that to the system-wide ones alone. The default is therefore already the wider listing, and passing it would drop rows rather than pin them. It is fatal outright on an installation that is not shared, and warns about privileges it may lack when run without them. The cost is that removing a system-wide package is out of reach, needing both that flag and administrator rights.

Important

Queries pass --disable-installer. MiKTeX installs packages on the fly by default, so without it reading the inventory is not guaranteed to leave the system as it found it.

Note

No outdated, though MiKTeX does have a non-mutating check: it prints bare package names and no version of any kind, where reporting something as outdated needs a version to report it against. The only route to one is asking after each package individually, thousands of invocations for a single answer. upgrade --all is unaffected.

No search, MiKTeX having no such command, and no cleanup: nothing in the package surface purges a cache or sweeps orphans.

Warning

The command that upgrades everything is update. MiKTeX’s upgrade is a different thing entirely, taking a package level such as basic or complete and erroring without one, so it is never used here.

Documentation: MiKTeX packages.

Initialize cli_errors list.

name: str = 'MiKTeX'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://miktex.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=22.3'

The release that introduced the packages command this drives.

version_regexes: tuple[str, ...] = ('\\(MiKTeX (?P<version>\\d+(?:\\.\\d+)*)',)

Search the release named in parentheses.

$ miktex --version
One MiKTeX Utility 1.12.0 (MiKTeX 26.5)

Two numbers share that line: the utility’s own version first, then the MiKTeX release, which is the one that means anything here. The parenthesis is what tells them apart. A word such as the build’s word size may follow the release, which the pattern stops before.

property installed: Iterator[Package]

Fetch installed packages.

$ miktex --disable-installer packages list --template "{isInstalled} {id} {version}"
true amsmath 2.17n
false zwpagelayout
true fancyhdr 4.0.3
install(package_id, version=None)[source]

Install one package.

$ miktex packages install fancyhdr
Return type:

str

Caution

MiKTeX fails outright when the package is already installed, rather than treating it as a no-op.

cli_names: tuple[str, ...] = ('miktex',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'miktex'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ miktex packages update
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Naming packages genuinely restricts the run to them, the rest being reported as already up to date.

$ miktex packages update fancyhdr
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ miktex packages remove fancyhdr
Return type:

str

Caution

MiKTeX fails outright when the package is not installed.

sync()[source]

Sync package metadata.

$ miktex packages update-package-database
Return type:

None

meta_package_manager.managers.mason module

meta_package_manager.managers.mason.MASON_ROOT = 'vim.fn.stdpath("data") .. "/mason"'

Lua expression resolving mason’s install root.

One directory per machine, holding bin, packages, registries and the rest. It is where a --clean process, loading none of the user’s configuration, has to look: unlike the plugin’s own checkout this path does not move with whichever plugin manager installed mason.

meta_package_manager.managers.mason.PLUGIN_CANDIDATES = ('"/lazy/mason.nvim"', '"/site/pack/*/*/mason.nvim"')

Globs, relative to Neovim’s data path, where mason’s own checkout may sit.

mason.nvim is a plugin like any other, so its location is decided by whatever installed it rather than by mason: lazy.nvim clones it under lazy, while the built-in package mechanism and the managers built on it use site/pack. Both are probed because a --clean process loads no configuration and therefore has nothing else to go on.

meta_package_manager.managers.mason.lua_command(body)[source]

Wrap a Lua body into the -c argument handed to Neovim.

The trailing os.exit(0) is the success path: it terminates Neovim before the failure gate in Mason.post_args can run.

Return type:

str

class meta_package_manager.managers.mason.Mason[source]

Bases: PackageManager

Installer of LSP servers, DAP adapters, linters and formatters for Neovim.

Important

mason is not a plugin manager, which is what separates it from Lazy and Vim_Pack. Those install Lua that runs inside the editor; mason installs ordinary developer tools, the same stylua or rust-analyzer binaries another host might get from Homebrew.

Note

Wrapping it is what makes those tools visible at all. mason redirects every backend it shells out to into the package’s own directory: a local npm install``rather than a global one, a``venv``per package,``cargo install –root .`,``GOBIN``and``GEM_HOME``pointed inside. So a``pyright` installed by mason appears in no other manager’s inventory, and without this wrapper mpm would not see it.

Caution

Reads and writes drive Neovim differently, and deliberately.

The inventory is read by a --clean process straight off mason’s own install tree, costing no plugin loading and immune to whatever the user’s configuration does. Mutations cannot work that way: MasonInstall and its siblings are user commands that exist only once mason is loaded, so those run without --clean and let the configuration supply them. That is mason’s own documented recipe for unattended use.

Note

Every mutating command blocks in headless mode rather than returning while work continues in the background: mason branches on #vim.api.nvim_list_uis() == 0 and runs the transaction synchronously, refusing an unknown package name up front instead of failing silently.

Warning

The install root is assumed to be mason’s default. A configuration moving install_root_dir elsewhere leaves the inventory empty, since finding the override would mean loading the very plugin the read path avoids.

Documentation: mason.nvim.

Initialize cli_errors list.

name: str = 'Neovim mason-nvim'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/mason-org/mason.nvim'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.0.0'

The release that reshaped mason’s API into the one described here.

2.0.0 removed the modules backing custom Lua packages, replaced the registry events, and raised the Neovim floor to 0.10.0. It is also the release the project moved to its own organization under, so it is the oldest version worth describing.

Caution

This floors mason, never the receipts it wrote. A host on a current mason still carries receipts from 1.x for anything installed back then, which is why installed() reads both of their shapes.

cli_names: tuple[str, ...] = ('nvim',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('--headless',)
post_args: tuple[str, ...] = ('-c', 'cquit')

Failure gate. Every Lua body exits on its own through lua_command(), and every mutation closes on qall, so reaching this means the command never got that far and the run is an error.

version_cli_options: tuple[str, ...] = ('--clean', '--headless', '-c', 'lua local d = vim.fn.stdpath("data") local c = vim.fn.glob(d .. "/lazy/mason.nvim", true, true) vim.list_extend(c, vim.fn.glob(d .. "/site/pack/*/*/mason.nvim", true, true)) for _, p in ipairs(c) do vim.opt.rtp:prepend(p) local ok, m = pcall(require, "mason.version") if ok then io.write("mason " .. m.VERSION) break end end os.exit(0)')

Self-contained probe: version detection skips Mason.pre_args and Mason.post_args, so this carries its own --headless and exits on its own.

Each candidate checkout is put on the runtime path only long enough to try loading mason from it, so a Neovim without mason prints nothing and exits successfully rather than raising. That silence is what leaves the manager unavailable on a host that merely has an editor, which matters here because lazy and vim-pack legitimately key on the same nvim binary.

id: str = 'mason'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

version_regexes: tuple[str, ...] = ('mason v?(?P<version>\\S+)',)

Search the version right after the mason string.

$ nvim --clean --headless \
> -c 'lua local d = vim.fn.stdpath("data") local c = vim.fn.glob(d .. "/lazy/mason.nvim", true, true) vim.list_extend(c, vim.fn.glob(d .. "/site/pack/*/*/mason.nvim", true, true)) for _, p in ipairs(c) do vim.opt.rtp:prepend(p) local ok, m = pcall(require, "mason.version") if ok then io.write("mason " .. m.VERSION) break end end os.exit(0)'
mason v2.3.1

The v is optional in the pattern because it belongs to mason’s own string rather than to the version: it is a tag name reported verbatim.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property installed: Iterator[Package]

Fetch installed packages.

mason writes a receipt beside every package it installs, and those receipts are the inventory: a --clean process reads them straight off the tree, so nothing has to be loaded and the user’s configuration cannot perturb the result.

A receipt carries no version field. It records the package’s source as a purl, and the version is the purl’s own version component, which is what mason itself reads back.

Caution

The source sits under source in a 2.0 receipt and under primary_source in every earlier one, exactly as mason’s own reader branches. Both are accepted here: the receipt’s schema version is fixed when the package is installed, so a current mason keeps serving 1.x receipts for anything installed under it, and reading only one shape would silently drop those packages instead of failing.

$ nvim --headless --clean \
> -c 'lua local root = vim.fn.stdpath("data") .. "/mason" .. "/packages" for _, dir in ipairs(vim.fn.glob(root .. "/*", true, true)) do local f = dir .. "/mason-receipt.json" if (vim.uv or vim.loop).fs_stat(f) then local ok, r = pcall(vim.json.decode, table.concat(vim.fn.readfile(f), "\n")) if ok and r and r.name then local s = r.source or r.primary_source io.write(r.name .. "\t" .. ((s and s.id) or "") .. "\n") end end end os.exit(0)' \
> -c 'cquit'
stylua  pkg:github/johnnymorganz/stylua@v2.5.2
install(package_id, version=None)[source]

Install one package.

Runs without --clean so the user’s configuration supplies the MasonInstall command, which mason documents as the way to drive it unattended.

$ nvim --headless -c 'MasonInstall stylua' -c 'qall' -c 'cquit'
Return type:

str

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

mason has no upgrade verb of its own: installing a package that is already present fetches whatever the registry currently offers, which is the upgrade.

$ nvim --headless -c 'MasonInstall stylua' -c 'qall' -c 'cquit'
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ nvim --headless -c 'MasonUninstall stylua' -c 'qall' -c 'cquit'
Return type:

str

sync()[source]

Sync package metadata.

MasonUpdate refreshes the registry index and upgrades nothing, which is exactly this operation. Its own description says so, and its body calls the registry update alone.

$ nvim --headless -c 'MasonUpdate' -c 'qall' -c 'cquit'
Return type:

None

meta_package_manager.managers.mise module

class meta_package_manager.managers.mise.Mise[source]

Bases: PackageManager

mise (formerly rtx) installs and switches between versions of developer tools like Node, Python, Ruby and any tool reachable through its plugin backends.

Note

mpm is system-scoped, so this wrapper reports every tool version present on disk regardless of which mise.toml (global or project) requested it. Project-pinned versions are not surfaced as a separate scope.

Note

Backend-prefixed tool IDs (pipx:ruff, cargo:ubi-cli, asdf:mise-plugins/mise-poetry) round-trip as-is. The colon is part of the package ID; mpm install pipx:ruff resolves the backend through mise itself.

Caution

mise outdated --json only reports tools tracked in a mise.toml (global or project). A tool installed bare with mise install <tool> and never pinned with mise use will not appear in the outdated list, so mpm outdated --mise understates the upgrade surface for those entries.

Initialize cli_errors list.

name: str = 'mise'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://mise.jdx.dev'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2025.5.10'

mise search shipped in 2025.5.10, the binding floor for the feature set this wrapper depends on. Earlier releases also miss the outdated --json fix from 2025.2.8 that emits valid JSON when no tool is outdated.

version_regexes: tuple[str, ...] = ('^(?P<version>\\d+\\.\\d+\\.\\d+)',)

mise uses CalVer (YYYY.M.P), not SemVer.

$ mise --version
2026.6.3 macos-arm64 (2026-06-13)
property installed: Iterator[Package]

Fetch installed packages.

Emits one meta_package_manager.package.Package per (tool, installed_version) pair, so a tool installed at multiple versions yields multiple entries sharing the same ID.

$ mise ls --installed --json
{
  "node": [
    {
      "version": "20.10.0",
      "install_path": "~/.local/share/mise/installs/node/20.10.0",
      "source": {"type": "mise.toml",
                 "path": "~/.config/mise/config.toml"}
    }
  ],
  "pipx:ruff": [
    {
      "version": "0.6.9",
      "install_path": "~/.local/share/mise/installs/pipx-ruff/0.6.9"
    }
  ]
}
property outdated: Iterator[Package]

Fetch outdated packages.

$ mise outdated --json
{
  "node": {
    "requested": "20",
    "current": "20.0.0",
    "latest": "20.10.0"
  }
}
search(query, extended, exact)[source]

Fetch matching packages.

mise search returns a two-column Tool  Description table. --match-type contains keeps the candidate set wide; the framework’s meta_package_manager.manager.PackageManager.refiltered_search() narrows it down to honor extended and exact flags.

$ mise search --no-header --match-type contains node
node                Node.js
node-build          Compile and install Node.js
nodejs              alias for node
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

mise install <tool> resolves to the latest version compatible with the active config; mise install <tool>@<version> pins it explicitly. Neither variant writes to mise.toml: the dedicated mise use command is the config-mutating verb and is deliberately avoided here.

$ mise install node@20
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ mise upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ mise upgrade node
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

mise uninstall <tool> errors when more than one version of the tool is installed. --all removes every installed version unconditionally, which matches mpm’s “remove this package” contract.

$ mise uninstall --all node
Return type:

str

sync()[source]

Refresh plugin metadata.

mise resolves tool listings and version catalogues through its plugins, so updating the plugins is the closest equivalent to the package-list refresh other managers perform during sync.

$ mise plugins update
Return type:

None

cleanup_cache()[source]

Clear mise’s download and metadata caches.

$ mise cache clear
Return type:

None

cli_names: tuple[str, ...] = ('mise',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'mise'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

$ mise doctor
Return type:

tuple[str, ...]

meta_package_manager.managers.nala module

class meta_package_manager.managers.nala.Nala[source]

Bases: PackageManager

Front-end to Debian’s apt, driving libapt-pkg directly.

Nala reaches the same archives apt does, adding a parallel downloader, a mirror-scoring fetcher and a transaction history it can roll back. It is wrapped on the same grounds as the AUR helpers that sit over pacman: a distinct tool with a vocabulary of its own, rather than a translation layer over another CLI. It shares dpkg’s lock with the rest of that family, so mpm runs it serially against them.

Important

Every invocation forces LC_ALL=C, and it is doing two jobs at once. Nala translates its own output at runtime, so a French host reports est installé``where the parsers expect``is installed; and it picks its tree glyphs from the encoding of its output stream. The same flag that pins the language to the untranslated strings also selects the ASCII glyphs, giving one stable shape to parse instead of a matrix of locale and encoding.

Caution

A listing is a record of three lines, not a line per package: a header naming the package and its version, a branch giving its status, and another carrying its description. That is why this is a class rather than a declarative definition, and why outdated correlates two lines to pair an installed version with the candidate it can move to.

Note

Nala’s own upgrade takes no package arguments at all, accepting only exclusions, so naming a package cannot restrict it. Upgrading one package therefore goes through install, which moves an already-installed package to its candidate version, exactly as apt does.

Documentation: nala.

Initialize cli_errors list.

name: str = 'Nala'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://gitlab.com/volian/nala'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Nala checks for root and exits with a message rather than escalating on its own, so mpm supplies the privilege for the operations that mutate.

requirement: str | None = '>=0.12.2'

The oldest release still shipped by a supported distribution, and the floor from which the listing format is unchanged: its emitting code is byte-identical from there through the newest release.

extra_env: ClassVar = {'LC_ALL': 'C'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_regexes: tuple[str, ...] = ('nala\\s+(?P<version>\\S+)',)

Search the version right after the nala string.

$ nala --version
nala 0.16.0
property installed: Iterator[Package]

Fetch installed packages.

$ nala list --installed
vim 2:8.2.3995-1+b2 [Debian/sid main]
+-- is installed
`-- Vi IMproved - enhanced vi editor
property outdated: Iterator[Package]

Fetch outdated packages.

The two versions sit on different lines: the header carries the installed one, and the status branch names the candidate.

$ nala list --upgradable
vim 2:8.2.3995-1+b2 [Debian/sid main]
+-- is installed and upgradable to 2:8.2.4659-1
`-- Vi IMproved - enhanced vi editor
search(query, extended, exact)[source]

Fetch matching packages.

The query is a regular expression as far as nala is concerned, so mpm’s own refiltering narrows whatever comes back.

Caution

Search does not support extended or exact matching.

$ nala search vim
Return type:

Iterator[Package]

cli_names: tuple[str, ...] = ('nala',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'nala'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

install(package_id, version=None)[source]

Install one package.

$ sudo nala install --assume-yes firefox
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ sudo nala upgrade --assume-yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Routed through install, since nala’s own upgrade accepts no package arguments and would upgrade everything. Installing a package already present moves it to its candidate version.

$ sudo nala install --assume-yes firefox
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ sudo nala remove --assume-yes firefox
Return type:

str

sync()[source]

Sync package metadata.

$ sudo nala update
Return type:

None

cleanup_orphan()[source]

Removes packages nothing depends on anymore.

$ sudo nala autoremove --assume-yes
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore.

$ sudo nala clean
Return type:

None

meta_package_manager.managers.nimble module

class meta_package_manager.managers.nimble.Nimble[source]

Bases: PackageManager

Nimble, the package manager of the Nim language.

A package is a Nim library or binary, identified by the bare name the registry publishes it under.

Caution

The inventory forces --ver, and that flag is the whole difference between a useful listing and a misleading one. Without it nimble list --installed prints package names and nothing else, so every package would be reported with no version at all while looking perfectly healthy. Upstream tracked the flag being ignored as nim-lang/nimble#1469, closed as completed; the fix is what sets the requirement floor below.

Note

Both listings open with a three-line legend describing the format, whose own lines look exactly like the records that follow: a :PackageName: placeholder where a name goes, and a └── @{Version} (...) placeholder where a version goes. Both parsers therefore demand a real value, refusing the brace-wrapped placeholders, rather than skipping a fixed number of header lines that a future release could renumber.

Note

Records span two lines, a name followed by one indented line per version held, which is what makes this a class rather than a bundled definition. Nimble keeps several versions of a package side by side, so the versions are reduced here to the newest per name.

Note

No outdated: Nimble has no command reporting which installed packages have newer releases.

No upgrade either, and that is a deliberate reading rather than an oversight. nimble upgrade is documented as upgrading “a list of packages in the lock file”, which is a project operation on a nimble.lock and not something that acts on the machine. Installing a package again does fetch the newest release, but Nimble adds it beside the version already held rather than replacing it, so reporting that as an upgrade would misstate what happened.

Documentation: Nimble README.

Initialize cli_errors list.

name: str = 'Nimble'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/nim-lang/nimble'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.22.0'

First release carrying the fix that makes list --installed --ver print versions: nim-lang/nimble#1469 was closed on 2025-09-18, between v0.20.1 and v0.22.0.

pre_args: tuple[str, ...] = ('--noColor', '--accept')

Strip styling so the parsers see plain text, and pre-answer the prompts.

--accept is not cosmetic: uninstall asks “Do you wish to continue?” and blocks forever without it.

version_regexes: tuple[str, ...] = ('nimble[ \\t]+v(?P<version>\\S+)',)

Search the version right after the nimble v string.

$ nimble --version
nimble v0.22.2 compiled at 2026-04-24 03:34:24
git hash: couldn't determine git hash
cli_names: tuple[str, ...] = ('nimble',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'nimble'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property installed: Iterator[Package]

Fetch installed packages.

$ nimble --noColor --accept list --installed --ver
Package list format:
{PackageName}
└── @{Version} ({CheckSum})[Special Versions (if any)] ({InstallPath})
parsetoml
├── @0.7.2 (2a9fb57ef1f6460fd61b1cfab2d83af44f788a25) (/Users/kde/.nimble/pkgs2/parsetoml-0.7.2-2a9fb57ef1f6460fd61b1cfab2d83af44f788a25)
└── @0.7.1 (586fe63467a674008c4445ed1b8ac882177d7103) (/Users/kde/.nimble/pkgs2/parsetoml-0.7.1-586fe63467a674008c4445ed1b8ac882177d7103)
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching, and reports no version: Nimble’s records carry a URL, tags, a description, a license and a website, but nothing identifying a release.

$ nimble --noColor --accept search parsetoml
parsetoml:
  url:         https://github.com/NimParsers/parsetoml.git (git)
  tags:        library, parse
  description: Library for parsing TOML files.
  license:     MIT
  website:     https://github.com/NimParsers/parsetoml
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ nimble --noColor --accept install checksums
Downloading https://github.com/nim-lang/checksums using git
      Info: using /opt/homebrew/Cellar/nim/2.2.10/nim/bin/nim for compilation
Return type:

str

remove(package_id)[source]

Remove one package.

$ nimble --noColor --accept uninstall checksums
    Looking for checksums (any version)
   Checking reverse dependencies
    Prompt: The following packages will be removed:
        ... checksums-0.2.2-6357ab195ec23e0e0a54d4d8b5e0212456bf899e
        ... Do you wish to continue? -> [forced yes]
    Removed checksums-0.2.2-6357ab195ec23e0e0a54d4d8b5e0212456bf899e
Return type:

str

sync()[source]

Sync package metadata.

$ nimble --noColor --accept refresh
Downloading Official package list
    Success Package list downloaded.
Return type:

None

meta_package_manager.managers.nix module

class meta_package_manager.managers.nix.Nix[source]

Bases: PackageManager

Nix, the functional package manager.

Note

All operations use the imperative nix-env interface, which manages a per-user package profile. Declarative approaches (NixOS modules, home-manager) are not covered.

Channel refresh (sync) and store garbage collection (cleanup) shell out to the sibling nix-channel and nix-collect-garbage binaries installed alongside nix-env, not to nix-env itself.

Initialize cli_errors list.

homepage_url: str | None = 'https://nixos.org'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cli_names: tuple[str, ...] = ('nix-env',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

version_regexes: tuple[str, ...] = ('nix-env \\(Nix\\) (?P<version>\\S+)',)
$ nix-env --version
nix-env (Nix) 2.18.1
property installed: Iterator[Package]

Fetch installed packages.

$ nix-env --query --installed
hello-2.12.1
nix-2.18.1
python3-3.11.6
property outdated: Iterator[Package]

Fetch outdated packages.

$ nix-env --query --upgradeable --compare-versions
hello-2.12.1 < 2.13.0
python3-3.11.6 < 3.12.0
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

Caution

nix-env --query --available evaluates the full nixpkgs set and can be slow on first invocation.

$ nix-env --query --available --attr-path --description 'hello'
nixpkgs.hello  hello-2.12.1  A program that produces a friendly greeting
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ nix-env --install hello
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ nix-env --upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ nix-env --upgrade hello
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ nix-env --uninstall hello
Return type:

str

sync()[source]

Update Nix channel metadata.

$ nix-channel --update
Return type:

None

cleanup_cache()[source]

Remove old generations and garbage-collect the Nix store.

$ nix-collect-garbage --delete-old
Return type:

None

id: str = 'nix'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Nix'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.npm module

class meta_package_manager.managers.npm.NPM[source]

Bases: PackageManager

The Node.js package manager.

mpm drives npm in global mode: every call forces --global so packages land in the shared prefix instead of the current working directory. Per-scope targeting and multi-binary discovery (several node versions through nvm) are tracked in #1725. Command equivalences with the sibling JS managers are listed in antfu-collective/ni.

Queries parse npm’s --json output. Mutating operations are marked privileged so --sudo can escalate writes into a root-owned global prefix, though escalation stays dormant unless requested.

Note

npm enforces a supply-chain cooldown through its min-release-age resolver option, refusing to resolve any release younger than the configured age. The version floor exists for it: min-release-age first shipped in 11.10.0, and older releases silently ignore the setting.

Caution

A fatal npm error (usually a local node version out of sync) is reported both on <stderr> and as a JSON blob on <stdout>. The run_cli override blanks that JSON so the failure surfaces once, through <stderr>, rather than being parsed as a package listing.

Initialize cli_errors list.

name: str = 'Node npm'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.npmjs.com'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

brewfile_entry_type: ClassVar[str | None] = 'npm'

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=11.10.0'

11.10.0 is the first version to ship min-release-age, the purpose-built release-age gate mpm uses for the supply-chain cooldown (see cooldown_env_var). Older npm releases silently ignore the env var, so the floor avoids advertising a gate that does nothing.

cooldown_env_var: ClassVar[str | None] = 'npm_config_min-release-age'

npm honors a release-age cooldown through its min-release-age resolver option.

npm maps any npm_config_<key> environment variable to a config setting, so npm_config_min-release-age sets min-release-age without touching the user’s .npmrc. Once set, npm refuses to resolve any package version younger than the configured age, which covers install and update along with their transitive dependencies. The hyphenated env var passes cleanly through Python’s subprocess.Popen env= mapping (shells that reject export foo-bar=baz are not involved).

The cooldown_env_value() method below is overridden to emit an integer number of days, the unit min-release-age expects.

See npm’s min-release-age config.

pre_args: tuple[str, ...] = ('--global', '--no-progress', '--no-update-notifier', '--no-fund', '--no-audit')
$ npm --version
6.13.7
cooldown_env_value()[source]

Render meta_package_manager.execution.CLIExecutor.cooldown as an integer day count for npm’s min-release-age.

Sub-day cooldowns round up so the gate over-protects rather than silently collapses to 0 (the “no cooldown” sentinel).

Return type:

str

run_cli(*args, **kwargs)[source]

Like the common run_cli helper, but silence NPM’s JSON output on error.

NPM is prone to breakage if local node version is not in sync:

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json outdated
{
  "error": {
    "code": "ERR_OUT_OF_RANGE",
    "summary": "The value of "err" is out of range. Received 536870212",
    "detail": ""
  }
}
Return type:

str

property installed: Iterator[Package]

Fetch installed packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json --depth 0 list
{
  "name": "lib",
  "dependencies": {
    "@eslint/json": {
      "version": "0.9.0",
      "overridden": false
    },
    "@mermaid-js/mermaid-cli": {
      "version": "10.8.0",
      "overridden": false
    },
    "corepack": {
      "version": "0.30.0",
      "overridden": false
    },
    "google-closure-compiler": {
      "version": "20240317.0.0",
      "overridden": false
    },
    "npm": {
      "version": "10.9.2",
      "overridden": false
    },
    "raven": {
      "version": "2.6.4",
      "overridden": false
    },
    "wrangler": {
      "version": "3.51.2",
      "overridden": false
    }
  }
}
property outdated: Iterator[Package]

Fetch outdated packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             --json outdated
{
  "my-linked-package": {
    "current": "0.0.0-development",
    "wanted": "linked",
    "latest": "linked",
    "location": "/Users/kev/dev/my-linked-package"
  },
  "npm": {
    "current": "3.10.3",
    "wanted": "3.10.5",
    "latest": "3.10.5",
    "location": "/opt/homebrew/lib/node_modules/npm"
  }
}
search(query, extended, exact)[source]

Fetch matching packages.

Doc: npm search.

Caution

Search does not supports exact matching.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             search --json python | jq
[
  {
    "name": "python",
    "description": "Interact with a python child process",
    "maintainers": [
      {
        "username": "drderidder",
        "email": "drderidder@gmail.com"
      }
    ],
    "version": "0.0.4",
    "date": "2015-01-25T02:48:07.820Z"
  },
  {
    "name": "raven",
    "description": "A standalone (Node.js) client for Sentry",
    "maintainers": [
      {
        "username": "benvinegar",
        "email": "ben@benv.ca"
      },
      {
        "username": "lewisjellis",
        "email": "me@lewisjellis.com"
      },
      {
        "username": "mattrobenolt",
        "email": "m@robenolt.com"
      },
      {
        "username": "zeeg",
        "email": "dcramer@gmail.com"
      }
    ],
    "keywords": [
      "raven",
      "sentry",
      "python",
      "errors",
      "debugging",
      "exceptions"
    ],
    "version": "1.1.2",
    "date": "2017-02-09T02:54:07.723Z"
  },
  {
    "name": "brush-python",
    "description": "Python brush module for SyntaxHighlighter.",
    "maintainers": [
      {
        "username": "alexgorbatchev",
        "email": "alex.gorbatchev@gmail.com"
      }
    ],
    "keywords": [
      "syntaxhighlighter",
      "brush",
      "python"
    ],
    "version": "4.0.0",
    "date": "2016-02-07T21:32:39.597Z"
  },
  (...)
]
$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             search --json --no-description python | jq
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             install markdown

added 3 packages in 3s
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             upgrade raven
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('npm',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'npm'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package and one only.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             uninstall raven
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Removes things we don’t need anymore.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             cache clean --force
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

doctor checks the registry connectivity, the node and npm versions, the ownership of the global folders and the cache checksums, exiting non-zero when any check fails.

$ npm --global --no-progress --no-update-notifier --no-fund --no-audit             doctor
Return type:

tuple[str, ...]

meta_package_manager.managers.oh_my_fish module

meta_package_manager.managers.oh_my_fish.omf_source_path()[source]

Locate the init.fish file every invocation sources.

Oh My Fish installs itself into $OMF_PATH, falling back to ~/.local/share/omf when the variable is unset, as its own installer does. The path is returned whether or not it exists, so the built command stays well-formed and simply fails to source, which is what makes the version probe double as Oh My Fish’s presence check.

Return type:

Path

class meta_package_manager.managers.oh_my_fish.OhMyFish[source]

Bases: PackageManager

Oh My Fish is a framework and plugin manager for the Fish shell.

Packages are cloned under $OMF_PATH and recorded in the user’s bundle file. Oh My Fish manages two kinds of package, plugins and themes, and reports both from one listing: mpm yields them together, since a name is unique across the two and every mutating command takes either.

Caution

omf is a Fish function, not a standalone binary: it is defined by sourcing $OMF_PATH/init.fish, so it cannot serve as the manager’s CLI. Every invocation is therefore wrapped in fish -c. Fish is the binary mpm executes, and Oh My Fish’s own presence is established by the version probe: a host with Fish but no Oh My Fish fails to source and reports no version, which leaves the manager unavailable.

Note

No outdated: Oh My Fish compares nothing against its remotes short of performing the update. upgrade --all still works, and mpm auto-skips the operation.

Note

No search: omf search exists and would map cleanly, but its results are printed by a private __omf.cli.search.output helper whose format no upstream sample pins down, so declaring it would mean guessing at a parser.

Documentation: Oh My Fish.

Initialize cli_errors list.

id: str = 'oh-my-fish'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Fish Oh My Fish'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/oh-my-fish/oh-my-fish'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=6.0.0'

The 6.x series is where this command set settled.

omf list, omf install, omf remove and the package-scoped omf update all predate it, but 6.0.0 is the release that moved the framework to $OMF_PATH with the init.fish entry point this manager sources.

cli_names: tuple[str, ...] = ('fish',)

Fish is the binary mpm actually executes.

Oh My Fish is a shell function defined by an init.fish file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable. Keying the manager on Fish instead makes the version probe the presence check.

extra_env: ClassVar = {'NO_COLOR': '1'}

Oh My Fish underlines its section headers through Fish’s set_color, which NO_COLOR disables so the listing parses as clean text.

version_regexes: tuple[str, ...] = ('Oh My Fish version (?P<version>\\S+)',)

Oh My Fish derives what it reports from git describe –tags –match ‘v*’ –always`, with the leading``v` cut off, so a checkout sitting on a release tag reports that release and one ahead of it reports a describe string.

$ fish -c 'source ~/.local/share/omf/init.fish; and omf --version'
Oh My Fish version 7
build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Fish shell Oh My Fish needs.

The version probe is guarded by a readability test that exits successfully when init.fish is absent, so a host that merely has Fish installed does not turn into a manager reporting errors. An init.fish that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the fish -c wrapper and Oh My Fish never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

Oh My Fish pipes both of its listings through column, so packages arrive several per line in a layout that depends on the terminal width, under an underlined Plugins and Themes header. Every token that is not one of those two headers is a package name: names carry no whitespace, which is what makes splitting on it sound.

No version is reported for any of them: a package is a Git clone tracking a branch, and Oh My Fish records no revision per package.

$ fish -c 'source ~/.local/share/omf/init.fish; and omf list'
Plugins
bang-bang     brew          fish-spec     osx
percol        pyenv         tab           z

Themes
agnoster      bobthefish    default       scorphish

The block above is an illustration rather than a harvested fixture: the column layout is computed from the terminal width, so no sample can be byte-accurate across hosts.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

install(package_id, version=None)[source]

Install one package.

A theme is additionally set as the active one by Oh My Fish itself, which is its own behavior and not something mpm asks for.

$ omf install z
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

Note

A bare omf update also updates the Oh My Fish core, which is the manager rather than a package. The core is left in, deliberately: unlike Antidote’s --bundles, Oh My Fish offers no flag to scope an update to packages only, and naming every package instead would race the listing.

$ omf update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

Naming a package keeps the core out of the update: Oh My Fish only refreshes itself when omf is one of the names passed.

$ omf update z
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ omf remove z
Return type:

str

meta_package_manager.managers.pacman module

class meta_package_manager.managers.pacman.Pacman[source]

Bases: PackageManager

Arch Linux’s native package manager, covering the official repositories.

mpm forces --noconfirm and --color never on every call so pacman runs unattended and prints uncolored text the regexes can parse. Installed packages come from --query and upgradable ones from --query --upgrades; searches hit the sync databases via --sync --search.

The Pacaur, Paru and Yay subclasses are AUR helpers that reuse every parser and forced argument here unchanged, overriding only the binary (and, for yay, adding a release-age cooldown).

Command equivalences with other managers are listed in Pacman/Rosetta.

Caution

--query --upgrades only reports updates for packages tracked in a sync database, so foreign packages (installed with pacman -U, as AUR helpers do) stay invisible to the base pacman binary. The subclasses escape this because their own binary also queries the AUR RPC. This upstream behavior is not confirmed on a live Arch box: see Pacman.outdated().

Initialize cli_errors list.

name: str = 'Arch Linux pacman'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://wiki.archlinux.org/title/pacman'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

Annotated with the base class’s own union so a subclass may widen it: DkpPacman ships for macOS too.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=5.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('--noconfirm', '--color', 'never')
version_regexes: tuple[str, ...] = ('.*Pacman\\s+v(?P<version>\\S+)',)

Search version right after the Pacman string.

$ pacman --version

 .--.                  Pacman v6.0.1 - libalpm v13.0.1
/ _.-' .-.  .-.  .-.   Copyright (C) 2006-2021 Pacman Development Team
\  '-. '-'  '-'  '-'   Copyright (C) 2002-2006 Judd Vinet
 '--'
                    This program may be freely redistributed under
                    the terms of the GNU General Public License.
property installed: Iterator[Package]

Fetch installed packages.

$ pacman --noconfirm --query
a52dec 0.7.4-11
aalib 1.4rc5-14
abseil-cpp 20211102.0-2
accountsservice 22.08.8-2
acl 2.3.1-2
acme.sh 3.0.2-1
acpi 1.7-3
acpid 2.0.33-1
property outdated: Iterator[Package]

Fetch outdated packages.

$ pacman --noconfirm --query --upgrades
linux 4.19.1.arch1-1 -> 4.19.2.arch1-1
linux-headers 4.19.1.arch1-1 -> 4.19.2.arch1-1

Note

pacman --query --upgrades (-Qu) only reports updates for packages tracked in a sync database (official repos, plus any local repo configured in pacman.conf). Foreign packages, those installed with pacman -U as most AUR helpers do, are invisible to -Qu and surface only under -Qm.

The Pacaur, Paru and Yay subclasses inherit this method verbatim, yet still see AUR updates because their own binary’s -Qu additionally queries the AUR RPC for foreign packages. The per-subclass binary override is therefore load-bearing: routing these helpers through pacman directly would silently drop every AUR update from the results.

Caution

This follows upstream -Qu semantics but has not been confirmed on a live Arch box. Before relying on it, verify that yay --query --upgrades invoked through mpm actually surfaces a pending AUR update.

property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

Same <name> <version> listing shape as installed(), narrowed by --deps --unrequired (-Qtd) to the orphan set.

$ pacman --noconfirm --color never --query --deps --unrequired
gtest 1.14.0-1
libwlroots 0.16.2-2
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not supports extended matching.

$ pacman --noconfirm --sync --search fire
extra/dump_syms 0.0.7-1
    Symbol dumper for Firefox
extra/firefox 99.0-1
    Standalone web browser from mozilla.org
extra/firefox-i18n-ach 99.0-1
    Acholi language pack for Firefox
extra/firefox-i18n-af 99.0-1
    Afrikaans language pack for Firefox
extra/firefox-i18n-an 99.0-1
    Aragonese language pack for Firefox
extra/firefox-i18n-ar 99.0-1
    Arabic language pack for Firefox
extra/firefox-i18n-ast 99.0-1
    Asturian language pack for Firefox
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo pacman --noconfirm --color never --sync firefox
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade the package provided as parameter.

$ sudo pacman --noconfirm --color never --sync --refresh --sysupgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ sudo pacman --noconfirm --color never --sync firefox
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

$ sudo pacman --noconfirm --color never --remove firefox
Return type:

str

remove_orphan(package_id)[source]

Remove a package together with its now-orphaned dependencies.

--recursive (-s) additionally removes the dependencies the package pulled in that no other installed package needs.

$ sudo pacman --noconfirm --color never --remove --recursive firefox
Return type:

str

sync()[source]

Sync package metadata.

$ sudo pacman --noconfirm --color never --sync --refresh
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore.

$ sudo pacman --noconfirm --color never --sync --clean --clean
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

--database --check (-Dk) verifies the consistency of the local package database, silent and exit-0 when everything is fine.

$ pacman --noconfirm --color never --database --check
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('pacman',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pacman'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pacman.DkpPacman[source]

Bases: Pacman

devkitPro’s pacman fork, covering the console homebrew toolchains.

devkitPro ships its own pacman build under the dkp-pacman name so it can sit beside a distribution’s own pacman without colliding, pointed at the devkitPro repositories holding the devkitARM, devkitA64 and devkitPPC toolchains and the libraries built against them.

Every operation, parser and forced argument is inherited from Pacman unchanged: the fork tracks upstream closely enough that its version banner still comes from the same printf(" .--.    Pacman v%s - libalpm v%s") call, so the inherited Pacman.version_regexes reads it as-is.

Unlike the AUR helpers below this one is not a helper at all but pacman itself, so it keeps the default_sudo inherited from Pacman.

Documentation: devkitPro pacman.

Initialize cli_errors list.

id: str = 'dkp-pacman'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'devkitPro pacman'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/devkitPro/pacman'

Home page of the project, only used in documentation for reference.

No mark of its own, and Arch’s would misattribute a devkitPro tool: the manager page keeps the default package glyph instead.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

devkitPro publishes dkp-pacman for Linux and for macOS, the latter through the devkitpro-pacman-installer.pkg of its releases. Its Windows path installs the toolchains through MSYS2’s own pacman instead, which is a different binary this manager does not claim.

requirement: str | None = '>=6.0.0'

The series aligned with upstream pacman 6, which every parser inherited here was written against. devkitPro’s own v1.0.x releases of 2020 predate that alignment and are excluded deliberately.

cli_names: tuple[str, ...] = ('dkp-pacman',)

The binary is deliberately prefixed upstream so it never shadows a distribution’s own pacman; the class name would otherwise resolve to dkppacman.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pacman.Pacaur[source]

Bases: Pacman

AUR helper wrapping pacman, driven through the pacaur binary.

Inherits every operation, parser and forced argument from Pacman; only the binary and version probe differ. Routing through pacaur is what lets --query --upgrades report AUR updates on top of the official repositories.

Unlike pacman, the helper must run as the regular user: it aborts under root (you cannot perform this operation as root) because makepkg refuses to build as root, and it invokes sudo pacman itself for the privileged steps. mpm therefore never wraps it in sudo.

Initialize cli_errors list.

unmaintained: bool = True

A manager whose upstream project is no longer maintained.

Covers projects that are officially retired and those we infer are abandoned: archived on their forge, left without a release or commit for years, formally superseded by a successor, or part of a discontinued platform. See the stability policy in CLAUDE.md for the full criteria.

An unmaintained manager is hidden from package selection by default (you can still use it by explicitly calling for it on the command line), and is exempt from the project stability policy: it may be dropped, in part or in full, in any release and without notice, once keeping it working becomes too burdensome.

Unmaintained managers are kept out of the functional and integration test matrices, so an unreliable or flaky one never blocks a release and we save CI resources. The commitment is to keep the wrapper for as long as that stays cheap: the cheap static invariants (ID format, attribute ordering, …) still apply for as long as the manager’s code lives in the source tree, to keep that code valid.

Every unmaintained manager must document itself through unmaintained_message.

unmaintained_message: str | None = 'The [original pacaur repository is archived](https://github.com/rmarquis/pacaur) (last commit 2018) and the [E5ten fork](https://github.com/E5ten/pacaur) has had no commits since 2021; migrate to `paru` or `yay`.'

Evidence and rationale for the unmaintained flag, as a MyST markdown block.

Rendered into the documentation (the manager’s page, and a ⚠️ marker in the manager tables). May embed markdown links to the archival notice, the successor project, or the discontinuation announcement. Required for every manager whose unmaintained flag is set, and only meaningful on such managers. Enforced by test_unmaintained.

name: str = 'Arch Linux pacaur'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/E5ten/pacaur'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

default_sudo: bool = False

pacaur aborts its sync-class operations under root and runs sudo pacman itself, so the escalation default inherited from Pacman must not wrap it.

internal_sudo: bool = True

pacaur calls sudo pacman from inside its own commands for the install, upgrade and removal steps.

requirement: str | None = '>=4.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

version_regexes: tuple[str, ...] = ('pacaur\\s+(?P<version>\\S+)',)

Search version right after the pacaur string.

$ pacaur --version
pacaur 4.8.6
cli_names: tuple[str, ...] = ('pacaur',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pacaur'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pacman.Paru[source]

Bases: Pacman

AUR helper wrapping pacman, driven through the paru binary.

Inherits every operation, parser and forced argument from Pacman; only the binary and version probe differ. Its own --query --upgrades reports AUR updates on top of the official repositories. The >=1.9.3 floor is the first paru release to implement --sysupgrade, the flag the inherited upgrade_all_cli builds.

Unlike pacman, the helper must run as the regular user: any transaction building AUR packages aborts under root (can’t install AUR package as root`), and paru invokes``sudo pacman` itself for the privileged steps. mpm therefore never wraps it in sudo.

Initialize cli_errors list.

name: str = 'Arch Linux paru'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/Morganamilo/paru'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

default_sudo: bool = False

paru refuses to build AUR packages under root and runs sudo pacman itself, so the escalation default inherited from Pacman must not wrap it.

internal_sudo: bool = True

paru calls sudo from inside its own commands (the Sudo/SudoFlags settings of paru.conf) for the install, upgrade and removal steps.

requirement: str | None = '>=1.9.3'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

version_regexes: tuple[str, ...] = ('paru\\s+v(?P<version>\\S+)',)

Search version right after the paru string.

$ paru --version
paru v1.10.0 - libalpm v13.0.1
cli_names: tuple[str, ...] = ('paru',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'paru'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pacman.Pikaur[source]

Bases: Pacman

AUR helper wrapping pacman, driven through the pikaur binary.

Inherits every operation, parser and forced argument from Pacman; the binary, the version probe and the release floor are what differ. Its own --query --upgrades reports AUR updates on top of the official repositories.

Like the other helpers, pikaur must run as the regular user: makepkg refuses to build as root, and pikaur drives sudo pacman itself for the privileged steps. mpm therefore never wraps it in sudo.

Note

pikaur wraps pacman’s options faithfully except –sync –refresh –sysupgrade``(`-Syu`), which it splits into a refresh pass and an upgrade pass so a user can amend the package selection in between. The inherited Pacman.upgrade_all_cli() still builds the combined form, and the --noconfirm forced by Pacman.pre_args is what keeps that split unattended.

Documentation: pikaur.

Initialize cli_errors list.

name: str = 'Arch Linux pikaur'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/actionless/pikaur'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

default_sudo: bool = False

pikaur builds AUR packages through makepkg, which hard-refuses to run as root, and calls sudo pacman itself, so the escalation default inherited from Pacman must not wrap it.

internal_sudo: bool = True

pikaur calls sudo pacman from inside its own commands for the install, upgrade and removal steps.

requirement: str | None = '>=1.0.0'

pikaur versions independently of pacman, so the inherited >=5.0.0 would reject every release it has ever made.

The floor sits at the start of the 1.x series because nothing this class relies on is newer than it: the wrapped pacman option set and the Pikaur v version banner both predate it, and the parsers are pacman’s own.

version_regexes: tuple[str, ...] = ('.*Pikaur\\s+v(?P<version>\\S+)',)

Search version right after the Pikaur string.

Anchoring on Pikaur rather than the inherited Pacman pattern is load-bearing: pikaur reports both versions, embedding the second line of pacman --version in its own output, so the inherited regex would silently report the version of pacman instead.

$ pikaur --version
Pikaur v1.33.3
Pacman v6.0.2 - libalpm v13.0.2 - pyalpm v0.10.6

The real banner side-joins those lines with an ASCII-art mascot, which is why the block above is an illustration rather than a harvested fixture: the .* prefix is what absorbs the art. Both forms are emitted by the same print_version() of pikaur/print_department.py, the quiet one verbatim.

cli_names: tuple[str, ...] = ('pikaur',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pikaur'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pacman.Trizen[source]

Bases: Pacman

AUR helper wrapping pacman, driven through the trizen binary.

Inherits every operation, parser and forced argument from Pacman; the binary, the version probe and the release floor are what differ. Its own --query --upgrades reports AUR updates on top of the official repositories.

Like the other helpers, trizen must run as the regular user: makepkg refuses to build as root, and trizen calls sudo pacman itself for the privileged steps. mpm therefore never wraps it in sudo.

Note

Upstream is slow rather than stopped: commits continue, but 1.68 of December 2022 is still the newest release. It stays unflagged here because the stability policy keys unmaintained on an abandoned upstream, not on a quiet release cadence.

Documentation: trizen.

Initialize cli_errors list.

name: str = 'Arch Linux trizen'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/trizen/trizen'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

cli_names: tuple[str, ...] = ('trizen',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

default_sudo: bool = False

trizen builds AUR packages through makepkg, which hard-refuses to run as root, and calls sudo pacman itself, so the escalation default inherited from Pacman must not wrap it.

id: str = 'trizen'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

internal_sudo: bool = True

trizen calls sudo pacman from inside its own commands for the install, upgrade and removal steps.

requirement: str | None = '>=1.0.0'

trizen versions independently of pacman, so the inherited >=5.0.0 would reject every release it has ever made. Nothing this class relies on is newer than the 1.x series: the parsers are pacman’s own.

version_regexes: tuple[str, ...] = ('trizen\\s+(?P<version>\\S+)',)

Search version right after the trizen string.

$ trizen --version
trizen 1.68
class meta_package_manager.managers.pacman.Yay[source]

Bases: Pacman

AUR helper wrapping pacman, driven through the yay binary.

Inherits every operation, parser and forced argument from Pacman; the binary, version probe and the release-age cooldown below are what differ. Its own --query --upgrades reports AUR updates on top of the official repositories.

Unlike pacman, the helper must run as the regular user: yay warns under root (Avoid running yay as root/sudo.) and any AUR build then dies in makepkg, which refuses to run as root. yay drives sudo itself for the privileged steps (its --sudo, --sudoflags and --sudoloop options), so mpm never wraps it in sudo. That also keeps the injected XDG_CONFIG_HOME cooldown overlay below visible to yay, where a sudo wrap would have reset the environment.

Note

yay exposes no release-age flag, so mpm enforces the supply-chain cooldown by overlaying a generated init.lua through a private XDG_CONFIG_HOME (see Yay.cooldown_env()). This needs yay >= 13.0.0, when the Lua UpgradeSelect/AURPreInstall hooks landed; an older yay stays a usable manager but cannot honor a cooldown. The upstream request for a less invasive injection point is Jguer/yay#2883.

Initialize cli_errors list.

cli_names: tuple[str, ...] = ('yay',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'yay'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

name: str = 'Arch Linux yay'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/Jguer/yay'

Home page of the project, only used in documentation for reference.

Annotated so a subclass may drop the mark: DkpPacman is a pacman fork that Arch’s logo would misattribute.

default_sudo: bool = False

yay discourages root runs (makepkg hard-refuses them for AUR builds) and drives sudo itself, so the escalation default inherited from Pacman must not wrap it. A wrap would also strip the XDG_CONFIG_HOME cooldown overlay through sudo’s environment reset.

internal_sudo: bool = True

yay calls the escalation binary from inside its own commands, configurable through its --sudo, --sudoflags and --sudoloop options.

requirement: str | None = '>=11.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cooldown_env_var: ClassVar[str | None] = 'XDG_CONFIG_HOME'

yay reads no release-age option of its own, so mpm repurposes XDG_CONFIG_HOME to point yay at the throwaway config overlay built by cooldown_env().

Unlike the single-value variables of pip/uv/npm, the value is a directory; the cutoff itself rides alongside it in MPM_COOLDOWN_EPOCH. Set so the structural supports_cooldown check (and the --cooldown help text) still recognize yay as cooldown-capable.

version_regexes: tuple[str, ...] = ('yay\\s+v(?P<version>\\S+)',)

Search version right after the yay string.

$ yay --version
yay v11.1.2 - libalpm v13.0.1
cooldown_requirement = '>=13.0.0'

Minimum yay version whose Lua hooks the cooldown overlay relies on.

v13.0.0 introduced yay.create_autocmd and the UpgradeSelect/AURPreInstall events. Kept apart from requirement (>=11.0.0) so a v11/v12 yay stays fully usable for everything except the cooldown.

property supports_cooldown: bool

Whether this yay can natively enforce a release-age cooldown.

Reports the structural capability while idle (cooldown is None) so the import-time COOLDOWN_SUPPORTED_MANAGERS help text stays I/O-free, and only probes the manager version once a cooldown is active, gating on cooldown_requirement. A yay older than that (or undetectable) reports no support, so the fail-closed default skips install/upgrade rather than running them unguarded.

cooldown_env()[source]

Deliver the release-age cooldown through a private XDG_CONFIG_HOME.

yay has no release-age option, so rather than injecting a single value mpm points yay at _cooldown_overlay_dir: a throwaway config tree whose generated init.lua (_YAY_COOLDOWN_INIT_LUA) registers the cooldown Lua hooks. The cutoff travels as MPM_COOLDOWN_EPOCH (Unix seconds of now - cooldown), keeping the init.lua asset static, and MPM_YAY_USER_DIR lets it chain the user’s real config so the redirect stays lossless.

Returns an empty mapping when no cooldown is set or the installed yay predates the Lua hooks (see supports_cooldown).

Return type:

Mapping[str, str | None]

meta_package_manager.managers.pacstall module

class meta_package_manager.managers.pacstall.Pacstall[source]

Bases: PackageManager

AUR-inspired, source-based package manager for Ubuntu and other Linux distributions.

Pacstall builds packages from “pacscripts” and installs the results as .deb archives through dpkg. mpm forces NO_COLOR and DISABLE_PROMPTS so output is uncolored and every call stays non-interactive.

pacstall self-escalates: every privileged subcommand re-execs the script through sudo pacstall (its elevate() function), and its documented invocation is unprefixed (pacstall -I foo). mpm therefore never wraps it and marks it internal_sudo instead: a warm sudo credential cache is kept alive for its mid-run re-exec, and the hidden-prompt watchdog covers the cold-cache case.

Note

Listing installed packages is a two-step probe: piped --list prints bare names with no versions, so mpm follows each with a --cache-info <pkg> version call to recover its version.

Note

--search matches names only and reports no versions. There is no per-package upgrade verb either, so upgrading one package reinstalls it through --install.

Initialize cli_errors list.

homepage_url: str | None = 'https://pacstall.dev'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

internal_sudo: bool = True

Marks a manager whose CLI invokes sudo itself mid-run.

Homebrew cask runs it from installer artifacts, fink re-execs its root commands through it, and the AUR helpers call sudo pacman for their install steps. mpm never wraps such a manager’s commands: either none of its operations carry a build_cli(..., sudo=True) marker (cask, fink), or its default_sudo = False policy leaves the markers it inherits unescalated (the AUR helpers). Running the tool under sudo is often forbidden outright (brew refuses root, makepkg refuses to build). Consumed by prime_sudo(), whose opportunistic probe keeps an already-warm credential cache alive for these internal escalations, and by the silent-call notice in run(), which flags a possibly-hidden password prompt on a cold cache.

Forcing sudo = true on such a manager (config key or --sudo) still never wraps its commands, but does promote it into the up-front prompt path of prime_sudo().

requirement: str | None = '>=6.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

extra_env: ClassVar = {'DISABLE_PROMPTS': '1', 'NO_COLOR': '1'}

Suppress ANSI colors and disable interactive prompts.

version_regexes: tuple[str, ...] = ('(?P<version>\\d+\\.\\d+\\.\\d+)',)
$ pacstall --version
6.3.7 Vanilla
property installed: Iterator[Package]

Fetch installed packages.

$ pacstall --list
neofetch
neovim

Note

When piped, pacstall --list outputs bare package names without versions. A follow-up pacstall --cache-info <pkg> version call retrieves the installed version per package.

property outdated: Iterator[Package]

Fetch outdated packages.

$ pacstall --list-upgrades
Upgradable: 2
    neofetch @ pacstall-programs#master ( 7.1.0-2 -> 7.2.0-1 )
    neovim @ pacstall-programs#master ( 0.9.4-1 -> 0.10.0-1 )
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching, and does not provide version information. Returns the best subset of results and lets meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ pacstall --search neovim
neovim @ pacstall-programs
neovim-git @ pacstall-programs
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ pacstall --install neofetch
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ pacstall --upgrade
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package by reinstalling it.

$ pacstall --install neofetch
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('pacstall',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pacstall'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Pacstall'

Return package manager’s common name.

Default value is based on class name.

remove(package_id)[source]

Remove one package.

$ pacstall --remove neofetch
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Sync package metadata from remote repositories.

$ pacstall --update
Return type:

None

meta_package_manager.managers.pip module

class meta_package_manager.managers.pip.Pip[source]

Bases: PackageManager

The pip package installer for Python, driven as a module (python -m pip) rather than through the pip executable.

Calling the module through the interpreter lets pip upgrade itself, an advantage on Windows in particular: see why you should use python -m pip.

Installed and outdated packages are read from pip’s list --format=json output. The outdated query adds --not-required to report only top-level packages, since upgrading a transitive dependency can break its parent’s version constraints (#1214). There is no search: PyPI disabled its server-side search API in 2020 under unmanageable load, so pip search no longer works (see pypa/pip#5216).

Note

All operations target the default pip scope (system site-packages, or the active virtualenv). Per-scope targeting (system vs user vs venv) and multi-binary discovery (multiple pythons via pyenv) are tracked in #1725.

Note

Interpreter discovery probes the running Python first, so an mpm installed inside a virtualenv manages that virtualenv, then the Python(s) on PATH. Two kinds are skipped so the manager only targets a scope the user can install into: mpm’s own distributor-managed bundle (Homebrew stages it under a Cellar prefix) and any externally-managed, non-virtualenv interpreter that PEP 668 forbids pip install into. When every candidate is skipped, the manager reports as unavailable.

Note

Installs, upgrades and removals are marked privileged, so a global install can escalate with --sudo, but escalation is off by default. The supply-chain cooldown needs pip 26.1, the first release to honor --uploaded-prior-to; older pip silently ignores the release-age gate.

Initialize cli_errors list.

name: str = 'Python pip'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://pip.pypa.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=26.1.0'

26.1 is the first version to ship --uploaded-prior-to, the release-age gate mpm uses for the supply-chain cooldown (see cooldown_env_var). Older pip releases silently ignore PIP_UPLOADED_PRIOR_TO, so the floor avoids advertising a gate that does nothing.

cooldown_env_var: ClassVar[str | None] = 'PIP_UPLOADED_PRIOR_TO'

pip honors a release-age cooldown through its --uploaded-prior-to resolver option.

pip maps any PIP_<UPPER_SNAKE> environment variable to a config setting, so PIP_UPLOADED_PRIOR_TO sets the option without touching the user’s pip.conf. The flag excludes from resolution any distribution uploaded after the given instant, which covers install and upgrade (with transitive dependencies). pip parses the RFC 3339 timestamp produced by the default meta_package_manager.execution.CLIExecutor.cooldown_env_value().

See pypa/pip#13674.

cli_names: tuple[str, ...] = ('python3', 'python')

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('-m', 'pip', '--no-color')
version_cli_options: tuple[str, ...] = ('-m', 'pip', '--no-color', '--version')

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('pip\\s+(?P<version>\\S+)',)
$ python -m pip --no-color --version
pip 2.0.2 from /usr/local/lib/python/site-packages/pip (python 3.7)
search_all_cli(cli_names, env=None)[source]

Yield the Python interpreters the pip manager may target.

The running interpreter is probed first, so an mpm installed into a virtualenv manages that virtualenv’s own packages, then the Python(s) found on PATH. Two kinds of interpreter are skipped, so the pip manager only ever targets a scope the user can actually install into:

  • mpm’s own distributor-managed bundle (see _running_from_bundled_app()), and

  • any externally-managed, non-virtualenv interpreter PEP 668 would forbid pip install into (see _pip_install_blocked()).

When every candidate is skipped the manager is left with no cli_path and reports as unavailable, which is correct: there is no user-managed pip environment to act on.

Todo

Evaluate findpython (the maintained MIT rewrite of pythonfinder) to replace the discovery loop here. It would only cover discovery: the eligibility filters (_running_from_bundled_app(), _pip_install_blocked()) stay mpm’s job, since findpython locates interpreters but does not judge whether pip install is allowed into one.

Return type:

Generator[Path, None, None]

property version: TokenizedString | None[source]

Print Python’s own version before Pip’s.

This gives much more context to the user about the environment when a Python executable is found but Pip is not.

Runs:

$ python --version --version
Python 3.10.10 (Feb  8 2023, 05:34) [Clang 14.0.0 (clang-1400.0.29.202)]
property installed: Iterator[Package]

Fetch installed packages.

$ python -m pip --no-color list --format=json --verbose --quiet
[
 {
    "version": "1.3",
    "name": "backports.functools-lru-cache",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
  },
  {
    "version": "0.9999999",
    "name": "html5lib",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
  },
  {
    "name": "setuptools",
    "version": "46.0.0",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": ""
  },
  {
    "version": "2.8",
    "name": "Jinja2",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": ""
  }
]
package_metadata_batch(packages)[source]

Enrich installed pip packages via importlib.metadata.

Each installed distribution exposes its METADATA file (the Core Metadata from PEP 621) plus RECORD, WHEEL, and INSTALLER files in its .dist-info directory. This method reads them in-process: no shell-outs, no network, fast enough to enumerate hundreds of distributions in a fraction of a second.

Maps Home-page / Project-URL lines into the portable homepage / vcs_url / issue_tracker_url slots, walks Requires-Dist into typed meta_package_manager.package.Dependency edges, and promotes the upstream author or maintainer to meta_package_manager.package.Originator.

Return type:

Iterator[tuple[Package, PackageMetadata]]

property outdated: Iterator[Package]

Fetch outdated packages.

Note

The --not-required flag filters out transitive dependencies, restricting results to top-level packages only. Upgrading transitive dependencies can break version constraints of their parent packages. See #1214.

$ python -m pip --no-color list --format=json --outdated         > --not-required --verbose --quiet
[
  {
    "latest_filetype": "wheel",
    "version": "0.7.9",
    "name": "alabaster",
    "latest_version": "0.7.10",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
  },
  {
    "latest_filetype": "wheel",
    "version": "0.9999999",
    "name": "html5lib",
    "latest_version": "0.999999999",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
   },
  {
    "latest_filetype": "wheel",
    "version": "2.8",
    "name": "Jinja2",
    "latest_version": "2.9.5",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
   },
  {
    "latest_filetype": "wheel",
    "version": "0.5.3",
    "name": "mccabe",
    "latest_version": "0.6.1",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
   },
  {
    "latest_filetype": "wheel",
    "version": "2.2.0",
    "name": "pycodestyle",
    "latest_version": "2.3.1",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": "pip"
   },
  {
    "latest_filetype": "wheel",
    "version": "2.1.3",
    "name": "Pygments",
    "latest_version": "2.2.0",
    "location": "/usr/local/lib/python3.7/site-packages",
    "installer": ""
   }
]
install(package_id, version=None)[source]

Install one package.

$ python -m pip --no-color install arrow
Collecting arrow
  Using cached arrow-1.1.1-py3-none-any.whl (60 kB)
Collecting python-dateutil>=2.7.0
  Using cached python_dateutil-2.8.2-py2.py3-none-any.whl (247 kB)
Requirement already satisfied: six>=1.5 in python3.9/site-packages (1.16.0)
Installing collected packages: python-dateutil, arrow
Successfully installed arrow-1.1.1 python-dateutil-2.8.2
Return type:

str

id: str = 'pip'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ python -m pip --no-color install --upgrade six
Collecting six
  Using cached six-1.15.0-py2.py3-none-any.whl (10 kB)
Installing collected packages: six
  Attempting uninstall: six
    Found existing installation: six 1.14.0
    Uninstalling six-1.14.0:
      Successfully uninstalled six-1.14.0
Successfully installed six-1.15.0
Return type:

tuple[str, ...]

Note

Pip lacks support of a proper full upgrade command. Raising an error let the parent class upgrade packages one by one.

See pypa/pip#59.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Remove one package.

$ python -m pip --no-color uninstall --yes arrow
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

$ python -m pip --no-color cache purge
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

check verifies that installed packages have compatible dependencies, reporting conflicts on <stdout> and exiting non-zero on any.

$ python -m pip --no-color check
No broken requirements found.
Return type:

tuple[str, ...]

meta_package_manager.managers.pipx module

class meta_package_manager.managers.pipx.Pipx[source]

Bases: PackageManager

pipx installs Python CLI applications, each in its own isolated venv.

Installed applications come from pipx list --json; only each venv’s main package is tracked, never the packages injected beside it. There is no search operation: the request was closed as not planned, since PyPI exposes no search API and custom search is out of pipx’s scope (see pypa/pipx#777).

Note

The outdated query prefers pipx 1.16.0’s native pipx list --outdated, which checks every venv in one call, each against its own backend (pip or uv). An older pipx falls back to probing each venv with its embedded pip, one call per application. The version floor stays at 1.0.0 so an older pipx remains fully usable: only the outdated path degrades.

Note

The supply-chain cooldown rides on the underlying pip and needs that pip to be at least 26.1, the first release to honor --uploaded-prior-to; older pip silently ignores the release-age gate.

Initialize cli_errors list.

name: str = 'Python pipx'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://pipx.pypa.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.0.0'
$ pipx --version
1.0.0
cooldown_env_var: ClassVar[str | None] = 'PIP_UPLOADED_PRIOR_TO'

pipx defers resolution to pip, so it honors pip’s --uploaded-prior-to gate through the same environment variable.

Setting PIP_UPLOADED_PRIOR_TO on a pipx invocation propagates to the pip subprocess pipx spawns to install the application and its dependencies, so the cutoff applies to the whole resolution. mpm injects the RFC 3339 timestamp from the default meta_package_manager.execution.CLIExecutor.cooldown_env_value().

Caution

Same caveat as meta_package_manager.managers.pip.Pip: the underlying pip must be at least 26.1 for the gate to take effect. Older pip releases silently ignore the env var.

See pypa/pipx#1811.

outdated_requirement = '>=1.16.0'

Minimum pipx version providing the native outdated query.

1.16.0 introduced pipx list --outdated (see pypa/pipx#149). Kept apart from requirement (>=1.0.0) so an older pipx stays fully usable, outdated falling back to one pip probe per venv.

property installed: Iterator[Package]

Fetch installed packages.

$ pipx list --json
{
  "pipx_spec_version": "0.1",
  "venvs": {
      "pycowsay": {
        "metadata": {
          "injected_packages": {},
          "main_package": {
            "app_paths": [
              {
                "__Path__": "~/.local/pipx/venvs/pycowsay/bin/pycowsay",
                "__type__": "Path"
              }
            ],
            "app_paths_of_dependencies": {},
            "apps": [
              "pycowsay"
            ],
            "apps_of_dependencies": [],
            "include_apps": true,
            "include_dependencies": false,
            "package": "pycowsay",
            "package_or_url": "pycowsay",
            "package_version": "0.0.0.1",
            "pip_args": [],
            "suffix": ""
          },
        "pipx_metadata_version": "0.2",
        "python_version": "Python 3.10.4",
        "venv_args": []
      }
    }
  }
}
property outdated: Iterator[Package]

Fetch outdated packages.

pipx 1.16.0 introduced a native outdated query, which checks all venvs in a single call, each against its own backend (pip or uv). Injected packages are excluded by default, so only each venv’s main package is reported. Pinned packages are kept: a newer release exists, even if pipx upgrade skips them.

$ pipx list --outdated --output=json
{
  "command": ["list"],
  "data": {
    "packages_checked": 1,
    "packages": [
      {
        "environment": "pycowsay",
        "package": "pycowsay",
        "version": "0.0.0.1",
        "latest_version": "0.0.0.2",
        "injected": false,
        "pinned": false
      }
    ],
    "skipped": []
  },
  "errors": [],
  "exit_code": 0,
  "pipx_result_version": "1",
  "status": "success"
}

A pipx older than outdated_requirement falls back to probing each venv with its embedded pip, one call per package. Only the venv’s main package is reported; its dependencies also show up in pip list --outdated but are silenced:

$ pipx runpip pycowsay list --no-color --format=json --outdated         > --verbose --quiet
[
  {
    "name": "pycowsay",
    "version": "0.0.0.1",
    "location": "~/.local/pipx/venvs/pycowsay/lib/python3.10/site-packages",
    "installer": "pip",
    "latest_version": "0.0.0.2",
    "latest_filetype": "wheel"
  }
]

Todo

Drop the fallback, which mimics Pip.outdated(), once pipx 1.16.0 is old enough to be required outright.

install(package_id, version=None)[source]

Install one package.

$ pipx install pycowsay
installed package pycowsay 0.0.0.1, installed using Python 3.10.4
These apps are now globally available
    - pycowsay
done! ✨ 🌟 ✨
Return type:

str

cli_names: tuple[str, ...] = ('pipx',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pipx'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_all_cli()[source]

Upgrade all packages.

Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Upgrade the package provided as parameter.

Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ pipx uninstall pycowsay
uninstalled pycowsay! ✨ 🌟 ✨
Return type:

str

meta_package_manager.managers.pixi module

class meta_package_manager.managers.pixi.Pixi[source]

Bases: PackageManager

pixi installs conda packages, either into a project workspace or machine-wide as global tools.

mpm is system-scoped, so this wrapper drives the pixi global scope alone and never touches a pixi.toml workspace. Global tools resolve from conda channels, conda-forge by default, and land in their own prefix under $PIXI_HOME.

Documentation: pixi global tools.

Important

pixi isolates each global tool in its own environment, and mpm keys packages on the environment name, not on the conda package names inside it. The environment is the unit every mutating pixi global verb addresses: uninstall deletes one whole environment and update refreshes one whole environment, neither taking a package name. pixi global install <pkg> names the environment after the package, so for everything mpm installs the two are the same string and every operation round-trips.

Keying on the inner dependencies instead was tried and is unsafe: it reports packages that remove cannot address one at a time, so removing one of them deletes the whole environment and silently takes its siblings with it.

Caution

An environment holding more than the package it is named after, built with pixi global install <pkg> --with <other> or pixi global add, is therefore reported as the single package <pkg>. Its extra packages are invisible to mpm, and removing <pkg> destroys them along with the environment, which is exactly what a bare pixi global uninstall <pkg> does. mpm neither widens nor narrows that behavior.

Note

An environment whose dependencies do not include the package it is named after reports no version. That is the same signal pixi’s own listing gives: it prints <name>: <version> inline only while the environment resolves to its eponymous package, and drops the version once the contents diverge.

Caution

No search operation is declared, though pixi search exists. Its --json mode cannot be capped: the flag conflicts_with_all the --limit and --limit-packages options that bound the human view, and outside a workspace pixi falls back to Platform::all() and queries every known conda subdir, roughly thirty of them, which is exactly how mpm runs it. Repodata carries no summary or description either, so the results would be name-only. Declaring nothing lets mpm skip the manager during a search rather than stall on it.

Bounding it means passing --platform, which would put a host-to-conda-subdir mapping in mpm that pixi already owns, and an empty result set is an error rather than an empty document, so reviving search is a deliberate piece of work rather than a one-line addition.

Caution

No outdated operation is declared: nothing in pixi global reports upgradable packages without performing the upgrade. pixi global update has no dry-run mode, and the request for a dedicated command (prefix-dev/pixi#6279) was closed pointing at the workspace-scoped pixi update --dry-run, which does not cover the global scope. upgrade --all is unaffected and maps to the native bare pixi global update.

Note

No sync operation either, despite the name of pixi global sync: that command reconciles installed environments against the manifest, installing and removing to match it, rather than refreshing package metadata from the channels. Mapping mpm sync onto it would make a read-shaped command mutate the machine.

Initialize cli_errors list.

name: str = 'pixi'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://pixi.sh'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.65.0'

0.65.0 is where pixi global list gained the --json flag this wrapper reads (prefix-dev/pixi#5530), and it is the binding floor. Every other operation is far older: install dates to 0.0.4, list to 0.3.0, and uninstall / update to the 0.33.0 rewrite that rebuilt pixi global around its manifest. That same rewrite is why nothing below 0.33.0 would work anyway: pixi global remove meant uninstall back then, and now means removing one dependency from an environment.

pre_args: tuple[str, ...] = ('--color=never', '--no-progress')

Both are global options, accepted ahead of any subcommand.

pixi colorizes its listings semantically and draws progress bars while solving. Each turns itself off when the matching stream is not a terminal, but mpm asks explicitly rather than relying on redirection. The version probe runs with auto_pre_args=False and so stays a bare pixi --version.

version_regexes: tuple[str, ...] = ('^pixi\\s+(?P<version>\\S+)',)
$ pixi --version
pixi 0.48.0
property installed: Iterator[Package]

Fetch installed packages.

The document is an array of environments, each carrying the explicit specs it was created from. Transitive dependencies are not listed, which is what makes this an inventory of tools rather than of everything on disk. Each environment yields exactly one package, keyed on the environment name, and its version is read from the dependency of the same name. A version is null for a package the manifest declares but that is not installed in the prefix, and the optional platform key is omitted unless the environment pins one.

The block below is source-derived: its layout follows pixi’s serde_json::to_string_pretty serialization of GlobalEnvironmentJson, and its values are those of the ripgrep entry in pixi’s own pixi global list reference output.

$ pixi --color=never --no-progress global list --json
[
  {
    "name": "ripgrep",
    "dependencies": [
      {
        "name": "ripgrep",
        "version": "14.1.0"
      }
    ],
    "exposed": [
      {
        "exposed_name": "rg",
        "executable": "rg"
      }
    ]
  }
]
install(package_id, version=None)[source]

Install one package.

The positional argument is a conda MatchSpec, so a version is pinned by appending ==<version> to the name rather than through a flag.

$ pixi --color=never --no-progress global install hyperfine
$ pixi --color=never --no-progress global install hyperfine==1.20.0
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

Bare pixi global update updates every environment: there is no --all flag. It also prunes stale environments on the way through.

$ pixi --color=never --no-progress global update
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('pixi',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pixi'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

pixi global update takes environment names and accepts no version at all, so a pinned upgrade is not expressible: mpm warns and upgrades to whatever the channels resolve to.

Routing a pinned upgrade through pixi global install <pkg>==<version> instead was tried and rejected. That verb takes a package spec rather than an environment name, and creates the environment when it is missing, so pinning a package that lives inside a differently-named environment forks a second environment holding a second copy and reports success, leaving the original untouched.

$ pixi --color=never --no-progress global update hyperfine
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Remove one package.

pixi global uninstall removes a whole environment, deleting its prefix outright, which is the counterpart of the pixi global install that created it and matches the unit installed() reports. An environment carrying co-installed extras loses those too.

The sibling pixi global remove is deliberately not used: it drops one dependency from an environment and leaves the environment behind, which would strand an entry mpm still reports as installed.

$ pixi --color=never --no-progress global uninstall hyperfine
Return type:

str

cleanup_cache()[source]

Clear pixi’s download caches.

--yes is required: with no cache-type flag, pixi clean cache asks for confirmation on <stdin> and would otherwise block forever under mpm.

$ pixi --color=never --no-progress clean cache --yes
Return type:

None

meta_package_manager.managers.pkcon module

class meta_package_manager.managers.pkcon.Pkcon[source]

Bases: PackageManager

PackageKit’s console client.

Documentation: PackageKit/PackageKit.

pkcon is an unprivileged client handing transactions to the packagekitd daemon over D-Bus, with the distro’s native backend (apt, dnf, zypp, alpm, …) doing the real work. Escalation is polkit’s job, so no operation is marked sudo: under a strict polkit policy, unattended mutations need a policy permitting them without interactive authentication.

Note

pkcon renders packages as a fused name-version.arch (repo) string and never exposes the raw name;version;arch;repo ID. Names and versions both legitimately contain dashes, so the name/version split below anchors on the first dash followed by a digit: a documented heuristic, not an exact science.

Initialize cli_errors list.

name: str = 'PackageKit'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.freedesktop.org/software/PackageKit/'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.7.0'

All the commands and flags used here (--plain, --noninteractive, --filter) are present since PackageKit 0.7.0.

extra_env: ClassVar = {'LC_ALL': 'C'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

post_args: tuple[str, ...] = ('--plain',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

version_regexes: tuple[str, ...] = ('^(?P<version>[\\d.]+)$',)
$ pkcon --version
1.3.6
property installed: Iterator[Package]

Fetch installed packages.

$ pkcon get-packages --filter installed --plain
Installed    gzip-1.12-1.fc38.x86_64 (koji-override-0)
Installed    hello-2.12.1-2.fc38.x86_64 (fedora)
property outdated: Iterator[Package]

Fetch outdated packages.

Result lines carry the update type as their status word (Security, Bug fix, Enhancement, Normal, …) and the version of the pending update.

Caution

With nothing to update, pkcon prints There are no updates available at this time.``and exits``5``(``PK_EXIT_CODE_NOTHING_USEFUL): a normal empty result, not a failure, so the error recorded for it is discarded.

$ pkcon get-updates --plain
Security     curl-8.0.1-2.fc38.x86_64 (updates)
Normal       hello-2.12.2-1.fc38.x86_64 (updates)
search(query, extended, exact)[source]

Fetch matching packages.

$ pkcon search name hello --plain
Available    hello-2.12.1-2.fc38.x86_64 (fedora)
Installed    rubygem-mixlib-shellout-3.2.7-3.fc38.noarch (fedora)
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ pkcon install --noninteractive hello --plain
Return type:

str

cli_names: tuple[str, ...] = ('pkcon',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pkcon'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

Note

With nothing to upgrade this exits 5 (“nothing useful was done”), which the best-effort maintenance flow reports as a failed manager but never as a non-zero mpm exit.

$ pkcon update --noninteractive --plain
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ pkcon update --noninteractive hello --plain
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ pkcon remove --noninteractive hello --plain
Return type:

str

sync()[source]

Refresh the cached repository metadata.

$ pkcon refresh --plain
Return type:

None

meta_package_manager.managers.pkg module

FreeBSD package managers.

Two managers share this module because they share the FreeBSD ecosystem and the same on-disk install database:

  • PKG wraps the binary pkg frontend, which fetches pre-compiled artifacts from the official FreeBSD repository.

  • Ports wraps the source-build workflow rooted at /usr/ports, driving make recipes directly and delegating registry queries back to pkg.

References:

meta_package_manager.managers.pkg.PORTS_TREE = PosixPath('/usr/ports')

Canonical location of the FreeBSD ports tree.

The Handbook documents this path as the convention; PORTSDIR can override it, but every tool and consumer in the wild assumes this default.

class meta_package_manager.managers.pkg.PKG[source]

Bases: PackageManager

FreeBSD’s binary pkg frontend, fetching pre-compiled artifacts from the official FreeBSD repository.

Only root may modify the package database, so mutating operations escalate through sudo by default, like the Ports sibling.

Note

outdated parses pkg upgrade --dry-run rather than pkg version, because only the dry-run names the target version each package would move to.

Caution

sync forces IGNORE_OSVERSION=yes: a package built for a newer FreeBSD than the running kernel would otherwise trigger an interactive confirmation that hangs the subprocess. It is passed as a -o command-line option rather than an environment variable, which sudo’s environment reset would strip from the escalated call. Support for that setting is also why the version floor is 1.11.

Initialize cli_errors list.

name: str = 'FreeBSD pkg'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/freebsd/pkg'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='freebsd', name='FreeBSD')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=1.11'

1.11 is the first version to support the IGNORE_OSVERSION setting.

$ pkg --version
1.20.9
pre_args: tuple[str, ...] = ('--quiet',)
property installed: Iterator[Package]

Fetch installed packages.

$ pkg query "%n %v %c"
7-zip 21.07_2 Console version of the 7-Zip file archiver
ap24-mod_mpm_itk 2.4.7_2 Run each vhost under a separate uid and gid
apache24 2.4.57 Version 2.4.x of Apache web server
aquantia-atlantic-kmod 0.0.5_1 Aquantia AQtion (Atlantic) Network Driver
arcconf 3.07.23971,1 Adaptec SCSI/SAS RAID administration tool
areca-cli-amd64 1.14.7.150519,1 Command Line Interface for ARC-xxxx RAID
base64 1.5_1 Utility to encode and decode base64 files
bash 5.1.12 GNU Project's Bourne Again SHell
beadm 1.4_1 Solaris-like utility to manage Boot Environments on ZFS
property outdated: Iterator[Package]

Fetch outdated packages.

$ pkg upgrade --dry-run
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Checking for upgrades (312 candidates): 100%
Processing candidates (312 candidates): 100%
The following 466 package(s) will be affected (of 0 checked):

Installed packages to be REMOVED:
    freenas-files: 13.0_1700495253
    py39-midcli: 20190509171453
    py39-middlewared: 13.0_1700495253

New packages to be INSTALLED:
    abseil: 20230125.3 [FreeBSD]
    argp-standalone: 1.5.0 [FreeBSD]
    brotli: 1.1.0,1 [FreeBSD]

Installed packages to be UPGRADED:
    7-zip: 21.07_2 -> 23.01 [FreeBSD]
    apache24: 2.4.57 -> 2.4.58_1 [FreeBSD]
    apr: 1.7.0.1.6.1_1 -> 1.7.3.1.6.3_1 [FreeBSD]
    aquantia-atlantic-kmod: 0.0.5_1 -> 0.0.5_2 [FreeBSD]
    bash: 5.1.12 -> 5.2.21 [FreeBSD]

Note

We rely on pkg upgrade instead of pkg version because the latter does not provides the new version:

$ pkg version --like "<"
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
7-zip-21.07_2                      <
apache24-2.4.57                    <
apr-1.7.0.1.6.1_1                  <
aquantia-atlantic-kmod-0.0.5_1     <
bash-5.1.12                        <
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

--dry-run turns autoremove into a read-only report of the would-be-removed packages.

$ pkg --quiet autoremove --dry-run
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 2 packages:

Installed packages to be REMOVED:
    libiconv: 1.17
    pcre: 8.45_3

Number of packages to be removed: 2
search(query, extended, exact)[source]

Fetch matching packages.

Default search on ID substring:

$ pkg search --raw --raw-format json-compact --search name nginx
{
    "name": "nginx",
    "version": "1.24.0_14,3",
    "comment": "Robust and small WWW server",
    (...)
}
{
    "name": "nginx-devel",
    "version": "1.25.3_9",
    "comment": "Robust and small WWW server",
    (...)
}
{
    "name": "nginx-ultimate-bad-bot-blocker",
    "version": "4.2020.03.2005_1",
    "comment": "Nginx bad bot and other things blocker",
    (...)
}
{
    "name": "p5-Nginx-ReadBody",
    "version": "0.07_1",
    "comment": "Nginx embedded perl module to read a request",
    (...)
}
(...)

Exact search on ID:

$ pkg search --raw --raw-format json-compact --search name --exact nginx
{
    "name": "nginx",
    "origin": "www/nginx",
    "version": "1.24.0_14,3",
    "comment": "Robust and small WWW server",
    "maintainer": "joneum@FreeBSD.org",
    "www": "https://nginx.com/",
    "abi": "FreeBSD:13:amd64",
    "arch": "freebsd:13:x86:64",
    "prefix": "/usr/local",
    "sum": "c39a7696e6eda7bfedba251e4480e50d4c65c520d5a783a584b19b3ef883",
    "flatsize": 1464332,
    "path": "All/nginx-1.24.0_14,3.pkg",
    "repopath": "All/nginx-1.24.0_14,3.pkg",
    "licenselogic": "single",
    "licenses": [
        "BSD2CLAUSE"
    ],
    "pkgsize": 473632,
    "desc": "NGINX is a high performance edge web server with the (...)",
    "deps": {
        "pcre2": {
            "origin": "devel/pcre2",
            "version": "10.42"
        }
    },
    "categories": [
        "www"
    ],
    "shlibs_required": [
        "libpcre2-8.so.0"
    ],
    "options": {
        "AJP": "off",
        "ARRAYVAR": "off",
        "AWS_AUTH": "off",
        "BROTLI": "off",
        "CACHE_PURGE": "off",
        "CLOJURE": "off",
        "COOKIE_FLAG": "off",
        "CT": "off",
        "DEBUG": "off",
        "DEBUGLOG": "off",
        "DEVEL_KIT": "off",
        "DRIZZLE": "off",
        "DSO": "on",
        "DYNAMIC_UPSTREAM": "off",
        "ECHO": "off",
        "ENCRYPTSESSION": "off",
        "FILE_AIO": "on",
        "FIPS_CHECK": "off",
        "FORMINPUT": "off",
        "GOOGLE_PERFTOOLS": "off",
        "GRIDFS": "off",
        "GSSAPI_HEIMDAL": "off",
        "GSSAPI_MIT": "off",
        "HEADERS_MORE": "off",
        "HTTP": "on",
        "HTTPV2": "on",
        "HTTPV3": "off",
        "HTTPV3_BORING": "off",
        "HTTPV3_LSSL": "off",
        "HTTPV3_QTLS": "off",
        "HTTP_ACCEPT_LANGUAGE": "off",
        "HTTP_ADDITION": "on",
        "HTTP_AUTH_DIGEST": "off",
        "HTTP_AUTH_KRB5": "off",
        "HTTP_AUTH_LDAP": "off",
        "HTTP_AUTH_PAM": "off",
        "HTTP_AUTH_REQ": "on",
        "HTTP_CACHE": "on",
        "HTTP_DAV": "on",
        "HTTP_DAV_EXT": "off",
        "HTTP_DEGRADATION": "off",
        "HTTP_EVAL": "off",
        "HTTP_FANCYINDEX": "off",
        "HTTP_SUBS_FILTER": "off",
        "HTTP_TARANTOOL": "off",
        "HTTP_UPLOAD": "off",
        "HTTP_UPLOAD_PROGRESS": "off",
        "HTTP_UPSTREAM_CHECK": "off",
        "HTTP_UPSTREAM_FAIR": "off",
        "HTTP_UPSTREAM_STICKY": "off",
        "HTTP_VIDEO_THUMBEXTRACTOR": "off",
        "HTTP_XSLT": "off",
        "HTTP_ZIP": "off",
        "ICONV": "off",
        "IPV6": "on",
        "LET": "off",
        "LINK": "off",
        "LUA": "off",
        "MAIL": "on",
        "MAIL_IMAP": "off",
        "MAIL_POP3": "off",
        "MAIL_SMTP": "off",
        "MAIL_SSL": "on",
        "MEMC": "off",
        "MODSECURITY3": "off",
        "NAXSI": "off",
        "NJS": "off",
        "NJS_XML": "off",
        "OPENTRACING": "off",
        "PASSENGER": "off",
        "POSTGRES": "off",
        "RDS_CSV": "off",
        "RDS_JSON": "off",
        "REDIS2": "off",
        "RTMP": "off",
        "SET_MISC": "off",
        "SFLOW": "off",
        "SHIBBOLETH": "off",
        "SLOWFS_CACHE": "off",
        "SRCACHE": "off",
        "STREAM": "on",
        "STREAM_REALIP": "on",
        "STREAM_SSL": "on",
        "STREAM_SSL_PREREAD": "on",
        "STS": "off",
        "THREADS": "on",
        "VOD": "off",
        "VTS": "off",
        "WEBSOCKIFY": "off",
        "WWW": "on",
        "XSS": "off"
    },
    "annotations": {
        "FreeBSD_version": "1302001",
        "build_timestamp": "2024-01-07T10:41:34+0000",
        "built_by": "poudriere-git-3.4.0",
        "cpe": "cpe:2.3:a:f5:nginx:1.24.0:::::freebsd13:x64:14",
        "port_checkout_unclean": "no",
        "port_git_hash": "756e18783",
        "ports_top_checkout_unclean": "no",
        "ports_top_git_hash": "756e18783"
    }
}

Extended search:

$ pkg search --raw --raw-format json-compact           --search name --search comment --search description nginx
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo pkg --quiet install --yes dmg2img
Updating FreeBSD repository catalogue...
FreeBSD repository is up to date.
All repositories are up to date.
Checking integrity... done (0 conflicting)
The following 1 package(s) will be affected (of 0 checked):

New packages to be INSTALLED:
    dmg2img: 1.6.7 [FreeBSD]

Number of packages to be installed: 1
[1/1] Installing dmg2img-1.6.7...
[1/1] Extracting dmg2img-1.6.7: 100%
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo pkg --quiet upgrade --yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo pkg --quiet upgrade --yes dmg2img
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo pkg --quiet delete --yes dmg2img
Checking integrity... done (0 conflicting)
Deinstallation has been requested for the following 1 packages:

Installed packages to be REMOVED:
    dmg2img: 1.6.7

Number of packages to be removed: 1
[1/1] Deinstalling dmg2img-1.6.7...
[1/1] Deleting files for dmg2img-1.6.7: 100%
pkg: Package database is busy while closing!
Return type:

str

sync()[source]

Sync package metadata.

$ sudo pkg --quiet -o IGNORE_OSVERSION=yes update
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%    7 MiB   3.6MB/s    00:02
Processing entries: 100%
FreeBSD repository update completed. 33804 packages processed.
All repositories are up to date.

The IGNORE_OSVERSION=yes prevents blocking update:

$ pkg --quiet update
Updating FreeBSD repository catalogue...
Fetching meta.conf: 100%    163 B   0.2kB/s    00:01
Fetching packagesite.pkg: 100%    7 MiB   3.6MB/s    00:02
Processing entries:   0%
Newer FreeBSD version for package zziplib:
To ignore this error set IGNORE_OSVERSION=yes
- package: 1302001
- running kernel: 1301000
Ignore the mismatch and continue? [y/N]:
Return type:

None

cleanup_orphan()[source]

Remove every package installed as a dependency and no longer required.

$ sudo pkg --quiet autoremove --yes
Checking integrity... done (0 conflicting)
Nothing to do.
Return type:

None

cleanup_cache()[source]

Delete every cached package from the local cache directory.

$ sudo pkg --quiet clean --yes --all
Nothing to do.
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

check --checksums validates every installed package’s files against their recorded checksums, exiting non-zero on mismatches.

$ pkg --quiet check --checksums --all
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('pkg',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pkg'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.pkg.Ports[source]

Bases: PackageManager

FreeBSD ports tree: the source-build workflow rooted at /usr/ports.

Note

Coexists with PKG on the same system: both share the install database maintained by pkg. Ports builds and tracks ports compiled from source under /usr/ports, while PKG handles binary packages from the FreeBSD repository. Listing operations may overlap because pkg does not distinguish ports-built from binary-installed packages once they are registered.

Note

installed and outdated delegate to the sibling pkg binary, since the ports tree keeps no registry of its own. Builds drive FreeBSD’s make directly with BATCH=yes to accept default build options without prompting. Upgrades shell out to the third-party portmaster: the ports tree ships no batch upgrader. sync refreshes the tree with git (portsnap was removed after FreeBSD 13).

Caution

Mutating operations require root privileges and a populated ports tree at /usr/ports. The manager flags itself unavailable when the tree is missing.

Initialize cli_errors list.

name: str = 'FreeBSD Ports Collection'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.freebsd.org/ports/'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='freebsd', name='FreeBSD')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

cli_names: tuple[str, ...] = ('make',)

The ports tree is driven by FreeBSD’s make.

No dedicated frontend exists; each port is a directory whose Makefile targets are invoked directly.

extra_env: ClassVar = {'BATCH': 'yes'}

Force non-interactive builds.

Many ports prompt for build option dialogs by default. BATCH=yes accepts the saved or default options without user interaction, which is the only sensible behavior for an automated tool. See ports(7).

version_cli_options: tuple[str, ...] = ('-V', '.MAKE.VERSION')

FreeBSD make exposes its version via internal variable expansion.

GNU Make’s --version flag does not work on BSD make; using -V .MAKE.VERSION keeps the probe portable and avoids accidentally matching a GNU Make installation shadowing the BSD binary.

version_regexes: tuple[str, ...] = ('(?P<version>\\d{8,})',)

BSD make reports its version as a date-like integer (e.g. 20240218).

property available: bool[source]

Available only when make is found and the ports tree exists.

The make binary alone is not enough: without a populated /usr/ports directory, every operation would fail. Treat the tree as part of the manager’s runtime requirement.

id: str = 'ports'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property installed: Iterator[Package]

Fetch packages currently registered as installed.

Delegates to pkg query because the ports tree itself maintains no registry: ports installs are recorded in the same database as binary pkg installs.

$ pkg query "%n %v %o %c"
curl 8.7.1 ftp/curl Non-interactive tool to get files from FTP/HTTP servers
python311 3.11.9 lang/python311 Interpreted object-oriented programming language
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property outdated: Iterator[Package]

Fetch packages whose installed version lags the ports tree.

Uses pkg version in ports-comparison mode (-PL=): it walks the local tree for each installed package and reports those with a newer Makefile version available.

$ pkg version -vIPL=
curl-8.7.1                         <   needs updating (port has 8.8.0)
python311-3.11.9                   <   needs updating (port has 3.11.10)
vim-9.1.0                          =   up-to-date with port
install(package_id, version=None)[source]

Build and install a port from source.

package_id may be either a bare port name (e.g. nginx) or its full origin (e.g. www/nginx). When given a bare name, the origin is resolved through pkg search -o against the active repository.

$ cd /usr/ports/www/nginx && sudo make BATCH=yes install clean
Return type:

str

upgrade_all_cli()[source]

Generate the CLI to upgrade every outdated port.

The ports tree has no first-party batch upgrader; the workflow relies on the third-party portmaster tool. We build the command line without checking that portmaster is installed, because upgrade commands are typically printed for the user to inspect before running.

$ sudo portmaster --no-confirm --no-term-title -a
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generate the CLI to upgrade one port via portmaster.

$ sudo portmaster --no-confirm --no-term-title www/nginx
Return type:

tuple[str, ...]

remove

Reuses PKG.remove(): the ports tree has no native uninstaller, and removal goes through the shared install database regardless of how the package was originally built.

sync()[source]

Refresh the local ports tree from upstream.

Modern FreeBSD distributes the ports tree via Git; portsnap was deprecated and removed after FreeBSD 13. We pull from whatever remote the tree was checked out from.

$ sudo git -C /usr/ports pull --ff-only
Return type:

None

cleanup_cache()[source]

Remove cached build artifacts from the ports tree.

Walks the tree once and invokes make clean at the root, which recursively cleans every port’s work directory. DISTCLEAN=yes also removes downloaded distfiles.

$ sudo make -C /usr/ports clean DISTCLEAN=yes BATCH=yes
Return type:

None

meta_package_manager.managers.pnpm module

class meta_package_manager.managers.pnpm.PNPM[source]

Bases: PackageManager

A Node.js package manager with a content-addressable global store.

Like meta_package_manager.managers.npm.NPM, mpm drives pnpm in global mode (--global on every operation) and parses its --json output. Command equivalences with the sibling JS managers are listed in antfu-collective/ni.

Note

pnpm enforces a supply-chain cooldown through its minimumReleaseAge setting (counted in minutes), refusing to install any release published more recently than the configured age. The version floor is set by search, which first shipped in 11.0.0; that release also clears the earlier minimumReleaseAge floor, so one requirement guards every advertised operation.

Caution

pnpm outdated exits 1 when it finds outdated packages, printing the report to <stdout> with an empty <stderr>. The query passes must_succeed so this benign non-zero exit is tolerated instead of raising.

Initialize cli_errors list.

name: str = 'Node pnpm'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://pnpm.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=11.0.0'

11.0.0 is the first version to ship the search subcommand. It also clears the 10.16.0 floor of minimumReleaseAge, the release-age gate mpm drives for the supply-chain cooldown (see cooldown_env_var), so a single floor covers every advertised operation. Older pnpm releases either lack search or silently ignore the cooldown setting.

cooldown_env_var: ClassVar[str | None] = 'pnpm_config_minimum_release_age'

pnpm honors a release-age cooldown through its minimumReleaseAge setting.

pnpm reads any setting from an environment variable built by snake-casing the setting name behind a pnpm_config_ prefix (the docs render pmOnFail as pnpm_config_pm_on_fail), so pnpm_config_minimum_release_age sets minimumReleaseAge without touching pnpm-workspace.yaml. Once set, pnpm refuses to install any version published more recently than the configured age, across direct and transitive dependencies.

minimumReleaseAge is expressed in minutes, so cooldown_env_value() is overridden to emit a minute count.

See pnpm’s minimumReleaseAge setting.

cooldown_env_value()[source]

Render meta_package_manager.execution.CLIExecutor.cooldown as an integer minute count for pnpm’s minimumReleaseAge.

Sub-minute cooldowns round up so the gate over-protects rather than silently collapsing to 0 (the “no cooldown” sentinel).

Return type:

str

property installed: Iterator[Package]

Fetch installed packages.

pnpm list --json returns an array of project objects; the global scope resolves to a single one whose dependencies map holds the installed packages.

$ pnpm list --global --json --depth 0
[
  {
    "name": "global",
    "dependencies": {
      "eslint": {
        "from": "eslint",
        "version": "9.15.0"
      },
      "typescript": {
        "from": "typescript",
        "version": "5.6.3"
      }
    }
  }
]
property outdated: Iterator[Package]

Fetch outdated packages.

pnpm outdated exits with code 1 when it finds outdated packages, but writes the report to <stdout> and leaves <stderr> empty. Passing must_succeed keeps the lenient failure gate that tolerates a non-zero exit with an empty <stderr> as a benign status code, so the call does not raise (see meta_package_manager.execution.CLIExecutor.run()).

$ pnpm outdated --global --json
{
  "eslint": {
    "current": "9.10.0",
    "latest": "9.15.0",
    "wanted": "9.15.0",
    "isDeprecated": false,
    "dependencyType": "dependencies"
  }
}
search(query, extended, exact)[source]

Fetch matching packages.

pnpm queries the registry’s /-/v1/search endpoint and, with --json, emits an array of the matched packages (an empty [] when none match).

Caution

Search does not support exact matching: the registry endpoint matches on names, descriptions and keywords, so the framework refilters the raw results for exact queries.

$ pnpm search --json is-positive
[
  {
    "name": "is-positive",
    "version": "3.1.0",
    "description": "Check if something is a positive number",
    "date": "2017-10-24T15:24:08.180Z",
    "maintainers": [
      {
        "username": "sindresorhus"
      }
    ]
  }
]
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ pnpm add --global markdown
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ pnpm update --global --latest
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ pnpm update --global --latest markdown
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('pnpm',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'pnpm'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package.

$ pnpm remove --global markdown
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Remove orphan packages from the global content-addressable store.

$ pnpm store prune
Return type:

None

meta_package_manager.managers.scoop module

class meta_package_manager.managers.scoop.Scoop[source]

Bases: PackageManager

Scoop is a user-level command-line installer for Windows.

Apps unpack under ~/scoop without elevation, so no operation is marked sudo.

Documentation: ScoopInstaller/Scoop.

Note

The installed, outdated and search listings are column tables introduced by a --- separator line: mpm drops everything up to that separator, then splits each row positionally on whitespace.

Attention

scoop --version does not reliably print a clean version: it often emits the raw git log line of the checkout instead. The probe therefore carries fallbacks that recover the version from a tag: vX.Y.Z ref or a Bump to version commit subject. See Scoop’s own version-reporting issue.

Caution

remove uninstalls with --purge, so a package’s persisted data directory is deleted with it rather than kept for a later reinstall.

Initialize cli_errors list.

name: str = 'Scoop'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://scoop.sh'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='windows', name='Windows')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.2.4'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

version_regexes: tuple[str, ...] = ('^v(?P<version>\\S+)\\s.+', '^.+,\\stag:\\sv(?P<version>\\S+),\\s.+', '^.+\\sBump\\sto\\sversion\\s(?P<version>\\S+)\\s.+')

Search version at the start of a line.

> scoop --version
Current Scoop version:
v0.2.4 - Released at 2022-08-08

'main' bucket:
5a5b13b6c (HEAD -> master, origin/HEAD) oh-my-posh: Update to version 11.1.1

Attention

Scoop does not always provide a clean version string.

So we fallback on parsing various git log output:

> scoop --version
Current Scoop version:
b588a06e (HEAD -> master, tag: v0.5.3, origin/master, origin/HEAD) Bump 0.5.3

'main' bucket:
46c50c6b0 (HEAD -> master, origin/master, origin/HEAD) fix arm64 version
> scoop --version
Current Scoop version:
b588a06e chore(release): Bump to version 0.5.3 (resync) (#6436)

'main' bucket:
46c50c6b0 aqua: fix arm64 version (#7071)
static remove_headers(text)[source]
Return type:

str

property installed: Iterator[Package]

Fetch installed packages.

>  scoop list
Installed apps:

Name   Version          Source Updated             Info
----   -------          ------ -------             ----
7zip   22.01            main   2022-09-27 08:03:30
dark   3.11.2           main   2022-09-27 08:04:26
git    2.37.3.windows.1 main   2022-09-27 08:03:58
python 3.10.7           main   2022-09-27 08:04:53
property outdated: Iterator[Package]

Fetch outdated packages.

> scoop status
Name           Installed Version Latest Version Missing Dependencies Info
----           ----------------- -------------- -------------------- ----
demulshooter   16.7.2            18.7.3
eduke32        20220611-10112    20220709-10115
Teracopy-np
yuzu-pineapple EA-2804           EA-2830
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

> scoop search zip
Results from local buckets...

Name             Version         Source Binaries
----             -------         ------ --------
7zip             22.01           main
7zip19.00-helper 19.00           main
busybox          4716-g31467ddfc main   bunzip2 | gunzip | gzip | unzip
bzip2            1.0.8.0         main
gow              0.8.0           main   bunzip2.exe | bzip2.exe | zip.exe
gzip             1.3.12          main
lzip             1.20            main
unzip            6.00            main
zip              3.0             main
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

> scoop install 7zip
Installing '7zip' (22.01) [64bit] from main bucket
7z2201-x64.msi (1.8 MB) [====================] 100%
Checking hash of 7z2201-x64.msi ... ok.
Extracting 7z2201-x64.msi ... done.
Linking ~\scoopppszip\current => ~\scoopppszip.01
Creating shim for '7z'.
Creating shortcut for 7-Zip (7zFM.exe)
Persisting Codecs
Persisting Formats
Running post_install script...
'7zip' (22.01) was installed successfully!

Notes
-----
Add 7-Zip as a context menu by running: "C:\scoop\...install-context.reg"
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

> scoop update --all
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

> scoop update 7zip
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

> scoop uninstall 7zip --purge
Uninstalling '7zip' (22.01).
Removing shim '7z.shim'.
Removing shim '7z.exe'.
Removing shortcut ~\AppData\Roaming\Scoop Apps-Zip.lnk
Unlinking ~\scoopppszip\current
'7zip' was uninstalled.
Return type:

str

sync()[source]

Sync package metadata.

> scoop status
WARN  Scoop out of date. Run 'scoop update' to get the latest changes.
> scoop update
Updating Scoop...
Updating 'main' bucket...
Converting 'main' bucket to git repo...
Checking repo... OK
The main bucket was added successfully.
Scoop was updated successfully!
> scoop status
Scoop is up to date.
Everything is ok!
Return type:

None

cleanup_cache()[source]

Removes things we don’t need anymore.

> scoop cleanup --all --cache
Everything is shiny now!
Return type:

None

cli_names: tuple[str, ...] = ('scoop',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

Caution

checkup prints its suggestions but is optimistic with its exit code, so an unhealthy setup may still report as : the relayed report is the signal to read.

> scoop checkup
Return type:

tuple[str, ...]

id: str = 'scoop'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.sdkman module

class meta_package_manager.managers.sdkman.SDKMAN[source]

Bases: PackageManager

SDKMAN! manages parallel versions of multiple Software Development Kits on Unix-based systems.

Note

SDKMAN! primarily serves the JVM ecosystem: Java, Gradle, Maven, Kotlin, Scala, and ~115 other candidates. Each candidate is treated as a package.

Caution

The sdk command is a shell function, not a standalone binary, so mpm detects SDKMAN by its init script (sdkman-init.sh) rather than a binary on PATH and wraps every invocation in bash -c 'source <init> && sdk <args>'.

Note

SDKMAN has no read-only “outdated” verb, so outdated pipes n into sdk upgrade to capture the candidate list without applying any upgrade.

Initialize cli_errors list.

homepage_url: str | None = 'https://sdkman.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=5.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cli_names: tuple[str, ...] = ('sdkman-init.sh',)

Detect SDKMAN by the presence of its init script.

cli_search_path: tuple[str, ...] = ('/home/runner/.sdkman/bin',)

List of additional path to help mpm hunt down the package manager CLI.

Must be a list of strings whose order dictates the search sequence.

Most of the time unnecessary: meta_package_manager.execution.CLIExecutor.cli_path works well on all platforms.

extra_env: ClassVar = {'sdkman_auto_answer': 'true', 'sdkman_colour_enable': 'false'}

Disable ANSI colors and auto-accept interactive prompts.

version_cli_options: tuple[str, ...] = ('version',)

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('script:\\s+(?P<version>\\S+)',)
$ sdk version
SDKMAN!
script: 5.18.2
native: 0.4.6
build_cli(*args, **kwargs)[source]

Wrap all CLI invocations to source the SDKMAN init script in bash.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the bash -c wrapper and SDKMAN never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

$ sdk current
Using:
groovy: 4.0.22
java: 21.0.4-tem
scala: 3.4.2
property outdated: Iterator[Package]

Fetch outdated packages.

$ echo n | sdk upgrade
Available defaults:
gradle (local: 2.3, 1.11; default: 8.9)
java (local: 21.0.4-tem; default: 25.0.2-tem)

Use prescribed default version(s)? (Y/n):

Note

Pipes n to sdk upgrade to obtain the outdated list without actually performing the upgrade. Overrides sdkman_auto_answer to false so the command prints the candidate list before prompting.

install(package_id, version=None)[source]

Install one package.

$ sdk install java 21.0.4-tem
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ sdk upgrade
Return type:

tuple[str, ...]

id: str = 'sdkman'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'SDKMAN'

Return package manager’s common name.

Default value is based on class name.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ sdk upgrade java
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Remove one package.

SDKMAN’s uninstall command requires both the candidate and a specific version. The currently installed version is looked up from installed() and passed to the CLI.

$ sdk uninstall java 21.0.4-tem
Return type:

str

sync()[source]

Sync package metadata.

$ sdk update
Return type:

None

cleanup_cache()[source]

Clear SDKMAN caches.

$ sdk flush
Return type:

None

meta_package_manager.managers.sfsu module

class meta_package_manager.managers.sfsu.SFSU[source]

Bases: PackageManager

sfsu (Scoop For Speed and Usability) is a Rust reimplementation of Scoop’s slower read paths, working against the same buckets and ~/scoop install tree.

mpm reaches for sfsu only where it is both faster than Scoop and speaks JSON: installed, outdated and search all pass --json and are parsed as structured objects instead of the whitespace tables Scoop prints.

Note

sfsu implements no mutating verbs, so install, remove and both upgrade commands are bound straight to Scoop through the Delegate descriptor: those operations run the scoop binary, and a host with sfsu but no Scoop cannot mutate anything.

Initialize cli_errors list.

name: str = 'Scoop sfsu'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/winpax/sfsu'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='windows', name='Windows')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.16.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

post_args: tuple[str, ...] = ('--no-color',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

version_regexes: tuple[str, ...] = ('sfsu\\s+(?P<version>\\S+)',)
> sfsu --version
sfsu 1.17.2
sprinkles 0.22.0 (crates.io published version)
property installed: Iterator[Package]

Fetch installed packages.

> sfsu list --json
[
  {
    "name": "7zip",
    "version": "26.00",
    "source": "main",
    "updated": "2026-03-18 17:54:32",
    "notes": ""
  },
  {
    "name": "git",
    "version": "2.53.0.3",
    "source": "main",
    "updated": "2026-03-15 09:12:04",
    "notes": ""
  }
]
property outdated: Iterator[Package]

Fetch outdated packages.

Uses sfsu status --only apps --json which returns packages with available updates.

> sfsu status --only apps --json
{
  "packages": [
    {
      "name": "git",
      "current": "2.53.0.2",
      "available": "2.53.0.3",
      "missing_dependencies": [],
      "info": null
    }
  ]
}
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching. Results are refiltered by meta_package_manager.manager.PackageManager.refiltered_search().

> sfsu search --json git
{
  "main": [
    {
      "name": "git",
      "bucket": "main",
      "version": "2.53.0.3",
      "installed": true,
      "bins": []
    },
    ...
  ],
  ...
}
Return type:

Iterator[Package]

install

Install one package.

> scoop install 7zip
Installing '7zip' (22.01) [64bit] from main bucket
7z2201-x64.msi (1.8 MB) [====================] 100%
Checking hash of 7z2201-x64.msi ... ok.
Extracting 7z2201-x64.msi ... done.
Linking ~\scoopppszip\current => ~\scoopppszip.01
Creating shim for '7z'.
Creating shortcut for 7-Zip (7zFM.exe)
Persisting Codecs
Persisting Formats
Running post_install script...
'7zip' (22.01) was installed successfully!

Notes
-----
Add 7-Zip as a context menu by running: "C:\scoop\...install-context.reg"
upgrade_all_cli

Generates the CLI to upgrade all outdated packages.

> scoop update --all
upgrade_one_cli

Generates the CLI to upgrade the provided package.

> scoop update 7zip
remove

Remove one package.

> scoop uninstall 7zip --purge
Uninstalling '7zip' (22.01).
Removing shim '7z.shim'.
Removing shim '7z.exe'.
Removing shortcut ~\AppData\Roaming\Scoop Apps-Zip.lnk
Unlinking ~\scoopppszip\current
'7zip' was uninstalled.
sync()[source]

Sync package metadata.

Uses sfsu’s native update command which updates Scoop and all buckets.

> sfsu update --no-color
Return type:

None

cleanup_cache()[source]

Removes old versions of all installed apps and clears the cache.

> sfsu cleanup --all --cache --no-color
Return type:

None

cli_names: tuple[str, ...] = ('sfsu',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'sfsu'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.sheldon module

class meta_package_manager.managers.sheldon.Sheldon[source]

Bases: PackageManager

Sheldon is a fast, configurable plugin manager for any shell.

Plugins are declared in a plugins.toml config file, each under a unique local name, and materialized into a plugins.lock file that Sheldon generates. Packages are identified by that local name, which is what every command below takes.

Unlike the other shell plugin managers mpm wraps, Sheldon is a real compiled binary rather than a sourced shell function, so it needs no interpreter wrapper: mpm calls sheldon directly.

Caution

No installed: Sheldon ships no command that prints its plugins. The inventory does exist, in the plugins.toml config file, but reaching it would mean mpm reading and parsing a configuration file instead of calling a CLI, which is not how a manager gathers packages here. The upstream command set is init, add, edit, remove, lock, source, completions and version: none of them lists anything.

Caution

No install: sheldon add requires two values, a unique local name and a source flag naming where the plugin comes from (--github, --git, --gist, --remote or --local). mpm’s install carries a single package id, which cannot supply both, and guessing a source from the id would be inventing a mapping Sheldon never defined. The operation is therefore not implemented rather than faked, and mpm auto-skips it.

Note

No outdated: Sheldon compares nothing against its remotes short of performing the update. upgrade --all still works, and mpm auto-skips the operation.

Documentation: sheldon.

Initialize cli_errors list.

name: str = 'Sheldon'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://sheldon.cli.rs'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.6.0'

The series carrying the subcommand set this class drives.

0.6.0 is where lock --update settled as the way to refresh every plugin source, split from the source command that generates the shell script.

extra_env: ClassVar = {'NO_COLOR': '1'}

Sheldon colors its progress output, which NO_COLOR disables. It also honors a --color flag, but the environment variable covers every invocation without threading a flag through each one.

cli_names: tuple[str, ...] = ('sheldon',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'sheldon'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

version_regexes: tuple[str, ...] = ('sheldon\\s+(?P<version>\\S+)',)

Sheldon declares its version through clap, which prints the crate name and release. The separate sheldon version subcommand prints a longer report, and is not what the probe reads.

$ sheldon --version
sheldon 0.8.2
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

lock --update re-fetches every plugin source declared in plugins.toml and regenerates the lock file. The sibling --reinstall discards and re-clones each source instead, which is a repair rather than an upgrade, so it is not what this builds.

$ sheldon lock --update
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

remove takes the plugin’s unique local name, the same identifier add assigned it in plugins.toml, and drops its entry from that file.

$ sheldon remove zsh-autosuggestions
Return type:

str

meta_package_manager.managers.snap module

class meta_package_manager.managers.snap.Snap[source]

Bases: PackageManager

Canonical’s snap installs sandboxed, self-updating packages.

snaps refresh themselves on a schedule, so upgrade merely forces a snap refresh sooner. Mutating operations escalate through sudo by default: the privileged work happens in the snapd daemon, but the daemon refuses state changes from an unprivileged client (snap install as a plain user is denied with a hint to retry with sudo), which is why the Snap store documents sudo snap install as the canonical invocation. A host authenticated against the store with snap login (or granted a polkit rule) can drop the wrap with --no-sudo or a [mpm.managers.snap] sudo = false override.

Note

snap localizes and colorizes its table headers with no terminal detection. mpm pins nothing to English: --color=never strips the ANSI, the header row is dropped, and every row is split on whitespace and read by column position, so the translated headers never reach the parser.

Note

snap refresh --list reports only the available version, so outdated looks each installed version up by ID from the cached installed set. search runs snap find, which matches summaries as well as names, so mpm refilters the results.

Initialize cli_errors list.

homepage_url: str | None = 'https://snapcraft.io'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=2.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

post_args: tuple[str, ...] = ('--color=never',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

version_regexes: tuple[str, ...] = ('snap\\s+(?P<version>\\S+)',)
$ snap --version
snap       2.44.1
snapd      2.44.1
series     16
linuxmint  19.3
kernel     4.15.0-91-generic
property installed: Iterator[Package]

Fetch installed packages.

$ snap list --color=never
Name    Version    Rev   Aufzeichnung   Herausgeber     Hinweise
core    16-2.44.1  8935  latest/stable  canonical✓      core
wechat  2.0        7     latest/stable  ubuntu-dawndiy  -
pdftk   2.02-4     9     latest/stable  smoser          -
property outdated: Iterator[Package]

Fetch outdated packages.

$ snap refresh --list --color=never
Name            Version  Rev  Herausgeber     Hinweise
standard-notes  3.3.5    8    standardnotes✓  -
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search is extended by default. So we return the best subset of results and let meta_package_manager.manager.PackageManager.refiltered_search() refine them.

$ snap find doc --color=never
Name       Version      Herausgeber  Hinweise  Zusammenfassung
journey    2.14.3       2appstudio   -         Your private diary.
nextcloud  17.0.5snap1  nextcloud✓   -         Nextcloud Server
skype      8.58.0.93    skype✓       classic   One Skype for all.
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo snap install standard-notes --color=never
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo snap refresh --color=never
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo snap refresh standard-notes --color=never
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('snap',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'snap'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Snap'

Return package manager’s common name.

Default value is based on class name.

remove(package_id)[source]

Remove one package.

Unlike list, find, refresh and install, snap’s remove subcommand rejects the global --color flag (error: unknown flag ‘color’`). Its output is not parsed, so the``–color=never` post-arg is dropped here with auto_post_args=False.

$ sudo snap remove standard-notes
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.sun_tools module

class meta_package_manager.managers.sun_tools.Sun_Tools[source]

Bases: PackageManager

Solaris’ legacy System V Release 4 packaging tools.

Documentation:

The suite spans several binaries: pkginfo (the read-only query tool, used as the main CLI), pkgadd and pkgrm.

Note

SVR4 packages come from local media or datastream files, not a network repository: there is no catalog to search, refresh or diff against, and pkgadd installs a specific local artifact rather than resolving a name. Only installed and remove are therefore implemented; Solaris 11’s modern repository-based interface is IPS (pkg), a different manager.

Initialize cli_errors list.

maintenance_note: str | None = 'The SVR4 packaging commands are legacy, superseded by IPS since Solaris 11, but still shipped and supported on [Oracle Solaris 11.4](https://docs.oracle.com/cd/E37838_01/html/E61051/pkgsvr4.html), whose support runs through 2037.'

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

name: str = 'Solaris SVR4 package tools'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://docs.oracle.com/cd/E86824_01/html/E54763/pkginfo-1.html'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='solaris', name='Solaris')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

cli_names: tuple[str, ...] = ('pkginfo',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

cli_search_path: tuple[str, ...] = ('/usr/sbin',)

List of additional path to help mpm hunt down the package manager CLI.

Must be a list of strings whose order dictates the search sequence.

Most of the time unnecessary: meta_package_manager.execution.CLIExecutor.cli_path works well on all platforms.

version_cli: str | None = 'uname'

None of the SVR4 tools has a version flag: pkginfo -v matches a package version and pkgadd/pkgrm only take -v as verbose. The suite ships with the base system, so its version is the OS release reported by uname -r (5.11 on Solaris 11).

version_cli_options: tuple[str, ...] = ('-r',)

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('(?P<version>[\\d.]+)',)
$ uname -r
5.11
id: str = 'sun-tools'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property installed: Iterator[Package]

Fetch installed packages.

Plain pkginfo prints no version column (only category, package instance and name), so the long -l listing is parsed instead: each package is a multi-line block carrying PKGINST:, VERSION: and STATUS: fields. Only completely-installed packages are yielded.

$ pkginfo -l
  PKGINST:  SUNWcar
      NAME:  Core Architecture, (Root)
  CATEGORY:  system
      ARCH:  i386.i86pc
   VERSION:  11.10.0,REV=2005.01.21.16.34
   BASEDIR:  /
    VENDOR:  Oracle Corporation
    STATUS:  completely installed
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Remove one package.

-n runs non-interactively: pkgrm exits instead of prompting, so a removal requiring interaction (like a dependency confirmation) fails fast rather than hanging mpm’s subprocess.

$ sudo pkgrm -n SUNWzlib
Return type:

str

meta_package_manager.managers.tazpkg module

class meta_package_manager.managers.tazpkg.Tazpkg[source]

Bases: PackageManager

SliTaz GNU/Linux’s package manager.

Documentation:

Note

tazpkg decorates every listing with localized, colorized titles, separators and count footers, with no terminal detection: LC_ALL=C pins the text to English, --output=raw switches the decorations to plain text, and any remaining ANSI sequence is stripped before parsing. Data rows are then matched by their digit-led version column, which no decoration line carries.

Note

No outdated operation: tazpkg up --check requires root and recharges the package lists from the mirror even when only listing, so there is no cleanly read-only upgradable listing.

Initialize cli_errors list.

maintenance_note: str | None = '[SliTaz](https://slitaz.org) has published no stable ISO since 5.0 (2023) but shows active development into 2026; `tazpkg` remains its native package manager.'

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

name: str = 'TazPkg'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://slitaz.org'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='slitaz', name='SliTaz GNU/Linux')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

extra_env: ClassVar = {'LC_ALL': 'C'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

post_args: tuple[str, ...] = ('--output=raw',)

Global list of options used before and after the invoked package manager CLI.

Automatically added to each meta_package_manager.execution.CLIExecutor.run_cli() call.

Essentially used to force silencing, low verbosity or no-color output.

version_cli: str | None = 'awk'

tazpkg has no version command at all: its own version only exists as the tazpkg row of the installed-packages database. This probe mirrors, verbatim, how tazpkg resolves its VERSION variable for itself:

export VERSION=$(awk -F$'\t' '$1=="tazpkg"{print $2}' \
    "$PKGS_DB/installed.info")
version_cli_options: tuple[str, ...] = ('-F\t', '$1=="tazpkg"{print $2}', '/var/lib/tazpkg/installed.info')

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('^(?P<version>[\\d.]+)$',)

A bare integer Mercurial revision on cooking releases (944) or a dotted version on stable ones (4.9.2).

property installed: Iterator[Package]

Fetch installed packages.

$ tazpkg list --output=raw
List of all installed packages
================================================================================
busybox                            1.36.0            base-system
nano                               6.2               editors
================================================================================
2 packages installed.
search(query, extended, exact)[source]

Fetch matching packages.

tazpkg matches the query as a case-insensitive substring of name-version, over installed then mirrored packages.

$ tazpkg search nano --output=raw
Installed packages
--------------------------------------------------------------------------------
nano                    6.2               editors
--------------------------------------------------------------------------------
1 installed package found for: nano
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package from the mirror.

--forced skips the already-installed guard, keeping the call non-interactive.

$ sudo tazpkg get-install nano --forced --output=raw
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

-i (no long form) auto-confirms, upgrading every outdated package; the command recharges the package lists first.

$ sudo tazpkg up -i --output=raw
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

tazpkg has no per-package upgrade verb: its own upgrade loop re-runs get-install --forced on each outdated package.

$ sudo tazpkg get-install nano --forced --output=raw
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('tazpkg',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'tazpkg'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove(package_id)[source]

Remove one package.

No --auto on purpose: it would also auto-confirm the “remove dependents?” follow-up and cascade. On a non-terminal stdout (mpm’s subprocess pipe) the (y/N) prompt is skipped and only the target package is removed.

$ sudo tazpkg remove nano --output=raw
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Recharge the package lists from the mirror.

$ sudo tazpkg recharge --output=raw
Return type:

None

cleanup_cache()[source]

Delete every downloaded package from the cache.

$ sudo tazpkg clean-cache --output=raw
Return type:

None

meta_package_manager.managers.uv module

class meta_package_manager.managers.uv.UVBase[source]

Bases: PackageManager

Virtual base shared by the UV and UVX managers defined below.

Initialize cli_errors list.

homepage_url: str | None = 'https://docs.astral.sh/uv'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

requirement: str | None = '>=0.5.0'

0.5.0 is the first version to introduce pip list --outdated command.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

virtual: bool = True

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cooldown_env_var: ClassVar[str | None] = 'UV_EXCLUDE_NEWER'

uv honors a release-age cooldown through its exclude-newer resolver option.

UV_EXCLUDE_NEWER mirrors the --exclude-newer flag and is read by every resolving subcommand (pip install, pip list --outdated, tool install, tool upgrade), so a single environment variable covers install, upgrade and outdated at once. uv accepts an RFC 3339 timestamp, which is exactly what the default meta_package_manager.execution.CLIExecutor.cooldown_env_value() produces.

Note

The environment variable is the only mechanism that reaches these subcommands, which is why the cutoff is injected rather than written to a config file. uv pip and uv tool operate at the user level and ignore project-local configuration: a [tool.uv] table in the pyproject.toml of whatever directory the user happens to stand in is never consulted. Only user-level and system-level uv.toml are, and UV_EXCLUDE_NEWER outranks both.

Caution

Because the variable outranks those files, injecting it replaces any standing exclude-newer the user configured rather than tightening it: a cooldown looser than their own policy silently widens it for the duration of the run. See Cooldown, section “The cooldown is authoritative, not a floor”.

uv exposes no environment variable for the companion --exclude-newer-package flag, so a per-package exemption cannot be injected the way this cutoff is.

See uv’s exclude-newer setting.

pre_args: tuple[str, ...] = ('--color', 'never', '--no-progress')
  • --color color-choice

    Control colors in output [default: auto]

    Possible values: - auto: Enables colored output only when the output is going to a terminal or TTY with support - always: Enables colored output regardless of the detected environment - never: Disables colored output

  • --no-progress

    Hide all progress outputs.

    For example, spinners or progress bars.

version_regexes: tuple[str, ...] = ('uv\\s+(?P<version>\\S+)',)
$ uv --version
uv 0.2.21 (ebfe6d8fc 2024-07-03)
cli_names: tuple[str, ...] = ('uvbase',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'uvbase'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'UVBase'

Return package manager’s common name.

Default value is based on class name.

class meta_package_manager.managers.uv.UV[source]

Bases: UVBase

Python packages managed with uv’s uv pip interface.

Installed and outdated packages are read with uv pip list (adding --outdated and --format=json), acting on whatever environment uv resolves, exactly as a bare uv pip call in the same shell would. The --outdated listing sets the >=0.5.0 version floor, the first uv release to ship it. The release-age cooldown rides on uv’s --exclude-newer resolver option, which every resolving subcommand honors, so one cutoff covers install, upgrade and outdated together.

Hint

Package specs are passed unquoted, working around uv parse failures on quoted specs.

Initialize cli_errors list.

name: str = 'Python uv'

Return package manager’s common name.

Default value is based on class name.

property installed: Iterator[Package]

Fetch installed packages.

$ uv --color never --no-progress pip list --format=json
[
  {
    "name": "markupsafe",
    "version": "2.1.5"
  },
  {
    "name": "meta-package-manager",
    "version": "5.17.0",
    "editable_project_location": "/Users/kde/meta-package-manager"
  },
  {
    "name": "myst-parser",
    "version": "3.0.1"
  }
]
property outdated: Iterator[Package]

Fetch outdated packages.

$ uv --color never --no-progress pip list --outdated --format=json
[
  {
    "name": "lark-parser",
    "version": "0.7.8",
    "latest_version": "0.12.0",
    "latest_filetype": "wheel"
  },
  {
    "name": "types-setuptools",
    "version": "75.3.0.20241107",
    "latest_version": "75.3.0.20241112",
    "latest_filetype": "wheel"
  }
]
install(package_id, version=None)[source]

Install one package.

$ uv --color never --no-progress pip install arrow
Return type:

str

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ uv --color never --no-progress pip install --upgrade arrow
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ uv --color never --no-progress pip uninstall arrow
Return type:

str

cleanup_cache()[source]

Removes things we don’t need anymore.

Warning

Skipped when mpm itself was launched by uv run or uvx: the parent uv process keeps a lock on its cache for as long as its child lives, so each cache command below would wait on its own ancestor for UV_LOCK_TIMEOUT (300 seconds by default), fail, and stall the whole cleanup for ten minutes. uv advertises itself to its children through the UV environment variable, which is the marker detected here.

$ uv --color never --no-progress cache clean
Clearing cache at: /Users/kde/Library/Caches/uv
Removed 97279 files (2.0GiB)
$ uv --color never --no-progress cache prune
No cache found at: /Users/kde/.cache/uv
Return type:

None

cli_names: tuple[str, ...] = ('uv',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'uv'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.uv.UVX[source]

Bases: UVBase

uv’s tool manager for isolated Python applications, like pipx.

mpm drives the uv tool subcommands; each application lives in its own venv. Installed and outdated tools are parsed from the plain-text tool list and tool list --outdated output: unlike the uv pip interface, uv tool emits no JSON. The --outdated listing sets the >=0.10.10 version floor, the first uv release to ship it. The release-age cooldown rides on uv’s --exclude-newer resolver option, covering install, upgrade and outdated through one cutoff.

Hint

Package specs are passed unquoted, working around uv parse failures on quoted specs.

Initialize cli_errors list.

name: str = 'Python uvx'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://docs.astral.sh/uv/guides/tools/'

Home page of the project, only used in documentation for reference.

brewfile_entry_type: ClassVar[str | None] = 'uv'

Mapped to Homebrew Bundle’s uv entry type, which installs via uv tool install: the same mechanism UVX wraps, while the pip-style UV manager has no Brewfile counterpart. See Snapshot and export, section “uv mapping”.

requirement: str | None = '>=0.10.10'

0.10.10 is the first version to introduce tool list --outdated command.

cli_names: tuple[str, ...] = ('uv',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'uvx'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property installed: Iterator[Package]

Fetch installed packages.

$ uv --color never --no-progress tool list
pycowsay v0.0.0.1
- pycowsay
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

property outdated: Iterator[Package]

Fetch outdated packages.

$ uv --color never --no-progress tool list --outdated
pycowsay v0.0.0.1 [latest: 0.0.0.2]
- pycowsay
install(package_id, version=None)[source]

Install one package.

$ uv --color never --no-progress tool install pycowsay
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ uv --color never --no-progress tool upgrade --all
Updated pycowsay v0.0.0.1 -> v0.0.0.2
    - pycowsay
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ uv --color never --no-progress tool upgrade pycowsay
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ uv --color never --no-progress tool uninstall pycowsay
Return type:

str

meta_package_manager.managers.vagrant module

class meta_package_manager.managers.vagrant.Vagrant[source]

Bases: PackageManager

Vagrant’s box manager, covering the base images it fetches from its registry.

Vagrant orchestrates virtual machines, which is not package management. Two of its subcommand trees are: vagrant box, covering versioned base images pulled from a registry, and vagrant plugin, covering Vagrant’s own extensions. Only one can be the inventory, and boxes are it. They carry the whole operation set, where plugins offer neither an outdated nor a search of any kind, and a plugin is a RubyGem installed into a private gem home rather than something with a registry of its own.

A package is a box, identified by the bare name the listing prints, which may be a registry name like ubuntu/jammy64, a purely local name, or a full URL. The provider and the architecture are deliberately dropped from the identifier.

Note

That last point is what makes this a class rather than a definition. Vagrant lists one row per (name, provider, version) triple, so a box installed in three versions appears three times, and the same is true of the outdated report. mpm keys a package on its id alone, so both listings are reduced here to one entry per name, keeping the newest version installed.

Caution

Every box command reads the registry under ~/.vagrant.d and needs no Vagrantfile, with two exceptions that are avoided rather than handled: vagrant box outdated inspects only the boxes the current directory’s Vagrantfile declares unless --global is passed, and vagrant box update is scoped the same way unless --box names one. Both forced flags are therefore load-bearing: without them the answer would depend on where mpm happened to be invoked, and would fail outright outside a Vagrant project.

One piece of ambient state cannot be escaped: Vagrant evaluates the Vagrantfile’s trigger configuration on every subcommand, so a malformed Vagrantfile in the working directory breaks even box list. Only the version probe is immune.

Note

No upgrade --all: Vagrant has no command that updates every installed box, box update addressing either one named box or the current project’s. mpm backfills it from outdated plus the per-box upgrade instead.

No sync either, there being no command that refreshes box metadata without also downloading, and the machine-readable output mode is unusable for boxes: it emits four lines per box with an empty target column, so nothing correlates them back into a record.

Documentation: Vagrant boxes.

Initialize cli_errors list.

maintenance_note: str | None = 'Upstream has slowed: the last stable release is `2.4.9` of August 2025, though the repository is still committed to. Note also that Vagrant is distributed under the Business Source License from `2.4.3` onwards, which some distributions treat as non-free.'

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

name: str = 'Vagrant'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://www.vagrantup.com'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.4.0'

The release whose listing groups boxes and renders the architecture as a trailing parenthesized segment, which is the shape _INSTALLED_REGEXP parses.

extra_env: ClassVar = {'VAGRANT_CHECKPOINT_DISABLE': '1'}

Additional environment variables to add to the current context.

Automatically applied on each meta_package_manager.execution.CLIExecutor.run_cli() calls.

version_regexes: tuple[str, ...] = ('^Vagrant[ \\t]+(?P<version>\\S+)$',)

Search the version right after the Vagrant string.

$ vagrant --version
Vagrant 2.4.9

Note the dashes: vagrant version without them is a different command that queries the network for the latest release.

property installed: Iterator[Package]

Fetch installed packages.

$ vagrant box list
linuxmint-21.3-cinnamon-64bit (hyperv, 0)
mintv1                        (hyperv, 0)
wolvverine/LinuxMintCinnamon  (hyperv, 1.1, (amd64))
property outdated: Iterator[Package]

Fetch outdated packages.

--global is what makes this answer for the machine: without it Vagrant reports only the boxes the working directory’s Vagrantfile declares, and fails where there is none.

Caution

Vagrant exits zero whether or not updates were found, by an explicit upstream decision, so the listing itself is the only signal.

$ vagrant box outdated --global
* 'ubuntu/jammy64' for 'virtualbox' is outdated! Current: 20231012.0.0. Latest: 20240126.0.0
* 'ubuntu/jammy64' for 'virtualbox' is outdated! Current: 20230914.0.0. Latest: 20240126.0.0
* 'ubuntu/jammy64' for 'virtualbox' is outdated! Current: 20230616.0.0. Latest: 20240126.0.0
search(query, extended, exact)[source]

Fetch matching packages.

Boxes have no search of their own: the query goes to the registry through Vagrant’s cloud command tree, which answers anonymously unless credentials are explicitly requested.

Caution

Search does not support extended or exact matching.

$ vagrant cloud search ubuntu --json
[
  {
    "name": "ubuntu/jammy64",
    "version": "20240126.0.0",
    "downloads": "1,234,567",
    "providers": "virtualbox",
    "architectures": "amd64"
  }
]
Return type:

Iterator[Package]

cli_names: tuple[str, ...] = ('vagrant',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'vagrant'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

install(package_id, version=None)[source]

Install one package.

$ vagrant box add ubuntu/jammy64
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

--box names the box explicitly, which is what lets this run outside a Vagrant project: the bare form updates whatever the current directory’s Vagrantfile declares instead.

$ vagrant box update --box ubuntu/jammy64
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

--all removes every version, provider and architecture of the box in one call. It is what keeps this addressable by a bare name: without it Vagrant refuses a box held in several versions and demands an explicit --box-version. --force skips the confirmation Vagrant would otherwise ask for a box still attached to a machine.

$ vagrant box remove --force --all ubuntu/jammy64
Return type:

str

cleanup_orphan()[source]

Removes outdated versions of installed boxes.

Keeps the newest version of each box and drops the rest. --force skips the confirmation Vagrant asks when a stale version is still attached to a machine, which would otherwise abort for want of a terminal.

$ vagrant box prune --force
Return type:

None

meta_package_manager.managers.vcpkg module

class meta_package_manager.managers.vcpkg.VCPKG[source]

Bases: PackageManager

C and C++ library manager, covering what it installs machine-wide.

vcpkg has two modes and only one is a package manager in mpm’s sense. In manifest mode it reads a vcpkg.json from a project tree and installs beside it, which is project scope and out of scope here, recorded among the project-scoped ecosystems of Unsupported managers. In classic mode it installs into its own root, shared by everything on the machine, which Microsoft’s own documentation compares to brew or apt. That mode is what this wraps, on the same footing as the runtime managers mpm wraps for what they install globally.

Important

--classic is forced on every invocation, and it is the whole basis of that scoping. vcpkg otherwise searches upwards from the working directory for a vcpkg.json and silently switches modes on finding one, so a listing taken inside a C++ project would report that project’s dependencies instead of the machine’s. Unlike the equivalent levers on other managers, this one is a documented, stable switch rather than a workaround.

Caution

A package is identified by its full specification, name:triplet, because that is vcpkg’s own unit: the same library built for two triplets is two installations, removed independently. Search results are named without a triplet, since nothing is installed yet and a bare name resolves against the default triplet at install time.

Note

The inventory is read as JSON rather than from the human listing, which cannot be parsed safely: that listing pads the specification to a fixed fifty columns and truncates anything longer to exactly fifty characters, leaving no separator at all before the version. Real specifications exceed that width, so the rows whose identifier was already corrupted are also the rows a whitespace split would silently misread.

Warning

A vcpkg binary on PATH is not necessarily a working one. vcpkg is normally cloned and bootstrapped, and a packaged binary with no root configured errors on every operation asking for VCPKG_ROOT to be set. Homebrew ships exactly that, and says so in its own caveats. The failure is loud and self-explanatory rather than silent.

Documentation: vcpkg classic mode.

Initialize cli_errors list.

name: str = 'vcpkg'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://vcpkg.io'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = None

No floor, because vcpkg’s version is a release date rather than a semantic version and a requirement here is written in digits and comparisons alone, which a hyphenated date cannot be.

Nothing is lost by it. Every interface used here shipped alongside manifest mode in 2020, so no release a user could plausibly be running lacks them, and a floor could not catch the case that would matter anyway: a locally built vcpkg reports a sentinel date far in the future precisely so that version checks in scripts always pass.

pre_args: tuple[str, ...] = ('--classic',)

Pins every call to the machine-wide installation, whatever the working directory contains.

version_regexes: tuple[str, ...] = ('version (?P<version>\\d{4}-\\d{2}-\\d{2})',)

Search the release date the version banner reports.

$ vcpkg --classic version
vcpkg package management program version 2026-07-27-unknownhash

See LICENSE.txt for license information.

The trailing component is a commit hash, or a packager’s own marker, and is dropped.

property installed: Iterator[Package]

Fetch installed packages.

$ vcpkg --classic list --x-json
{
  "zlib:x64-linux": {
    "package_name": "zlib",
    "triplet": "x64-linux",
    "version": "1.3.1",
    "port_version": 0,
    "features": [],
    "desc": ["A compression library"]
  }
}

The port revision is appended to the version as vcpkg itself renders it, and only when it is not zero.

property outdated: Iterator[Package]

Fetch outdated packages.

vcpkg’s update is a report rather than a mutation: in classic mode it compares what is installed against the ports catalog and prints the difference, changing nothing. It refuses to run in manifest mode at all, which the forced --classic keeps it out of.

$ vcpkg --classic update
Using local port versions. To update the local ports, use ``git pull``.
The following packages differ from their port versions:
        corrade:x64-windows              2020.06#4 -> 2020.06#5
        openal-soft:x64-windows          1.22.2#5 -> 1.23.0
cli_names: tuple[str, ...] = ('vcpkg',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'vcpkg'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

search(query, extended, exact)[source]

Fetch matching packages.

Read as JSON, whose keys are the port names. The human listing computes its column widths from the results and renders a port’s features as rows of their own carrying no version, neither of which a single pattern reads reliably.

Caution

Search does not support extended or exact matching.

Caution

--x-json is experimental, as its x prefix announces, and a vcpkg predating it ignores it silently rather than refusing it: the command succeeds and prints the human column listing instead. Decoding that as JSON raises, and since nothing isolates one manager’s failure from the rest of a fan-out, the exception took down an entire mpm search on any host carrying such a build. A version floor could not have caught it, vcpkg numbering its releases by date, as requirement explains, so the column listing is parsed instead when the JSON does not decode.

Falling back rather than merely reporting the loss matters beyond search: install picks its manager by searching first, so a vcpkg whose search answers nothing can install nothing either.

$ vcpkg --classic search excel --x-json
cpr                      1.14.2           C++ Requests is a simple wrapper around libcurl
cpr[ssl]                                  Enable SSL support
duckdb[excel]                             Statically link the excel extension into DuckDB
freexl                   2.0.0#2          FreeXL is an open source library to extract valid data
Return type:

Iterator[Package]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

install(package_id, version=None)[source]

Install one package.

A bare name resolves against the default triplet; a full specification pins the one it names.

$ vcpkg --classic install zlib:x64-linux
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

--no-dry-run is required for vcpkg to act at all: without it the command prints its plan, warns, and exits non-zero.

$ vcpkg --classic upgrade --no-dry-run
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

$ vcpkg --classic upgrade --no-dry-run zlib:x64-linux
Return type:

tuple[str, ...]

remove(package_id)[source]

Removes a package.

--recurse is deliberately not passed. vcpkg refuses to remove a package other installations depend on, listing them and exiting non-zero, and that refusal is the right outcome: the alternative would quietly remove packages the user never named.

$ vcpkg --classic remove zlib:x64-linux
Return type:

str

meta_package_manager.managers.vim_pack module

meta_package_manager.managers.vim_pack.PLUGIN_LIST = 'vim.pack.get(nil, {info = false})'

Lua expression listing every plugin vim.pack manages.

info is turned off on purpose: the extra payload it gathers (the Git branches and tags available for each plugin) costs one Git invocation per plugin and holds nothing mpm reports.

meta_package_manager.managers.vim_pack.lua_string(value)[source]

Render value as a Lua string literal.

JSON string syntax is a subset of Lua’s, so json.dumps() quotes and escapes any plugin URL into a valid Lua literal. ensure_ascii is turned off because Lua has no \uXXXX escape: a non-ASCII source must stay verbatim UTF-8.

Return type:

str

meta_package_manager.managers.vim_pack.lua_command(body)[source]

Wrap a Lua body into the -c argument handed to Neovim.

The trailing os.exit(0) is the success path: it terminates Neovim before the failure gate in Vim_Pack.post_args can run.

Return type:

str

meta_package_manager.managers.vim_pack.lua_resolve(package_id, action)[source]

Lua resolving a src URL to its plugin name, then running action.

vim.pack.del() and vim.pack.update() both address plugins by the short name Neovim derives from the source URL, while mpm keys packages on the URL itself. The mapping is looked up in vim.pack.get() output rather than recomputed here, so a plugin whose spec overrides its name still resolves. A URL that matches nothing leaves the loop a no-op, which keeps removing an absent plugin idempotent.

Return type:

str

class meta_package_manager.managers.vim_pack.Vim_Pack[source]

Bases: PackageManager

Neovim’s built-in plugin manager.

vim.pack is a Lua API shipped in Neovim’s core since 0.12, not a standalone binary: each operation below is a Lua one-liner evaluated by a throw-away Neovim process. Plugins are Git clones under stdpath('data')/site/pack/core/opt, pinned by a nvim-pack-lock.json lock file in stdpath('config').

Note

Every invocation runs --clean, so the user’s init.lua is never sourced. vim.pack.get() reads the lock file rather than the current session, so the inventory stays complete without paying for, nor being perturbed by, a full editor startup. stdpath() is XDG-derived and --clean does not move it, so both the lock file and the plugin directory still resolve.

Caution

Neovim exits 0 even when a -c command raises, which would hide every failure from mpm. Vim_Pack.post_args therefore closes each invocation with -c 'cquit': on success the Lua payload has already called os.exit(0), and on error control falls through to that gate and Neovim exits 1.

Caution

Installing a plugin registers it in the lock file and clones it to disk, but mpm does not edit the user’s init.lua. A plugin installed through mpm is therefore on disk but not loaded by the next editor start until a matching vim.pack.add() call is added to the configuration.

Note

Packages are keyed on their src URL. vim.pack accepts no registry shorthand: Vim_Pack.install() needs a URL while Vim_Pack.remove() and Vim_Pack.upgrade_one_cli() address plugins by the short name Neovim derives from it, so the URL is the only identifier mpm can feed back into every operation. Package ids therefore round-trip through install, remove, upgrade and backup/restore.

Note

No outdated: vim.pack exposes no read-only “list upgradable” call. vim.pack.update() fetches and then either applies the new revisions or renders them into a confirmation buffer, neither of which mpm can consume as a query, so mpm auto-skips the operation and upgrade --all still works.

Initialize cli_errors list.

name: str = 'Neovim vim-pack'

Spelled with a dash: manager names are restricted to letters, digits, spaces, apostrophes and dashes, so the vim.pack API name cannot be used verbatim.

homepage_url: str | None = 'https://neovim.io/doc/user/pack.html'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=0.12.0'

vim.pack landed in Neovim 0.12.

cli_names: tuple[str, ...] = ('nvim',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('--clean', '--headless')
post_args: tuple[str, ...] = ('-c', 'cquit')

Failure gate, only reached when the Lua payload raised before reaching its own os.exit(0).

version_regexes: tuple[str, ...] = ('NVIM\\s+v(?P<version>\\S+)',)
$ nvim --version
NVIM v0.12.4
Build type: Release
LuaJIT 2.1.1785763465
id: str = 'vim-pack'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

property installed: Iterator[Package]

Fetch installed packages.

The rev reported for each plugin is the Git commit it is checked out at, which is the only revision vim.pack records: a plugin is pinned to a branch, tag or version range, and the lock file stores the commit that resolved to.

$ nvim --clean --headless \
> -c 'lua io.write(vim.json.encode(vim.pack.get(nil, {info = false}))) os.exit(0)' \
> -c 'cquit'
[{"active":false,"rev":"0ce2d843d6f588bb0c8c7eec6449171615dc56d9","spec":{"name":"vim-sensible","src":"https://github.com/tpope/vim-sensible"},"path":"/home/kev/.local/share/nvim/site/pack/core/opt/vim-sensible"},{"active":false,"rev":"a2e1f2b2e2e5a4c1d0f9b8a7c6d5e4f3a2b1c0d9","spec":{"name":"plenary.nvim","src":"https://github.com/nvim-lua/plenary.nvim"},"path":"/home/kev/.local/share/nvim/site/pack/core/opt/plenary.nvim"}]
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

install(package_id, version=None)[source]

Install one package.

Loading is turned off so the freshly cloned plugin’s own code is not sourced into the throw-away process mpm drives.

$ nvim --clean --headless \
> -c 'lua vim.pack.add({{src = "https://github.com/tpope/vim-sensible"}}, {confirm = false, load = false}) os.exit(0)' \
> -c 'cquit'
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ nvim --clean --headless \
> -c 'lua vim.pack.update(nil, {force = true}) os.exit(0)' \
> -c 'cquit'
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ nvim --clean --headless \
> -c 'lua for _, p in ipairs(vim.pack.get(nil, {info = false})) do if p.spec.src == "https://github.com/tpope/vim-sensible" then vim.pack.update({p.spec.name}, {force = true}) end end os.exit(0)' \
> -c 'cquit'
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ nvim --clean --headless \
> -c 'lua for _, p in ipairs(vim.pack.get(nil, {info = false})) do if p.spec.src == "https://github.com/tpope/vim-sensible" then vim.pack.del({p.spec.name}, {force = true}) end end os.exit(0)' \
> -c 'cquit'
Return type:

str

meta_package_manager.managers.volta module

class meta_package_manager.managers.volta.Volta[source]

Bases: PackageManager

Volta manages JavaScript command-line tools, installing each package from the npm registry into its own isolated image pinned to a specific Node runtime.

Tools installed with volta install never land in npm’s global prefix: Volta keeps them under its own VOLTA_HOME layout and exposes their binaries through shims on PATH. The npm executable found on a Volta-equipped host is itself such a shim, and npm --global operations do not see Volta-managed tools, hence this dedicated backend (requested in #1995).

Volta has no command listing outdated packages, so outdated (and with it the synthesized upgrade --all) is unsupported: upgrades are targeted, by reinstalling the latest release of a named package.

Initialize cli_errors list.

unmaintained: bool = True

A manager whose upstream project is no longer maintained.

Covers projects that are officially retired and those we infer are abandoned: archived on their forge, left without a release or commit for years, formally superseded by a successor, or part of a discontinued platform. See the stability policy in CLAUDE.md for the full criteria.

An unmaintained manager is hidden from package selection by default (you can still use it by explicitly calling for it on the command line), and is exempt from the project stability policy: it may be dropped, in part or in full, in any release and without notice, once keeping it working becomes too burdensome.

Unmaintained managers are kept out of the functional and integration test matrices, so an unreliable or flaky one never blocks a release and we save CI resources. The commitment is to keep the wrapper for as long as that stays cheap: the cheap static invariants (ID format, attribute ordering, …) still apply for as long as the manager’s code lives in the source tree, to keep that code valid.

Every unmaintained manager must document itself through unmaintained_message.

unmaintained_message: str | None = "Volta's maintainers [declared the project unmaintained on 2025-11-14](https://github.com/volta-cli/volta/issues/2080) and recommend migrating to [`mise`](https://mise.jdx.dev). The final release, [`2.0.2`](https://github.com/volta-cli/volta/releases/tag/v2.0.2), dates back to 2024-12-05."

Evidence and rationale for the unmaintained flag, as a MyST markdown block.

Rendered into the documentation (the manager’s page, and a ⚠️ marker in the manager tables). May embed markdown links to the archival notice, the successor project, or the discontinuation announcement. Required for every manager whose unmaintained flag is set, and only meaningful on such managers. Enforced by test_unmaintained.

homepage_url: str | None = 'https://volta.sh'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.0.2'

1.0.2 ships the fixes making volta list report correct information (volta-cli/volta#778 and volta-cli/volta#926), the listing this backend parses. The plain output format itself is stable from 1.0 through the final 2.0.2 release.

cli_search_path: tuple[str, ...] = ('~/.volta/bin',)

VOLTA_HOME/bin, where the official install script places the volta binary on Linux and macOS. Windows installers register the binary on PATH themselves.

property installed: Iterator[Package]

Fetch installed packages.

volta list all --format plain prints one line per tool. Only package lines carrying the (default) marker are retained: they are the globally-installed npm packages Volta manages through volta install and volta uninstall. runtime (Node) and package-manager (npm, pnpm, Yarn) lines are pinned toolchain components Volta cannot uninstall, so they are kept out of the inventory. So is a package shadowed by the working directory’s own JavaScript project: it renders with project placeholders instead of versions, so run mpm outside a project tree for the full global inventory.

The sample below is derived from the format’s unit tests in Volta’s plain.rs and the trace of #1995:

$ volta list all --format plain
runtime node@12.4.0 (default)
package-manager npm@6.13.4 (default)
package-manager yarn@1.16.0 (default)
package @larksuite/cli@1.0.79 / lark-cli / node@12.4.0 npm@built-in (default)
package ember-cli@3.10.0 / ember / node@12.4.0 npm@built-in (default)
package typescript@3.4.1 / tsc, tsserver / node@12.4.0 npm@built-in (default)
cli_names: tuple[str, ...] = ('volta',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'volta'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

install(package_id, version=None)[source]

Install one package.

Volta pins exact versions natively through npm’s name@version spec syntax; a bare name resolves to the latest release.

$ volta install typescript@3.4.1
Return type:

str

name: str = 'Volta'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the package provided as parameter.

Volta has no dedicated upgrade command for packages: reinstalling a bare name fetches the latest release and swaps it in as the new default.

$ volta install ember-cli
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ volta uninstall ember-cli
Return type:

str

meta_package_manager.managers.winget module

class meta_package_manager.managers.winget.WinGet[source]

Bases: PackageManager

Microsoft’s official Windows package manager.

mpm reads inventory from winget list --details, whose Key: Value blocks carry the installed version and an Available Upgrades section, and reads search from winget’s fixed-width column table.

Note

installed and outdated keep only rows whose Origin Source is winget, dropping packages winget merely tracks (sideloaded, portable or Microsoft Store). Store entries still surface in search, but their real version cannot be queried through winget, so mpm tags them with an msstore sentinel version and sorts them below winget-native ones.

Warning

Two Windows-only, process-level workarounds keep winget from taking the calling process down with it:

  • winget is spawned with DETACHED_PROCESS. Its COM server and installer children call GenerateConsoleCtrlEvent as they shut down, broadcasting a CTRL_C_EVENT to every process sharing their console: detaching removes winget from that console, so the signal never reaches the caller.

  • WindowsPackageManagerServer.exe is killed by image name after each call. This COM server is activated out-of-process, so it never inherits mpm’s pipes and is never reaped by communicate().

Initialize cli_errors list.

homepage_url: str | None = 'https://github.com/microsoft/winget-cli'

Home page of the project, only used in documentation for reference.

brewfile_entry_type: ClassVar[str | None] = 'winget'

Name of the Brewfile DSL entry type this manager maps to, or None if the manager has no Brewfile equivalent.

Set by the subset of managers Homebrew Bundle’s DSL covers, and consumed by meta_package_manager.brewfile when rendering the output of mpm dump --brewfile. Which manager maps to which entry is tabulated from these declarations in Snapshot and export, section “Brewfile”, where the export’s own quirks are documented too.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='windows', name='Windows')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.28.190'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

post_args: tuple[str, ...] = ('--accept-source-agreements', '--disable-interactivity')
--accept-source-agreements:

Used to accept the source license agreement, and avoid the following prompt:

> winget list
The "msstore' source requires that you view the following agreements before using.
Terms of Transaction: https://aka.ms/microsoft-store-terms-of-transaction
The source requires the current machine's 2-letter geographic region to be sent to the backend service to function prope rly (ex. "US").

Do you agree to all the source agreements terms?
[Y] Yes [N] No:
--disable-interactivity:

Disable interactive prompts.

Todo

Add the --no-progress option once it is available in the stable release:

version_regexes: tuple[str, ...] = ('v(?P<version>\\S+)',)
> winget --version
v1.28.220
windows_creation_flags: int = 0

Detach winget from the calling process’s console.

When winget runs, the Windows COM infrastructure activates WindowsPackageManagerServer.exe as a separate process. Installer EXEs launched by winget upgrade or winget install are also spawned as grandchildren. Both the COM server and any installer EXEs call GenerateConsoleCtrlEvent(0) during their own shutdown, which broadcasts a CTRL_C_EVENT to every process sharing the same console — including the Python test runner — causing it to exit with code 1 even after all tests pass.

DETACHED_PROCESS breaks the shared-console link: winget has no console, so neither the COM server nor any installer EXE can broadcast console events that reach us. Output is still captured because stdout and stderr are redirected to pipes, which are independent of console attachment.

windows_processes_to_cleanup: tuple[str, ...] = ('WindowsPackageManagerServer.exe',)

Kill winget’s COM server after each call.

WindowsPackageManagerServer.exe is activated by the Windows COM infrastructure when winget runs, not as a direct child process. It therefore does not inherit our pipe handles and is not reaped by communicate(). Kill it by image name after each call to avoid accumulating orphan COM server processes.

property installed: Iterator[Package]

Fetch installed packages.

> winget list --details --accept-source-agreements --disable-interactivity
(1/7) CCleaner [CCleaner]
Version: 6.08
Publisher: Piriform Software Ltd
Local Identifier: ARP\Machine\X64\CCleaner
Product Code: CCleaner
Installer Category: exe
Installed Scope: Machine
Installed Architecture: X64
Installed Locale: en-US
Origin Source: winget
Available Upgrades:

(2/7) Git [Git.Git]
Version: 2.37.3
Publisher: The Git Development Community
Origin Source: winget

Only returns packages with Origin Source: winget to exclude packages installed via other sources (e.g., sideload, portable).

property outdated: Iterator[Package]

Fetch outdated packages.

> winget list --upgrade-available --details --accept-source-agreements --disable-interactivity
(1/4) Git [Git.Git]
Version: 2.37.3
Publisher: The Git Development Community
Origin Source: winget
Available Upgrades:
  winget [2.45.1]

(2/4) Microsoft Edge [Microsoft.Edge]
Version: 109.0.1518.70
Publisher: Microsoft
Origin Source: winget
Available Upgrades:
  winget [125.0.2535.51]

Only returns packages with Origin Source: winget to exclude packages installed via other sources (e.g., sideload, portable).

search(query, extended, exact)[source]

Fetch matching packages.

> winget search --query vscode --accept-source-agreements --disable-interactivity
Name                             Id                               Version      Match               Source
---------------------------------------------------------------------------------------------------------
Microsoft Visual Studio Code     Microsoft.VisualStudioCode       1.89.1       Moniker: vscode     winget
MrCode                           zokugun.MrCode                   1.82.0.23253 Tag: vscode         winget
VSCodium Insiders                VSCodium.VSCodium.Insiders       1.88.0.24095 Tag: vscode         winget
VSCodium                         VSCodium.VSCodium                1.89.1.24130 Tag: vscode         winget
Upgit                            pluveto.Upgit                    0.2.18       Tag: vscode         winget
vscli                            michidk.vscli                    0.3.0        Tag: vscode         winget
Huawei QuickApp IDE              Huawei.QuickAppIde               14.0.1       Tag: vscode         winget
TheiaBlueprint                   EclipseFoundation.TheiaBlueprint 1.44.0       Tag: vscode         winget
Codium                           Alex313031.Codium                1.86.2.24053 Tag: vscode         winget
Cursor Editor                    CursorAI,Inc.Cursor              latest       Tag: vscode         winget
Microsoft Visual Studio Code CLI Microsoft.VisualStudioCode.CLI   1.89.1       Moniker: vscode-cli winget
> winget search --query vscode --exact --accept-source-agreements --disable-interactivity
Name                         Id                               Version      Match           Source
-------------------------------------------------------------------------------------------------
Microsoft Visual Studio Code Microsoft.VisualStudioCode       1.89.1       Moniker: vscode winget
MrCode                       zokugun.MrCode                   1.82.0.23253 Tag: vscode     winget
VSCodium Insiders            VSCodium.VSCodium.Insiders       1.88.0.24095 Tag: vscode     winget
VSCodium                     VSCodium.VSCodium                1.89.1.24130 Tag: vscode     winget
Upgit                        pluveto.Upgit                    0.2.18       Tag: vscode     winget
vscli                        michidk.vscli                    0.3.0        Tag: vscode     winget
Huawei QuickApp IDE          Huawei.QuickAppIde               14.0.1       Tag: vscode     winget
TheiaBlueprint               EclipseFoundation.TheiaBlueprint 1.44.0       Tag: vscode     winget
Codium                       Alex313031.Codium                1.86.2.24053 Tag: vscode     winget
Cursor Editor                CursorAI,Inc.Cursor              latest       Tag: vscode     winget
> winget search --id VSCodium.VSCodium --accept-source-agreements --disable-interactivity
Name              Id                         Version      Source
----------------------------------------------------------------
VSCodium Insiders VSCodium.VSCodium.Insiders 1.88.0.24095 winget
VSCodium          VSCodium.VSCodium          1.89.1.24130 winget
> winget search --name Codium --accept-source-agreements --disable-interactivity
Name              Id                         Version      Source
----------------------------------------------------------------
Codium            Alex313031.Codium          1.86.2.24053 winget
VSCodium Insiders VSCodium.VSCodium.Insiders 1.88.0.24095 winget
VSCodium          VSCodium.VSCodium          1.89.1.24130 winget
> winget search --id VSCodium.VSCodium --exact --accept-source-agreements --disable-interactivity
Name     Id                Version      Source
----------------------------------------------
VSCodium VSCodium.VSCodium 1.89.1.24130 winget
> winget search --name Codium --exact --accept-source-agreements --disable-interactivity
Name   Id                Version      Source
--------------------------------------------
Codium Alex313031.Codium 1.86.2.24053 winget
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

> winget install --id Microsoft.PowerToys --accept-package-agreements --accept-source-agreements --disable-interactivity
Found Power Toys [Microsoft.PowerToys] Version 0.15.2
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Successfully verified installer hash
Starting package install...
  ██████████████████████████████  100%
Successfully installed
Return type:

str

cli_names: tuple[str, ...] = ('winget',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'winget'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'WinGet'

Return package manager’s common name.

Default value is based on class name.

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

> winget update --all --accept-package-agreements --accept-source-agreements --disable-interactivity
Name                            Id                            Version       Available     Source
------------------------------------------------------------------------------------------------
Microsoft Edge                  Microsoft.Edge                109.0.1518.70 125.0.2535.51 winget
Microsoft Edge WebView2 Runtime Microsoft.EdgeWebView2Runtime 109.0.1518.70 125.0.2535.51 winget
Python Launcher                 Python.Launchez               < 3.12.0      3.12.0        winget
Microsoft Visual C++ (x86)...   Microsoft.VCRedist.2015+.X86  14.34.31931.0 14.38.33135.0 winget
4 upgrades available.

Installing dependencies:
This package requires the following dependencies:
  - Packages
      Microsoft.UI.Xaml.2.8 [>= 8.2306.22001.0]
(1/3) Found Microsoft Edge WebView2 Runtime [Microsoft.EdgeWebView2Runtime] Version 125. 0.2535.51
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://msedge.sf.dl.delivery.mp.microsoft.com/filestreamingservice/files/e5dd841e-17ff-43b7-a2c0-ff759f55c202/MicrosoftEdgeWebView2RuntimeInstallerARM64.exe
  ██████████████████████████████  166 MB /  166 MB
Successfully verified installer hash
Starting package install...
Successfully installed

(...)
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

> winget install --id Git.Git --accept-package-agreements --accept-source-agreements --disable-interactivity
Found Git [Git.Git] Version 2.45.1
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://github.com/git-for-windows/git/releases/download/v2.45.1.windows.1/Git-2.45.1-64-bit.exe
  ██████████████████████████████  64.7 MB / 64.7 MB
Successfully verified installer hash
Starting package install...
Successfully installed

Todo

Automatically uninstall the package if the technology is different:

> winget upgrade --id Microsoft.Edge
A newer version was found, but the install technology is different from the current version installed. Please uninstall the package and install the newer version.
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

> winget uninstall --id Microsoft.PowerToys --source winget --accept-source-agreements --disable-interactivity
Found PowerToys (Preview) [Microsoft.PowerToys]
Starting package uninstall...
  ██████████████████████████████  100%
Successfully uninstalled
Return type:

str

sync()[source]

Sync package metadata from remote sources.

> winget source update --accept-source-agreements --disable-interactivity
Return type:

None

meta_package_manager.managers.xbps module

class meta_package_manager.managers.xbps.XBPS[source]

Bases: PackageManager

X Binary Package System used by Void Linux.

Note

XBPS is split across several sibling binaries: xbps-query for read-only operations, xbps-install for installs, sync and upgrades, and xbps-remove for uninstalls and cache cleanup. mpm resolves the siblings from the same directory as cli_path.

Initialize cli_errors list.

name: str = 'Void XBPS'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/void-linux/xbps'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=0.59'

Version 0.59 is the first to ship the long-form options (--list-pkgs, --repository, --search, --update, --dry-run, --sync, --yes, --clean-cache, --remove-orphans) that the methods below depend on.

cli_names: tuple[str, ...] = ('xbps-install',)

Use xbps-install as the canonical entry point.

The other XBPS binaries (xbps-query, xbps-remove) are looked up in the same directory as xbps-install via cli_path.

property installed: Iterator[Package]

Fetch installed packages.

$ xbps-query --list-pkgs
ii base-files-0.144_1            Void Linux base system files
ii cmark-gfm-0.29.0.gfm.13_1     CommonMark parsing and rendering library
ii curl-8.5.0_1                  Command line tool for transferring data
property outdated: Iterator[Package]

Fetch outdated packages.

Caution

Reads from the local repository cache. Run sync() first to refresh the index.

$ xbps-install --update --dry-run
firefox-120.0_1 update x86_64 https://repo-default.voidlinux.org/current 45MB 12MB
python3-3.11.6_2 update x86_64 https://repo-default.voidlinux.org/current 30MB 8MB
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

$ xbps-query --list-orphans
libglvnd-1.7.0_1
orc-0.4.34_1
search(query, extended, exact)[source]

Fetch matching packages.

Caution

xbps-query --search matches against pkgver and short_desc properties at the same time. Extended and exact matching are not supported, so the best subset of results is returned and refined later by meta_package_manager.manager.PackageManager.refiltered_search().

$ xbps-query --repository --search firefox
[-] firefox-120.0_1            Standalone web browser from mozilla.org
[*] firefox-esr-115.5.0_1      Extended support release of Firefox
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo xbps-install --yes firefox
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

$ sudo xbps-install --sync --update --yes
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ sudo xbps-install --update --yes firefox
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package and one only.

$ sudo xbps-remove --yes firefox
Return type:

str

id: str = 'xbps'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

remove_orphan(package_id)[source]

Remove one package, recursively dropping orphaned dependencies.

$ sudo xbps-remove --recursive --yes firefox
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

sync()[source]

Synchronize remote repository indexes.

$ sudo xbps-install --sync --yes
Return type:

None

cleanup_orphan()[source]

Remove installed packages no longer required by any other, sparing the cache.

$ sudo xbps-remove --remove-orphans --yes
Return type:

None

cleanup_cache()[source]

Clean the binary package cache, sparing the orphans.

$ sudo xbps-remove --clean-cache --yes
Return type:

None

doctor_cli()[source]

Generates the CLI running the native self-diagnosis.

xbps-pkgdb --all checks the integrity of the package database and of every installed package, exiting non-zero on errors.

$ xbps-pkgdb --all
Return type:

tuple[str, ...]

meta_package_manager.managers.yarn module

class meta_package_manager.managers.yarn.Yarn[source]

Bases: PackageManager

Virtual base shared by Yarn Classic and Yarn Berry.

The two Yarn lines grew incompatible CLIs, so mpm models them as separate managers, YarnClassic and YarnBerry, both invoking the same yarn binary. The reported version decides which one is active: Classic claims the 1.x range, Berry 2.x and later. Only the shared cache-cleanup operation lives on this base.

Command equivalences with the sibling JS managers are listed in antfu-collective/ni.

Initialize cli_errors list.

homepage_url: str | None = 'https://yarnpkg.com'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

virtual: bool = True

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Removes things we don’t need anymore.

See yarn cache clean.

$ yarn cache clean --all
yarn cache v1.22.19
success Cleared cache.
✨  Done in 0.35s.
Return type:

None

cli_names: tuple[str, ...] = ('yarn',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'yarn'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Yarn'

Return package manager’s common name.

Default value is based on class name.

class meta_package_manager.managers.yarn.YarnClassic[source]

Bases: Yarn

Yarn Classic, the 1.x line.

mpm claims this class for any yarn binary reporting a 1.x version and drives it through the yarn global command family, so installs, upgrades and removals target the global prefix. Its --json output is a stream of one JSON object per line, not a single document, so every query is parsed line by line.

Note

Yarn has no dedicated search command by maintainer decision, so search is simulated with yarn info and only resolves exact package names.

Initialize cli_errors list.

maintenance_note: str | None = 'Yarn Classic (`1.x`) is [frozen](https://github.com/yarnpkg/yarn), taking only security fixes; the actively developed [Yarn Berry](https://github.com/yarnpkg/berry) line has a different CLI and is wrapped separately as the `yarn-berry` manager.'

A watch note about a still-maintained upstream whose activity is slowing or whose status is ambiguous, as a MyST markdown block.

Unlike unmaintained, this is purely informational: the manager stays in the default selection and in the test matrices. It renders as a {note} admonition atop the manager’s documentation page, flagging upstreams worth keeping an eye on (a slow release cadence, superseded-but-still-shipped tools, a discontinued platform still under vendor support). May embed markdown links. Mutually exclusive with unmaintained: a confirmed-dead manager carries an unmaintained_message instead. Enforced by test_maintenance_note.

id: str = 'yarn'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Yarn Classic'

Return package manager’s common name.

Default value is based on class name.

requirement: str | None = '>=1.20.0,<2.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cli_names: tuple[str, ...] = ('yarn',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

pre_args: tuple[str, ...] = ('--silent',)
property installed: Iterator[Package]

Fetch installed packages.

$ yarn global --json list --depth 0
{"type":"activityStart","data":{"id":0}}
{"type":"activityTick","data":{"id":0,"name":"awesome-lint@^0.18.0"}}
{"type":"activityTick","data":{"id":0,"name":"arrify@^2.0.1"}}
{"type":"activityTick","data":{"id":0,"name":"case@^1.6.3"}}
{"type":"activityTick","data":{"id":0,"name":"emoji-regex@^9.2.0"}}
{"type":"activityEnd","data":{"id":0}}
{"type":"progressStart","data":{"id":0,"total":327}}
{"type":"progressTick","data":{"id":0,"current":1}}
{"type":"progressTick","data":{"id":0,"current":2}}
{"type":"progressTick","data":{"id":0,"current":3}}
{"type":"progressTick","data":{"id":0,"current":4}}
{"type":"progressTick","data":{"id":0,"current":5}}
{"type":"progressFinish","data":{"id":0}}
{"type":"info","data":""awesome-lint@0.18.0" has binaries:"}
{"type":"list","data":{"type":"bins-awesome-lint","items":["awesome-lint"]}}
$ yarn global list --depth 0
yarn global v1.22.19
info "awesome-lint@0.18.0" has binaries:
   - awesome-lint
✨  Done in 0.13s.
property global_dir: str[source]

Locate the global directory.

$ yarn global dir
~/.config/yarn/global
property outdated: Iterator[Package]

Fetch outdated packages.

Yarn emits its --json output as a stream of one JSON object per line (the sample below elides the info color-legend object; the human-readable transcript further down shows it):

$ yarn --json outdated --cwd ~/.config/yarn/global
{"type":"warning","data":"package.json: No license field"}
{"type":"table","data":{"head":["Package","Current","Wanted","Latest","Package Type","URL"],"body":[["markdown","0.4.0","0.4.0","0.5.0","dependencies","git://github.com/evilstreak/markdown-js.git"]]}}
$ yarn outdated --cwd ~/.config/yarn/global
yarn outdated v1.22.19
warning package.json: No license field
info Color legend :
"<red>"    : Major Update backward-incompatible updates
"<yellow>" : Minor Update backward-compatible features
"<green>"  : Patch Update backward-compatible bug fixes
Package  Current Wanted Latest Package Type URL
markdown 0.4.0   0.4.0  0.5.0  dependencies git://github.com/.../md-js.git
✨  Done in 0.95s.
search(query, extended, exact)[source]

Fetch matching packages.

Warning

Yarn maintainers have decided to not implement a dedicated search command.

Search is simulated by a direct call to yarn info, and as a result only works for exact match.

$ yarn --json info python | jq
{
  "type": "inspect",
  "data": {
    "name": "python",
    "description": "Interact with python child process",
    "dist-tags": {
      "latest": "0.0.4"
    },
    "versions": [
      "0.0.0",
      "0.0.1",
      "0.0.2",
      "0.0.3",
      "0.0.4"
    ],
    "maintainers": [
      {
        "name": "drderidder",
        "email": "drderidder@gmail.com"
      }
    ],
    "time": {
      "modified": "2017-09-16T05:26:13.151Z",
      "created": "2011-07-11T01:59:04.362Z",
      "0.0.0": "2011-07-11T01:59:05.137Z",
      "0.0.1": "2011-07-17T05:23:33.166Z",
      "0.0.2": "2011-07-20T03:42:50.379Z",
      "0.0.3": "2014-06-08T00:39:08.562Z",
      "0.0.4": "2015-01-25T02:48:07.820Z"
    },
    "author": {
      "name": "Darren DeRidder"
    },
    "repository": {
      "type": "git",
      "url": "git://github.com/73rhodes/node-python.git"
    },
    "homepage": "https://github.com/73rhodes/node-python",
    "bugs": {
      "url": "https://github.com/73rhodes/node-python/issues"
    },
    "readmeFilename": "README.md",
    "users": {
      "dewang-mistry": true,
      "goliatone": true,
      "sapanbhuta": true,
      "aditcmarix": true,
      "imlucas": true,
      "heyderpd": true,
      "ukuli": true,
      "chbardel": true,
      "asaupup": true,
      "nuwaio": true
    },
    "version": "0.0.4",
    "main": "./lib/python.js",
    "engines": {
      "node": ">= 0.4.1"
    },
    "gitHead": "69754aaa57658193916a1bf5fc391198098f74f6",
    "scripts": {},
    "dist": {
      "shasum": "3094e898ef17a33aa9c3e973b3848a38e47d1818",
      "tarball": "https://registry.npmjs.org/python/-/python-1.tgz"
    },
    "directories": {}
  }
}
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ yarn --silent global add awesome-lint
yarn global v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...

success Installed "awesome-lint@0.18.0" with binaries:
    - awesome-lint
✨  Done in 16.15s.
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ yarn --silent global upgrade --latest
yarn global v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Rebuilding all packages...
success Saved lockfile.
success Saved 271 new dependencies.
info Direct dependencies
├─ awesome-lint@0.18.0
└─ markdown@0.5.0
info All dependencies
├─ @babel/code-frame@7.18.6
├─ @babel/helper-validator-identifier@7.18.6
├─ @nodelib/fs.scandir@2.1.5
├─ array-to-sentence@1.1.0
├─ array-union@2.1.0
├─ awesome-lint@0.18.0
├─ fs.realpath@1.0.0
(...)
└─ zwitch@1.0.5
✨  Done in 19.89s.
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ yarn --silent global upgrade markdown --latest
yarn global v1.22.19
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Rebuilding all packages...
success Saved lockfile.
success Saved 2 new dependencies.
info Direct dependencies
└─ markdown@0.5.0
info All dependencies
├─ markdown@0.5.0
└─ nopt@2.1.2
✨  Done in 1.77s.
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ yarn --silent global remove awesome-lint
yarn global v1.22.19
[1/2] 🗑  Removing module awesome-lint...
[2/2] 🔨  Regenerating lockfile and installing missing dependencies...
success Uninstalled packages.
✨  Done in 0.21s.
Return type:

str

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

class meta_package_manager.managers.yarn.YarnBerry[source]

Bases: Yarn

Yarn Berry, the 2.x and later line.

mpm claims this class for any yarn binary reporting a 2.x or newer version.

Warning

Yarn Berry removed the yarn global command family entirely: it has no notion of globally installed packages. Only search is available, while installed, outdated, install, upgrade and remove are all unsupported.

Note

search is simulated with yarn npm info and only resolves exact package names.

Initialize cli_errors list.

id: str = 'yarn-berry'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Yarn Berry'

Return package manager’s common name.

Default value is based on class name.

requirement: str | None = '>=2.0.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

cli_names: tuple[str, ...] = ('yarn',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

search(query, extended, exact)[source]

Fetch matching packages.

Warning

Search is simulated by a direct call to yarn npm info, and as a result only works for exact match.

$ yarn npm info python --json | jq
{
  "name": "python",
  "description": "Interact with python child process",
  "dist-tags": {
    "latest": "0.0.4"
  },
  "versions": [
    "0.0.0",
    "0.0.1",
    "0.0.2",
    "0.0.3",
    "0.0.4"
  ],
  "version": "0.0.4",
  (...)
}
Return type:

Iterator[Package]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

meta_package_manager.managers.zef module

class meta_package_manager.managers.zef.Zef[source]

Bases: PackageManager

Zef, the module manager of the Raku language.

A package is a Raku distribution, identified by the bare name its identity string opens with. Raku names are colon-separated (JSON::Fast) and the identity appends its own colon-prefixed fields to them (JSON::Fast:ver<0.20>:auth<zef:timo>), so every pattern here matches the name lazily up to the literal :ver< rather than splitting on colons.

Note

Two distributions may share a name and differ only by the auth field, and several versions of one may be installed side by side. mpm keys a package on its id alone, so both listings are reduced here to one entry per name, keeping the highest version. That reduction is what makes this a class rather than a bundled definition.

Note

Search compounds the same problem rather than avoiding it: it answers with a pipe-delimited table carrying one row per (distribution, version) pair, so a single module comes back once per release it has ever published.

Note

No outdated: zef reports no staleness of its own. upgrade covers both the bulk and the single-package cases natively, so neither is synthesized.

Documentation: zef README.

Initialize cli_errors list.

name: str = 'Zef'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/ugexe/zef'

Home page of the project, only used in documentation for reference.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='windows', name='Windows'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

version_regexes: tuple[str, ...] = ('^(?P<version>\\d+\\.\\d+\\.\\d+)',)

Search the bare version zef prints on its own.

$ zef --version
1.1.3
property installed: Iterator[Package]

Fetch installed packages.

$ zef list --installed
===> Found via inst#/opt/homebrew/Cellar/rakudo-star/2026.07/share/perl6/site
App::Prove6:ver<0.0.18>:auth<zef:leont>
Config::TOML:ver<0.1.3>:auth<zef:raku-community-modules>
Config:ver<3.0.4>:auth<cpan:TYIL>:api<3>
Crane:ver<0.1.2>:auth<zef:raku-community-modules>
Digest:ver<1.1.0>:auth<zef:grondilu>
search(query, extended, exact)[source]

Fetch matching packages.

Caution

Search does not support extended or exact matching.

$ zef search JSON::Fast
===> Found 50 results
-------------------------------------------------------------------------------
ID|From                            |Package                              |Description
-------------------------------------------------------------------------------
0 |Zef::Repository::Ecosystems<fez>|JSON::Fast:ver<0.20>:auth<zef:timo>  |A naive, fast json parser and serializer
1 |Zef::Repository::Ecosystems<fez>|JSON::Fast:ver<0.20.1>:auth<zef:timo>|A naive, fast json parser and serializer
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ zef install JSON::Fast::Hyper
===> Testing: hyperize:ver<0.0.4>:auth<zef:lizmat>
===> Testing [OK] for hyperize:ver<0.0.4>:auth<zef:lizmat>
===> Testing: JSON::Fast::Hyper:ver<0.0.11>:auth<zef:lizmat>
===> Testing [OK] for JSON::Fast::Hyper:ver<0.0.11>:auth<zef:lizmat>
===> Installing: hyperize:ver<0.0.4>:auth<zef:lizmat>
===> Installing: JSON::Fast::Hyper:ver<0.0.11>:auth<zef:lizmat>
Return type:

str

upgrade_all_cli()[source]

Generate the CLI to upgrade all packages.

$ zef upgrade
Return type:

tuple[str, ...]

cli_names: tuple[str, ...] = ('zef',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'zef'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

upgrade_one_cli(package_id, version=None)[source]

Generate the CLI to upgrade one package.

$ zef upgrade JSON::Fast
Return type:

tuple[str, ...]

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

remove(package_id)[source]

Remove one package.

$ zef uninstall JSON::Fast::Hyper
===> Uninstalled from inst#/opt/homebrew/Cellar/rakudo-star/2026.07/share/perl6/site
JSON::Fast::Hyper:ver<0.0.11>:auth<zef:lizmat>
Return type:

str

sync()[source]

Sync package metadata.

$ zef update
Return type:

None

meta_package_manager.managers.zim module

meta_package_manager.managers.zim.zim_source_path()[source]

Locate the init.zsh file every invocation sources.

Zim installs itself into $ZIM_HOME, falling back to ${ZDOTDIR:-${HOME}}/.zim when the variable is unset, exactly as its own installer and zimfw.zsh do. The path is returned whether or not it exists, so the built command stays well-formed and simply fails to source, which is what makes the version probe double as Zim’s presence check.

Return type:

Path

class meta_package_manager.managers.zim.Zim[source]

Bases: PackageManager

Zim is a configuration framework and module manager for Zsh.

Modules are declared in the user’s .zimrc, then cloned under $ZIM_HOME. Packages are identified by the module name Zim reports, which is the id mpm keys them on.

Caution

zimfw is a shell function, not a standalone binary: it is defined by sourcing $ZIM_HOME/init.zsh, and the zimfw.zsh script behind it carries no shebang. Every invocation is therefore wrapped in zsh -c. Zsh is the binary mpm executes, and Zim’s own presence is established by the version probe: a host with Zsh but no Zim fails to source and reports no version, which leaves the manager unavailable.

Caution

No install and no remove: Zim materializes exactly the module set the user’s own .zimrc declares. zimfw install fetches what that file already names and zimfw uninstall drops what it no longer names, so neither takes a module of mpm’s choosing. Installing one would mean mpm editing the user’s .zimrc, which is configuration mpm does not own. Both operations are therefore not implemented rather than faked, and mpm auto-skips them.

Note

No outdated: zimfw check does compare each module against its remote, but it reports through the same progress display as update rather than a parseable list, and no upstream sample pins its format down. upgrade –all still works and mpm auto-skips the operation.

Documentation: zimfw.

Initialize cli_errors list.

name: str = 'Zsh Zim'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://zimfw.sh'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=1.0.0'

Zim versions independently of Zsh, so no Zsh floor applies here.

The 1.x series is where zimfw became the single entry point carrying the list, update and version subcommands this class drives.

cli_names: tuple[str, ...] = ('zsh',)

Zsh is the binary mpm actually executes.

Zim is a shell function defined by an init.zsh file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable. Keying the manager on Zsh instead makes the version probe the presence check.

extra_env: ClassVar = {'NO_COLOR': '1', 'SHELL_SESSIONS_DISABLE': '1'}

NO_COLOR drops the bold Zim wraps every module name in, so the listing parses as clean text. SHELL_SESSIONS_DISABLE keeps macOS’ Zsh session bookkeeping from writing a session file on every query, as for Antidote.

id: str = 'zim'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

version_regexes: tuple[str, ...] = ('(?P<version>\\d+(?:\\.\\d+)+)',)

Zim prints its version bare, with no name or prefix around it.

Its version|--version case is a single print -R $:_zversion:`, so the regex is anchored on the shape of the version itself. The labeled `zimfw version:  ... string belongs to the separate zimfw info subcommand and is never what the probe reads.

$ zsh -c 'source ~/.zim/init.zsh && zimfw --version'
1.18.0
virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Zsh shell Zim needs.

The version probe is guarded by a readability test that exits successfully when init.zsh is absent. Zsh is the default shell on macOS and near ubiquitous elsewhere, so an unguarded probe would turn every host that merely has Zsh into a manager reporting errors. An init.zsh that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the zsh -c wrapper and Zim never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

Zim prints one module per line, suffixing each with the state flags that apply to it. Two of those flags mean the row is not an installed module and are skipped: (not installed) for a module the .zimrc declares but that was never fetched, and (unused) for a leftover directory no longer declared. (external), (frozen) and (disabled) all still describe installed modules and are kept.

$ zsh -c 'source ~/.zim/init.zsh && zimfw list'
environment
git
input
termtitle
utility
duration-info (frozen)
zsh-completions
upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

zimfw update re-reads the module set the user’s .zimrc declares and pulls each one.

$ zimfw update
Return type:

tuple[str, ...]

meta_package_manager.managers.zinit module

meta_package_manager.managers.zinit.zinit_source_path()[source]

Locate the zinit.zsh file every invocation sources.

Falls back to the current installer’s location when none of the candidates exists, so the built command stays well-formed and simply fails to source, which is what makes the version probe double as Zinit’s presence check.

Return type:

Path

class meta_package_manager.managers.zinit.Zinit[source]

Bases: PackageManager

Zinit is a flexible and fast Zsh plugin manager.

Zinit installs Zsh plugins, snippets and completions from GitHub and other forges, cloning each into $ZINIT[PLUGINS_DIR]. Packages are identified by the user/repo slug Zinit both reports and accepts, which is the id mpm keys them on. A plugin the user renamed through the id-as ice reports under that alias instead, and feeds back into every operation just the same.

Caution

zinit is a shell function, not a standalone binary, so every invocation is wrapped in zsh -c 'source <zinit.zsh> && zinit <args>'. Zsh is therefore the manager’s CLI, and Zinit’s own presence is established by the version probe: a host with Zsh but no Zinit fails to source and reports no version, which leaves the manager unavailable.

Caution

Zinit.installed() is the one operation that cannot use that wrapper. Zinit tracks plugins in shell state populated by the zinit load calls of the user’s .zshrc, so a freshly sourced non-interactive shell knows of none. That query therefore runs zsh --interactive, paying a full shell startup to inventory what the user’s Zsh actually loads. Plugins deferred with the wait ice (Zinit’s turbo mode) load asynchronously after the prompt would have been drawn, so a non-interactive run may miss them.

Note

No outdated: Zinit’s only “what would change” command is zinit status --all, which unconditionally runs .zinit-self-update first, pulling and recompiling Zinit itself. A query that mutates the manager is not a query, so mpm auto-skips the operation and upgrade --all still works.

Note

No search: Zinit resolves plugins straight from forge URLs and indexes no registry to search.

Initialize cli_errors list.

homepage_url: str | None = 'https://github.com/zdharma-continuum/zinit'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=3.10.0'

First release of the zdharma-continuum fork whose confirmation prompt, and thus the --yes flag Zinit.remove() depends on, behaves.

cli_names: tuple[str, ...] = ('zsh',)

Zsh is the binary mpm actually executes.

Zinit itself is a shell function defined by a zinit.zsh file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable, and that file ships non-executable. Keying the manager on Zsh instead makes the version probe the presence check, since sourcing an absent zinit.zsh yields no version and leaves the manager unavailable.

extra_env: ClassVar = {'SHELL_SESSIONS_DISABLE': '1'}

Keep macOS’ Zsh session bookkeeping from writing a session file on every query.

version_cli_options: tuple[str, ...] = ('version',)

CLI options used to produce the version of the package manager.

The raw output produced by the package manager CLI will be parsed with the version_regexes below to extract the version number.

version_regexes: tuple[str, ...] = ('zinit\\s+v(?P<version>\\S+)',)

Zinit reports the git describe of its own checkout, so a clone sitting past a tag reports a 3.15.0-5-gb1946ac flavored version.

$ zinit version
zinit v3.15.0 (darwin25.4.0_arm64)
id: str = 'zinit'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

name: str = 'Zinit'

Return package manager’s common name.

Default value is based on class name.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Zsh shell Zinit needs.

Three subcommands need a shell of their own shape, so the wrapper is chosen from the subcommand rather than being uniform.

plugins reads the plugin registry out of shell state that the zinit load calls of the user’s .zshrc populate, so it runs zsh --interactive and lets that file do the sourcing. Sourcing zinit.zsh again on top would reset the registry and report nothing.

load is prefixed with the cloneonly ice, which stops Zinit right after the clone. Installing a plugin otherwise sources it, running third-party shell code inside the process mpm drives.

version is guarded by a readability test that exits successfully when zinit.zsh is absent. Zsh is the default shell on macOS and near ubiquitous elsewhere, so an unguarded probe would turn every host that merely has Zsh into a manager reporting errors. A zinit.zsh that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the zsh -c wrapper and Zinit never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

Zinit reports no version alongside a plugin, so packages are yielded bare: pinning a plugin to a revision is an ice modifier of the user’s own zinit load call, not state Zinit surfaces in this listing.

$ zsh --interactive -c 'zinit plugins'
==> 3 Plugins

 1 L ~zinit/zinit.git

 2 L zdharma-continuum/fast-syntax-highlighting

 3 U zsh-users/zsh-completions


Loaded: L | Unloaded: U
install(package_id, version=None)[source]

Install one package.

Zinit conflates installing a plugin with sourcing it, so Zinit.build_cli() sets the cloneonly ice ahead of this call.

$ zinit load zdharma-continuum/null
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

Note

Zinit self-updates before updating anything else, so this also pulls and recompiles Zinit itself.

$ zinit update --all
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ zinit update zdharma-continuum/null
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ zinit delete --yes zdharma-continuum/null
Return type:

str

meta_package_manager.managers.zplug module

meta_package_manager.managers.zplug.zplug_source_path()[source]

Locate the init.zsh file every invocation sources.

zplug installs itself into $ZPLUG_HOME, falling back to ~/.zplug when the variable is unset, exactly as its own installer and documentation do. The path is returned whether or not it exists, so the built command stays well-formed and simply fails to source, which is what makes the version probe double as zplug’s presence check.

Return type:

Path

class meta_package_manager.managers.zplug.Zplug[source]

Bases: PackageManager

zplug is a plugin manager for Zsh.

Plugins are declared in the user’s .zshrc with zplug "user/repo" calls, then materialized under $ZPLUG_HOME/repos. Packages are identified by the user/repo slug zplug reports, which is the id mpm keys them on.

Caution

zplug is a shell function, not a standalone binary: it is defined by sourcing $ZPLUG_HOME/init.zsh, so it cannot serve as the manager’s CLI. Every invocation is therefore wrapped in zsh -c. Zsh is the binary mpm executes, and zplug’s own presence is established by the version probe: a host with Zsh but no zplug fails to source and reports no version, which leaves the manager unavailable.

Caution

No install and no remove: zplug materializes exactly the plugin set the user’s own .zshrc declares. zplug install clones what that file already names and zplug clean drops repositories it no longer names, so neither takes a plugin of mpm’s choosing. Installing one would mean mpm editing the user’s .zshrc, which is configuration mpm does not own. Both operations are therefore not implemented rather than faked, and mpm auto-skips them.

Note

No outdated: zplug status does check each plugin against its remote, but it reports through a progress display rather than a parseable list, and its output is not pinned by any upstream sample this implementation could be held to. upgrade --all still works and mpm auto-skips the operation.

Documentation: zplug.

Initialize cli_errors list.

name: str = 'Zsh zplug'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://github.com/zplug/zplug'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='debian', name='Debian'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='macos', name='macOS'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

requirement: str | None = '>=2.0.0'

The 2.x series is where the command set this class drives settled.

zplug list and the bare zplug update both date from the 2.0 rewrite that introduced $ZPLUG_HOME and the init.zsh entry point this manager sources.

cli_names: tuple[str, ...] = ('zsh',)

Zsh is the binary mpm actually executes.

zplug is a shell function defined by an init.zsh file that is sourced, never executed, so it cannot serve as the manager’s CLI: mpm requires an executable. Keying the manager on Zsh instead makes the version probe the presence check.

extra_env: ClassVar = {'NO_COLOR': '1', 'SHELL_SESSIONS_DISABLE': '1'}

NO_COLOR keeps zplug’s status glyphs out of the listing so the parser sees clean text. SHELL_SESSIONS_DISABLE keeps macOS’ Zsh session bookkeeping from writing a session file on every query, as for Antidote.

version_regexes: tuple[str, ...] = ('(?P<version>\\d+(?:\\.\\d+)+)',)

zplug prints its version bare, with no name or prefix around it.

Its --version handler is a single __zplug::io::print::put "$_ZPLUG_VERSION\n", so the regex is anchored on the shape of the version itself rather than on a surrounding label.

$ zsh -c 'source ~/.zplug/init.zsh && zplug --version'
2.4.2
id: str = 'zplug'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

build_cli(*args, **kwargs)[source]

Wrap all CLI invocations in the Zsh shell zplug needs.

The version probe is guarded by a readability test that exits successfully when init.zsh is absent. Zsh is the default shell on macOS and near ubiquitous elsewhere, so an unguarded probe would turn every host that merely has Zsh into a manager reporting errors. An init.zsh that is present but broken still fails loudly.

Note

The **kwargs accepted by the base class (auto_pre_args, sudo, etc.) are accepted but ignored because every invocation goes through the zsh -c wrapper and zplug never requires elevated privileges.

Return type:

tuple[str, ...]

property installed: Iterator[Package]

Fetch installed packages.

zplug prints one plugin per line as <package> => <tags>, the tags being the as:, from:, use: and frozen: annotations declared for it, or the literal nil when it carries none. Only the left-hand side is an identifier, and no version is reported anywhere: a plugin is a Git clone tracking a branch.

A plugin sourced from a local directory is listed by its absolute path instead, and is yielded under that path as its id.

$ zsh -c 'source ~/.zplug/init.zsh && zplug list'
zplug/zplug => nil
b4b4r07/zsh-gomi => as:command, use:bin/gomi
peco/peco => as:command, from:gh-r, frozen:1
upgrade_all_cli()[source]

Generates the CLI to upgrade all packages.

A bare zplug update re-reads the plugin set the user’s .zshrc declares and pulls each one.

$ zplug update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade one package.

$ zplug update b4b4r07/zsh-gomi
Return type:

tuple[str, ...]

meta_package_manager.managers.zypper module

class meta_package_manager.managers.zypper.Zypper[source]

Bases: PackageManager

openSUSE’s package manager.

mpm drives zypper in XML mode (--xmlout) and parses the result with xmltodict: the most stable machine-readable output zypper offers. Every call is pinned with --no-color and --no-abbrev (untruncated columns), --non-interactive for unattended runs, and --no-cd --no-refresh so it never touches removable media or auto-refreshes metadata (mpm refreshes explicitly through sync).

Note

Both installed and search run search --details --type package: --details is the only mode exposing versions, but it returns one row per source package, architecture and past release. mpm drops other-version rows and keeps the highest edition per package name to collapse those duplicates.

Documentation:

Initialize cli_errors list.

name: str = 'openSUSE Zypper'

Return package manager’s common name.

Default value is based on class name.

homepage_url: str | None = 'https://en.opensuse.org/Portal:Zypper'

Home page of the project, only used in documentation for reference.

Slug of the brand mark standing for this manager in the documentation.

Names an SVG vendored under docs/assets/managers/, whose provenance and license are recorded in docs/assets/managers/logos.yaml. Inlined at the top of the manager’s page by meta_package_manager._docs; a manager leaving it unset keeps the page’s default package glyph.

Several managers legitimately share one slug, either because they wrap the same upstream (brew and cask) or because the tool has no mark of its own and its ecosystem’s stands in (apt under Debian’s swirl, cargo under Rust’s gear). Documentation-only, like homepage_url: no CLI output reads it.

platforms: frozenset[Platform] | Group | Platform | Iterable[Platform | Group] = frozenset({Platform(id='aix', name='IBM AIX'), Platform(id='almalinux', name='AlmaLinux'), Platform(id='alpine', name='Alpine Linux'), Platform(id='altlinux', name='ALT Linux'), Platform(id='amzn', name='Amazon Linux'), Platform(id='android', name='Android'), Platform(id='arch', name='Arch Linux'), Platform(id='buildroot', name='Buildroot'), Platform(id='cachyos', name='CachyOS'), Platform(id='centos', name='CentOS'), Platform(id='chromeos', name='ChromeOS'), Platform(id='clearlinux', name='Clear Linux OS'), Platform(id='cloudlinux', name='CloudLinux OS'), Platform(id='cygwin', name='Cygwin'), Platform(id='debian', name='Debian'), Platform(id='dragonfly_bsd', name='DragonFly BSD'), Platform(id='endeavouros', name='EndeavourOS'), Platform(id='exherbo', name='Exherbo Linux'), Platform(id='fedora', name='Fedora'), Platform(id='freebsd', name='FreeBSD'), Platform(id='generic_linux', name='Generic Linux'), Platform(id='gentoo', name='Gentoo Linux'), Platform(id='guix', name='Guix System'), Platform(id='haiku', name='Haiku'), Platform(id='hurd', name='GNU/Hurd'), Platform(id='ibm_powerkvm', name='IBM PowerKVM'), Platform(id='illumos', name='illumos'), Platform(id='kali', name='Kali Linux'), Platform(id='kvmibm', name='KVM for IBM z Systems'), Platform(id='linuxmint', name='Linux Mint'), Platform(id='mageia', name='Mageia'), Platform(id='mandriva', name='Mandriva Linux'), Platform(id='manjaro', name='Manjaro Linux'), Platform(id='midnightbsd', name='MidnightBSD'), Platform(id='netbsd', name='NetBSD'), Platform(id='nixos', name='NixOS'), Platform(id='nobara', name='Nobara'), Platform(id='openbsd', name='OpenBSD'), Platform(id='opensuse', name='openSUSE'), Platform(id='openwrt', name='OpenWrt'), Platform(id='oracle', name='Oracle Linux'), Platform(id='os400', name='IBM i'), Platform(id='parallels', name='Parallels'), Platform(id='pidora', name='Pidora'), Platform(id='pikaos', name='PikaOS'), Platform(id='raspbian', name='Raspbian'), Platform(id='rhel', name='RedHat Enterprise Linux'), Platform(id='rocky', name='Rocky Linux'), Platform(id='scientific', name='Scientific Linux'), Platform(id='slackware', name='Slackware'), Platform(id='sles', name='SUSE Linux Enterprise Server'), Platform(id='slitaz', name='SliTaz GNU/Linux'), Platform(id='solaris', name='Solaris'), Platform(id='sourcemage', name='Source Mage GNU/Linux'), Platform(id='sunos', name='SunOS'), Platform(id='tuxedo', name='Tuxedo OS'), Platform(id='ubuntu', name='Ubuntu'), Platform(id='ultramarine', name='Ultramarine'), Platform(id='void', name='Void Linux'), Platform(id='wsl1', name='Windows Subsystem for Linux v1'), Platform(id='wsl2', name='Windows Subsystem for Linux v2'), Platform(id='xenserver', name='XenServer')})

List of platforms supported by the manager.

Allows for a mishmash of platforms and groups of platforms. Will be normalized into a frozenset of Platform instances at instantiation.

default_sudo: bool = True

Built-in escalation default, used when sudo is None.

False on the base: most managers install into user-writable trees and never need root. The system package managers whose privileged operations require root (apt, dnf, pacman, zypper, …) set this to True so their build_cli(..., sudo=True) operations escalate out of the box, while staying switchable off through sudo (--no-sudo or config) for rootless setups.

requirement: str | None = '>=1.14.0'

Version requirement specifier.

Supports a comma-separated range of constraints (e.g. ">=1.20.0,<2.0.0"). A bare version string like "1.20.0" is treated as >=1.20.0.

Parsed by meta_package_manager.version.VersionRange.

Defaults to None, which deactivates version check entirely.

pre_args: tuple[str, ...] = ('--no-color', '--no-abbrev', '--non-interactive', '--no-cd', '--no-refresh')
version_regexes: tuple[str, ...] = ('zypper\\s+(?P<version>\\S+)',)
$ zypper --version
zypper 1.14.11
property installed: Iterator[Package]

Fetch installed packages.

$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout search --details --type package --installed-only
property outdated: Iterator[Package]

Fetch outdated packages.

$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout list-updates
<?xml version='1.0'?>
<stream>
    <message type="info">Loading repository data...</message>
    <message type="info">Reading installed packages...</message>
    <update-status version="0.6">
        <update-list>
            <update name="git" kind="package" edition="2.34.1-10.9.1"
                    edition-old="2.26.2-3.34.1" arch="x86_64">
                <summary>Fast, scalable revision control system</summary>
                <description>
                    Git is a fast, scalable, distributed revision
                    control system.
                </description>
                <license/>
                <source
                    url="http://download.opensuse.org/updata/leap/15.3/sle"
                    alias="repo-sle-update"/>
            </update>
            <update name="vim" kind="package" edition="9.0.1234-1.1"
                    edition-old="8.2.4956-1.1" arch="x86_64">
                <summary>Vi IMproved text editor</summary>
                <description>
                    Highly configurable text editor.
                </description>
                <license/>
                <source
                    url="http://download.opensuse.org/update/leap/15.3/sle"
                    alias="repo-sle-update"/>
            </update>
        </update-list>
    </update-status>
</stream>
property orphans: Iterator[Package]

Fetch packages installed as dependencies that nothing requires anymore.

$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             packages --unneeded
Loading repository data...
Reading installed packages...
S  | Repository | Name    | Version   | Arch
---+------------+---------+-----------+-------
i  | @System    | libfoo  | 1.2.3-1.1 | x86_64
i+ | openSUSE   | libbar  | 0.9-2.4   | noarch
search(query, extended, exact)[source]

Fetch matching packages.

$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout search --details --type package kopete
$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout search --details --type package --search-description kopete
$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout search --details --type package --match-exact kopete
$ zypper --no-color --no-abbrev --non-interactive --no-cd --no-refresh             --xmlout search --details --type package --search-description             --match-exact kopete
Return type:

Iterator[Package]

install(package_id, version=None)[source]

Install one package.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh install kopete
Return type:

str

upgrade_all_cli()[source]

Generates the CLI to upgrade all outdated packages.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh update
Return type:

tuple[str, ...]

upgrade_one_cli(package_id, version=None)[source]

Generates the CLI to upgrade the provided package.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh update kopete
Return type:

tuple[str, ...]

remove(package_id)[source]

Remove one package.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh remove kopete
Return type:

str

remove_orphan(package_id)[source]

Remove one package, dropping dependencies it alone pulled in.

--clean-deps additionally removes the dependencies that were installed with the package and are no longer needed.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh remove --clean-deps kopete
Return type:

str

cli_names: tuple[str, ...] = ('zypper',)

List of CLI names the package manager is known as.

This list of recognized CLI names is ordered by priority. That way we can influence the search of the right binary.

..hint::

This was helpful in the case of the Python transition from 2.x to 3.x, where multiple versions of the same executable were named python or python3.

By default, this property’s value is derived from the manager’s ID (see the MetaPackageManager.__init__ method above).

id: str = 'zypper'

Package manager’s ID.

Derived by defaults from the lower-cased class name in which underscores _ are replaced by dashes -.

This ID must be unique among all package manager definitions and lower-case, as they’re used as feature flags for the mpm CLI.

sync()[source]

Sync package metadata.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh refresh
Return type:

None

virtual: bool = False

Should we expose the package manager to the user?

Virtual package manager are just skeleton classes used to factorize code among managers of the same family.

cleanup_cache()[source]

Removes things we don’t need anymore.

$ sudo zypper --no-color --no-abbrev --non-interactive --no-cd             --no-refresh clean
Return type:

None