v0.9.25 — mureo upgrade [--all]
Added — mureo upgrade [--all] for pipx venv-aware plugin upgrades (#177, #178)
Operators installing mureo via pipx install mureo and extending it with
third-party packages (via mureo.providers / mureo.policy_gates /
mureo.web_extensions entry-point groups, typically registered through
pipx inject or pip install into the same venv) hit a UX gap: there
was no single command for keeping the whole stack fresh.
pipx upgrade mureoonly upgrades the primary venv package; injected
plugins are silently left behind.pipx upgrade <plugin>fails because plugins do not have a same-named
venv (pipx expects~/.local/pipx/venvs/<plugin>/).pipx inject mureo <pkg> --forcetriggers a known pipx 1.11
"looks like a path" bug whenevercwdcontains amureodirectory,
so operators cannot reliably use it as an upgrade path.
mureo upgrade closes this gap with a single top-level subcommand that
operates on sys.executable — the venv currently running the CLI —
independent of cwd, PATH, and PYTHONPATH.
Usage
mureo upgrade # upgrade mureo itself
mureo upgrade <pkg> # upgrade a same-venv package
mureo upgrade <pkg>==<version> # version-pinned upgrade
mureo upgrade --all # mureo + every installed mureo-* in one pip call
mureo upgrade --dry-run # print the pip command without invoking it
Safety properties
- Argument-injection guard. Package specs are validated against a
PEP 503 regex (optionally followed by a single==<version>pin) and
pip is always invoked with a--sentinel. Hostile inputs such as
-r/etc/passwd,--index-url=http://attacker/,pkg @ git+https://…,
PEP 508 markers, and extras are rejected at the boundary; pip's
option parser never sees them. - Squatter-resistant discovery.
--allwalks
importlib.metadata.distributions(), normalises every name per
PEP 503, and accepts onlymureoexact match ormureo-<rest>.
Prefix squatters likemureologyormureoextrasare excluded by
construction. - Same-venv guarantee. Every pip / ensurepip invocation uses
sys.executable, so the command can never accidentally upgrade a
globally-installed mureo or a sibling venv. - Targeted
ensurepipfallback. Only the literal
No module named pipfailure ofpython -m pip --versiontriggers
anensurepip --upgradebootstrap; every other failure is surfaced
verbatim so permission / network / disk errors are never silently
bypassed. After a successful bootstrap, pip availability is
re-probed to produce a clear diagnostic for half-broken venvs. - Atomic resolution under
--all. A singlepip install --upgrade
invocation is issued with every target so pip's resolver sees the
full set together. - Exit-code transparency. pip's exit code is propagated as the CLI
exit code, enabling automation scripts to retry or branch.
Why ship this in OSS rather than per-plugin
Each plugin author could in principle ship its own <plugin> upgrade
command, but that path produces duplicated code per plugin and forces
operators to remember a different command for each one. Centralising
the logic in OSS — which already owns mureo install-desktop and
mureo configure, both also venv-aware top-level commands — keeps the
mental model simple: mureo upgrade --all is the only command an
operator needs.