meta_package_manager.bar_plugin module¶
SwiftBar and Xbar plugin for Meta Package Manager (the mpm CLI).
Set the update cycle to several hours. One notice a day is enough, and each check uses many resources. A short cycle can also use up the GitHub API quota that Homebrew needs.
Both hosts give the plugin options to the script as environment variables:
Xbar passes them from its settings UI to the script.
SwiftBar does the same since
2.1.0added support forxbar.var(swiftbar/SwiftBar#472).
- meta_package_manager.bar_plugin.SWIFTBAR_MIN_VERSION = (2, 1, 0)¶
SwiftBar
2.1.0fixes a bug with multiple parameters in a font string.The fix first went out in a test build labelled
2.1.2. No release used that number: the public releases numbered it2.1.0. A floor at2.1.2would exclude every SwiftBar release.
- meta_package_manager.bar_plugin.MPM_MIN_VERSION = (5, 0, 0)¶
mpm5.0.0is the first version that renders the complete menu layout.
- meta_package_manager.bar_plugin.SHELL_ENV_MIN_VERSION = (8, 0, 0)¶
First
mpmrelease accepting--shell-env, which the plugin passes to it.Both hosts start this plugin outside a terminal. SwiftBar runs it through
$SHELL -l -c, a login shell that reads.zprofileand skips.zshrc, and Xbar runs it with no shell at all, on thePATHof the desktop session. The option makesmpmadopt the environment of an interactive login shell before it looks for managers, so the menu lists what a terminal would. An oldermpmgets no such option: it would reject it as unknown, which is worse than the narrowPATH.The GNOME Shell extension carries the same gate, and
tests/test_gnome_extension.pyholds the two in sync.
- meta_package_manager.bar_plugin.INSTALL_ARGV = ('uv', 'tool', 'install', '--upgrade', 'meta-package-manager')¶
Install command offered when no runnable
mpmis found.A global uv tool install is the first method on the installation page. It puts
mpmon thePATHof every shell. Apip installputs it in one interpreter, which may not be the one that runs this plugin.--upgradealso covers anmpmthat is too old, so the command needs no version specifier: the latest release always satisfiesMPM_MIN_VERSION. Xbar also breaks a quoted>=specifier (matryer/xbar#831).The GNOME Shell extension offers the same command in its own menu for a missing
mpm.tests/test_gnome_extension.pychecks that the two are equal.
- meta_package_manager.bar_plugin.INSTALL_DOCS_URL = 'https://mpm.run/install/'¶
Installation page, offered beside
INSTALL_ARGV.uvmay be missing too, and it is not the only method: a distribution package, Homebrew or a standalone binary also installmpm.
- meta_package_manager.bar_plugin.PLUGIN_DOCS_URL = 'https://mpm.run/bar-plugin/'¶
Documentation of this plugin, linked from the About submenu.
This is the same address as the one in the
<xbar.abouturl>header. The host shows that header in its plugin browser only, and never in the menu.
- meta_package_manager.bar_plugin.MPM_TIMEOUT = 60¶
Maximum duration in seconds for one
mpmcall.Passed as
--timeoutto everympmcall. Thempmdefaults are set for interactive use and are too long for a background menu bar refresh: 120 seconds for a read-only query, and 500 seconds for an operation that changes state, likesync. With this limit, a hung package manager fails the refresh after one minute, and it does not block the menu bar for several minutes.
- meta_package_manager.bar_plugin.VERSION_REGEX = re.compile('\n .+ # Any string\n \\ # A space\n version # The "version" string\n \\ # A space\n [^\\.]*? , re.MULTILINE|re.VERBOSE)¶
Both readings of the version that
mpm --versionprints, with or without ANSI colors.versionis the numeric part, andreleaseis the whole token. A development build reports8.0.0.dev0+40ce0879, and its suffix identifies the build.
- class meta_package_manager.bar_plugin.Candidate(args: tuple[str, ...], runnable: bool = False, up_to_date: bool = False, version: tuple[int, ...] | None = None, error: str | Exception | None = None, release: str | None = None)[source]¶
Bases:
NamedTupleOne way to run
mpmfound on the system, and the result of its version probe.versionis the tuple that the code compares withMPM_MIN_VERSION, andreleaseis the token as printed. TheprobeMpm()function of the GNOME Shell extension returns the same fields.Create new instance of Candidate(args, runnable, up_to_date, version, error, release)
- property rank: tuple[bool, bool, tuple[int, ...]]¶
Sort key of
MPMPlugin.ranked_mpm: runnable first, then up to date, then the highest version.errorandreleaseare not part of the key. Python cannot compare two exceptions, and it cannot compare a missing version with a found one. Either case would make the sort raise an error.
- class meta_package_manager.bar_plugin.MPMPlugin[source]¶
Bases:
objectFinds the
mpmCLI on the system and calls it.mpmproduces the main output of the plugin.The output must follow both the Xbar dialect and the SwiftBar dialect.
- static getenv_str(var, default=None)[source]¶
Read an environment variable.
All environment variables are strings. This method always returns a lowercase string.
- static getenv_bool(var, default=False)[source]¶
Read an environment variable as a boolean.
Uses configparser.RawConfigParser.BOOLEAN_STATES to convert the string.
- Return type:
- static getenv_int(var, default)[source]¶
Read an environment variable as an integer.
Returns the default when the value is not a number. A typo in a plugin setting then changes the layout, and the menu still works.
- Return type:
- static normalize_params(font_string, valid_ids=None)[source]¶
Parse a string of parameters and return a normalized string.
The input is a space-separated list of parameters. Each parameter is a key/value pair separated by an equal sign.
The method keeps the parameters named in
valid_idsand ignores the others. By default it keepscolor,fontandsize.One parameter can occur more than once. The method keeps the last value.
Both hosts document the available parameters:
- Return type:
- static version_to_str(version_tuple)[source]¶
Convert a tuple of integers into a version string.
- Return type:
- property align_columns: bool[source]¶
Center each version pair around its arrow, and align the package names.
The rows use a fixed-width font, so every padding space has the same width. See
align_rows()for the reason to align on the arrow.
- property plugin_version: str[source]¶
Version that this script reports to its host.
Read from the
<xbar.version>header. That header is the only place where the number is written: both hosts parse it from the source, andbump-my-versionupdates it at each release. A constant beside it would be a second copy, and the two could become different.
- property mpm_options: tuple[str, ...][source]¶
Options added to every
mpmcall.They go after the options of the plugin and before the subcommand. A single-value option that occurs twice, like
--verbosity, then takes the value from the user.The version probe does not use them. A mistyped option then makes
syncfail with mpm’s own usage error, which the menu shows. Without this, the same typo would look like a missingmpm. The upgrade actions of the menu use these options too:BarPluginRendererbuilds them inside theoutdatedcall and inherits this environment.The value comes from
VAR_MPM_OPTIONS, read withoutgetenv_str()because that method lowercases it. A--verbosity INFOlevel and a path in--configmust keep their case. The GNOME Shell extension’smpm-optionssetting is the equivalent option.
- property always_visible: bool[source]¶
Keep the menu bar icon when there is nothing to report.
SwiftBar hides a plugin that produces no output. To make the icon disappear, the plugin renders nothing. The plugin must then separate an empty output that the user asked for from the empty output of a failed
mpmcall. For this reason,print_menu()accepts an empty output only when this option is set.Xbar does not hide a plugin, so the variable is declared for SwiftBar only.
The value comes from the
VAR_ALWAYS_VISIBLEenvironment variable. The name matches thealways-visiblesetting of the GNOME Shell extension.
- property error_font: str[source]¶
Error font: the monospace font, in red.
It sets no size of its own. The menu gives a row the height of the largest font in it, and both hosts put the extra space under the text instead of dividing it between the rows. With
size=10, an error line had 15 pixels of space below it, and every other row had 9.
- property is_swiftbar: bool[source]¶
Truewhen the host is SwiftBar, which sets theSWIFTBARvariable.
- static search_venv(folder)[source]¶
Return the command that runs
mpmfrom the project infolder, orNone.A folder is a project when it holds a lockfile. The command is the one that the project’s tool provides to run a program inside the environment it manages. The result never starts with an environment assignment:
check_mpm()runs the command without a shell, and a shell-less call would read the assignment as the program name. The other candidates ofsearch_mpm()cover a folder with no lockfile.
- search_mpm()[source]¶
Yield each command that can run
mpm.The method covers every context of a system where
mpmmay be installed.ranked_mpmkeeps the order of these candidates.The commands from a virtual environment come first. The plugin prefers the
mpmthat it belongs to. This file is part of the package, so the walk up its parent folders reaches the project that installed it. Thatmpmis the one released with this plugin, and its dependencies are already resolved. Both hosts put a symlink to this file in their own plugin folder, which is why the code below resolves the path first. An unresolved path would walk that plugin folder, find nothing, and leave the plugin with anothermpmfrom the system.The other candidates are for a plugin installed in the host alone: a system-wide installation, then the module under an interpreter.
check_mpm()runs each candidate before the ranking, so none of them is accepted without a test.
- check_mpm(mpm_cli_args)[source]¶
Run the version probe of one command and read the result.
--no-colorkeeps the output parseable when Click detects a terminal. A command with a missing program is a candidate like the others, and its error is the exception.- Return type:
- property ranked_mpm: list[Candidate][source]¶
Every
mpmfound on the system, best candidate first.Sorted on
Candidate.rank. Two candidates with the same rank keep the order thatsearch_mpm()gave them.
- property shell_env_options: tuple[str, ...]¶
--shell-envfor anmpmthat accepts it, nothing for an older one.Goes right after the
mpmcommand and ahead ofmpm_options, so a--no-shell-envtyped intoVAR_MPM_OPTIONSwins.
- static pp(label, *args)[source]¶
Print one menu line in the SwiftBar and Xbar dialect.
The first argument is the label of the menu line. A pipe separates it from the other parameters, and a space separates those parameters from each other.
The method prints nothing when the label is empty. A
Noneparameter renders nothing, so a package with no upgrade command still gets a menu line with its label alone.- Return type:
- print_error(message, submenu='')[source]¶
Print an error message, with one menu line per line of text.
The lines use a red, fixed-width font, which keeps the layout of a traceback or of an exception. The message is dedented and its empty lines are removed, to keep the block compact.
The message is converted to a string, so the caller can pass an exception object.
- Return type:
- print_about()[source]¶
Print the menu footer, with the version of the plugin and the version of
mpm.This script and
mpmare installed and updated separately. A plugin file copied into the host’s folder keeps its version whilempmchanges, and no other part of the menu shows the difference. Thempmline reports the release as printed, with its suffix. The ranking compares the numeric part only.The footer is one collapsed row. Three visible rows would push the package list down for a user who opened the menu to read it.
- Return type:
Print the main menu.
- Return type: