Downstream packagingΒΆ
This page is for distribution packagers, and for anyone building mpm from the packaging specs maintained in this repository: how to wire the test suite into a package build, which dependency constraints to pin against, and where each distribution channel stands.
To install mpm on your own system, head to the installation methods instead. For the release-time automation that keeps the in-repo specs fresh, see the releasing page.
Test suiteΒΆ
The mpm test suite splits into two layers, separated by the integration pytest marker:
A hermetic layer (everything not marked
integration) needs no network, no package managers and no writable$HOME. It runs cleanly inside a build sandbox. Beyondpytestit importspyyamlandtomlkit(both pulled in bytests/test_docs.py); the SBOM tests additionally want the[sbom-offline]and[sbom-online]extras but skip themselves when those are absent, so a lean build never has to ignore them.pyproject-fmtstays optional too, its formatting-fixpoint test auto-skipping when missing.An integration layer (marked
integration:tests/test_manager_*.py,tests/test_cli*.pyand the Xbar/SwiftBar plugin suite) drives the ~70 real package managers (apt,brew,pip,npm, and more) and thempmCLI end-to-end. It cannot run in a hermetic builder.
Pick the skip path that fits the builder. Either way no per-module ignore list is needed, and the selection stays correct as test modules are added:
Writable-
$HOMEbuilders (Alpineβs abuild, Debian buildd, RPM mock, and similar) select the hermetic layer explicitly:$ pytest -m "not integration"
Sandbox builders that set
HOME=/homeless-shelter(Guix, Nix) get the integration layer auto-skipped throughextra_platforms.pytest.skip_guix_build(wired up intests/conftest.py), so a plainpytestalready runs only the hermetic layer. Do not override$HOMEback to a writable path, or the auto-skip stops firing and the integration tests fail.
Repo-maintenance sync guards (which regenerate a committed artifact from the installed tooling and compare) skip automatically outside a git checkout, so a tarball or sdist build never trips on a tooling-version mismatch. A builder that packages the SBOM extras can install [sbom-offline] / [sbom-online] to exercise the SBOM tests instead of skipping them.
Running only the sanity-check phase (or its equivalent) stays a valid minimal option: it confirms the package imports cleanly and its declared dependencies resolve. Full functional verification of the integration layer is covered by the projectβs own GitHub Actions CI, where the package managers are pre-installed.
The --skip-destructive and pytest -m "not destructive" selectors exist for developer environments where some package managers are present but mutating them would be undesirable. They do not make the suite hermetic.
Note
As of mpm > 7.3.0, the PyPI sdist ships tests/, docs/ and the .github/ workflow files the docs tests parse, so a build can run the suite straight from the sdist. Earlier releases shipped no tests: those builds must start from the GitHub tag tarballs instead.
DependenciesΒΆ
This is a graph of the default, main dependencies of the Python package:
flowchart LR
meta_package_manager[["`meta-package-manager`"]]
subgraph primary-deps [Primary dependencies]
click_extra{{"`click-extra`"}}
tomli{{"`tomli`"}}
xmltodict{{"`xmltodict`"}}
boltons{{"`boltons`"}}
extra_platforms{{"`extra-platforms`"}}
packageurl_python{{"`packageurl-python`"}}
backports_strenum{{"`backports-strenum`"}}
tomli_w{{"`tomli-w`"}}
end
jsonschema(["`jsonschema`"])
referencing(["`referencing`"])
typing_extensions(["`typing-extensions`"])
pygments(["`pygments`"])
requests(["`requests`"])
anyio(["`anyio`"])
click_0(["`click`"])
idna(["`idna`"])
jinja2(["`jinja2`"])
arrow(["`arrow`"])
beautifulsoup4(["`beautifulsoup4`"])
certifi(["`certifi`"])
cloup(["`cloup`"])
colorama(["`colorama`"])
docutils(["`docutils`"])
exceptiongroup(["`exceptiongroup`"])
httpcore(["`httpcore`"])
license_expression(["`license-expression`"])
markdown_it_py(["`markdown-it-py`"])
packaging(["`packaging`"])
rdflib(["`rdflib`"])
accessible_pygments(["`accessible-pygments`"])
attrs(["`attrs`"])
isoduration(["`isoduration`"])
jsonschema_specifications(["`jsonschema-specifications`"])
mdit_py_plugins(["`mdit-py-plugins`"])
pluggy(["`pluggy`"])
py_serializable(["`py-serializable`"])
python_dateutil(["`python-dateutil`"])
rfc3339_validator(["`rfc3339-validator`"])
rfc3987_syntax(["`rfc3987-syntax`"])
rpds_py(["`rpds-py`"])
six(["`six`"])
sphinx_basic_ng(["`sphinx-basic-ng`"])
sphinxcontrib_jquery(["`sphinxcontrib-jquery`"])
tabulate(["`tabulate`"])
wcmatch(["`wcmatch`"])
wcwidth(["`wcwidth`"])
alabaster(["`alabaster`"])
babel(["`babel`"])
beartype(["`beartype`"])
boolean_py(["`boolean-py`"])
bracex(["`bracex`"])
charset_normalizer(["`charset-normalizer`"])
deepmerge(["`deepmerge`"])
defusedxml(["`defusedxml`"])
execnet(["`execnet`"])
fqdn(["`fqdn`"])
h11(["`h11`"])
hjson(["`hjson`"])
imagesize(["`imagesize`"])
iniconfig(["`iniconfig`"])
isodate(["`isodate`"])
json_with_comments(["`json-with-comments`"])
json5(["`json5`"])
jsonpointer(["`jsonpointer`"])
lark(["`lark`"])
lxml(["`lxml`"])
markupsafe(["`markupsafe`"])
mdurl(["`mdurl`"])
ply(["`ply`"])
psutil(["`psutil`"])
pyparsing(["`pyparsing`"])
rfc3986_validator(["`rfc3986-validator`"])
roman_numerals(["`roman-numerals`"])
semantic_version(["`semantic-version`"])
snowballstemmer(["`snowballstemmer`"])
sortedcontainers(["`sortedcontainers`"])
soupsieve(["`soupsieve`"])
sphinxcontrib_applehelp(["`sphinxcontrib-applehelp`"])
sphinxcontrib_devhelp(["`sphinxcontrib-devhelp`"])
sphinxcontrib_htmlhelp(["`sphinxcontrib-htmlhelp`"])
sphinxcontrib_jsmath(["`sphinxcontrib-jsmath`"])
sphinxcontrib_qthelp(["`sphinxcontrib-qthelp`"])
sphinxcontrib_serializinghtml(["`sphinxcontrib-serializinghtml`"])
tzdata(["`tzdata`"])
uri_template(["`uri-template`"])
uritools(["`uritools`"])
urllib3(["`urllib3`"])
webcolors(["`webcolors`"])
subgraph ext_sbom-offline [--extra sbom-offline]
ext_sbom-offline_spdx_tools{{"`spdx-tools >=0.8.2`"}}
ext_sbom-offline_cyclonedx_python_lib{{"`cyclonedx-python-lib >=11.9`"}}
end
subgraph ext_sbom-online [--extra sbom-online]
platformdirs{{"`platformdirs >=4`"}}
ext_sbom-online_httpx{{"`httpx >=0.27`"}}
end
subgraph grp_docs [--group docs]
sphinx{{"`sphinx >=8`"}}
myst_parser{{"`myst-parser >=4`"}}
furo{{"`furo >=2025.9.25`"}}
sphinx_datatables{{"`sphinx-datatables >=1`"}}
sphinxcontrib_mermaid{{"`sphinxcontrib-mermaid >=1.2.3`"}}
sphinx_autodoc_typehints{{"`sphinx-autodoc-typehints >=2.4`"}}
sphinx_copybutton{{"`sphinx-copybutton >=0.5.2`"}}
sphinx_design{{"`sphinx-design >=0.6`"}}
sphinxext_opengraph{{"`sphinxext-opengraph >=0.13`"}}
tomlkit{{"`tomlkit >=0.13`"}}
end
subgraph grp_test [--group test]
pytest{{"`pytest >=9`"}}
spdx_tools{{"`spdx-tools`"}}
cyclonedx_python_lib{{"`cyclonedx-python-lib`"}}
httpx{{"`httpx >=0.27`"}}
pyyaml{{"`pyyaml >=6`"}}
pytest_cov{{"`pytest-cov >=7`"}}
pytest_xdist{{"`pytest-xdist >=3.7`"}}
coverage{{"`coverage >=7.11`"}}
pytest_github_actions_annotate_failures{{"`pytest-github-actions-annotate-failures >=0.3`"}}
pytest_randomly{{"`pytest-randomly >=4.0.1`"}}
respx{{"`respx >=0.22`"}}
pyproject_fmt{{"`pyproject-fmt >=2.25.1`"}}
end
subgraph grp_typing [--group typing]
types_boltons{{"`types-boltons >=25.0.0.20250919`"}}
types_pyyaml{{"`types-pyyaml >=6.0.12.9`"}}
types_xmltodict{{"`types-xmltodict >=1.0.1.20250920`"}}
end
meta_package_manager ==>|" >=8.4 "| click_extra
meta_package_manager ==>|" >=2 "| tomli
meta_package_manager ==>|" >=0.12 "| xmltodict
meta_package_manager ==>|" >=25 "| boltons
meta_package_manager ==>|" >=13.1 "| extra_platforms
meta_package_manager ==>|" >=0.11 "| packageurl_python
meta_package_manager ==>|" >=1 "| backports_strenum
meta_package_manager ==>|" >=1 "| tomli_w
sphinx --> pygments
sphinx --> requests
sphinx --> tomli
sphinx --> jinja2
sphinx --> colorama
sphinx --> docutils
sphinx --> packaging
sphinx --> alabaster
sphinx --> babel
sphinx --> imagesize
sphinx --> roman_numerals
sphinx --> snowballstemmer
sphinx --> sphinxcontrib_applehelp
sphinx --> sphinxcontrib_devhelp
sphinx --> sphinxcontrib_htmlhelp
sphinx --> sphinxcontrib_jsmath
sphinx --> sphinxcontrib_qthelp
sphinx --> sphinxcontrib_serializinghtml
click_extra --> sphinx
click_extra --> pytest
click_extra --> pygments
click_extra --> pyyaml
click_extra --> tomli
click_extra --> click_0
click_extra --> cloup
click_extra --> docutils
click_extra --> xmltodict
click_extra --> boltons
click_extra --> extra_platforms
click_extra --> tabulate
click_extra --> tomlkit
click_extra --> wcmatch
click_extra --> wcwidth
click_extra --> deepmerge
click_extra --> hjson
click_extra --> json_with_comments
click_extra --> json5
pytest --> pygments
pytest --> tomli
pytest --> colorama
pytest --> exceptiongroup
pytest --> packaging
pytest --> pluggy
pytest --> iniconfig
spdx_tools --> pyyaml
spdx_tools --> click_0
spdx_tools --> license_expression
spdx_tools --> rdflib
spdx_tools --> xmltodict
spdx_tools --> beartype
spdx_tools --> ply
spdx_tools --> semantic_version
spdx_tools --> uritools
cyclonedx_python_lib --> jsonschema
cyclonedx_python_lib --> referencing
cyclonedx_python_lib --> typing_extensions
cyclonedx_python_lib --> license_expression
cyclonedx_python_lib --> packageurl_python
cyclonedx_python_lib --> py_serializable
cyclonedx_python_lib --> lxml
cyclonedx_python_lib --> sortedcontainers
myst_parser --> sphinx
myst_parser --> pyyaml
myst_parser --> jinja2
myst_parser --> docutils
myst_parser --> markdown_it_py
myst_parser --> mdit_py_plugins
furo --> sphinx
furo --> pygments
furo --> beautifulsoup4
furo --> accessible_pygments
furo --> sphinx_basic_ng
httpx --> anyio
httpx --> idna
httpx --> certifi
httpx --> httpcore
pytest_cov --> pytest
pytest_cov --> coverage
pytest_cov --> pluggy
pytest_xdist --> pytest
pytest_xdist --> execnet
pytest_xdist --> psutil
sphinx_datatables --> sphinx
sphinx_datatables --> packaging
sphinx_datatables --> sphinxcontrib_jquery
sphinxcontrib_mermaid --> sphinx
sphinxcontrib_mermaid --> pyyaml
sphinxcontrib_mermaid --> jinja2
coverage --> tomli
pytest_github_actions_annotate_failures --> pytest
pytest_randomly --> pytest
respx --> httpx
sphinx_autodoc_typehints --> sphinx
sphinx_copybutton --> sphinx
sphinx_design --> sphinx
sphinxext_opengraph --> sphinx
jsonschema --> referencing
jsonschema --> idna
jsonschema --> attrs
jsonschema --> isoduration
jsonschema --> jsonschema_specifications
jsonschema --> rfc3339_validator
jsonschema --> rfc3987_syntax
jsonschema --> rpds_py
jsonschema --> fqdn
jsonschema --> jsonpointer
jsonschema --> rfc3986_validator
jsonschema --> uri_template
jsonschema --> webcolors
referencing --> typing_extensions
referencing --> attrs
referencing --> rpds_py
requests --> idna
requests --> certifi
requests --> charset_normalizer
requests --> urllib3
anyio --> typing_extensions
anyio --> idna
anyio --> exceptiongroup
click_0 --> colorama
jinja2 --> markupsafe
beautifulsoup4 --> typing_extensions
beautifulsoup4 --> soupsieve
cloup --> typing_extensions
cloup --> click_0
exceptiongroup --> typing_extensions
httpcore --> certifi
httpcore --> h11
license_expression --> boolean_py
markdown_it_py --> mdurl
rdflib --> isodate
rdflib --> pyparsing
accessible_pygments --> pygments
mdit_py_plugins --> markdown_it_py
py_serializable --> defusedxml
sphinx_basic_ng --> sphinx
sphinxcontrib_jquery --> sphinx
tabulate --> wcwidth
wcmatch --> bracex
isoduration --> arrow
jsonschema_specifications --> referencing
rfc3339_validator --> six
rfc3987_syntax --> lark
arrow --> python_dateutil
arrow --> tzdata
python_dateutil --> six
meta_package_manager -.-> ext_sbom-offline
meta_package_manager -.-> ext_sbom-online
meta_package_manager -.-> grp_docs
meta_package_manager -.-> grp_test
meta_package_manager -.-> grp_typing
ext_sbom-offline_spdx_tools -.- spdx_tools
ext_sbom-offline_cyclonedx_python_lib -.- cyclonedx_python_lib
ext_sbom-online_httpx -.- httpx
click accessible_pygments "https://pypi.org/project/accessible-pygments/" _blank
click alabaster "https://pypi.org/project/alabaster/" _blank
click anyio "https://pypi.org/project/anyio/" _blank
click arrow "https://pypi.org/project/arrow/" _blank
click attrs "https://pypi.org/project/attrs/" _blank
click babel "https://pypi.org/project/babel/" _blank
click backports_strenum "https://pypi.org/project/backports-strenum/" _blank
click beartype "https://pypi.org/project/beartype/" _blank
click beautifulsoup4 "https://pypi.org/project/beautifulsoup4/" _blank
click boltons "https://pypi.org/project/boltons/" _blank
click boolean_py "https://pypi.org/project/boolean-py/" _blank
click bracex "https://pypi.org/project/bracex/" _blank
click certifi "https://pypi.org/project/certifi/" _blank
click charset_normalizer "https://pypi.org/project/charset-normalizer/" _blank
click click_0 "https://pypi.org/project/click/" _blank
click click_extra "https://pypi.org/project/click-extra/" _blank
click cloup "https://pypi.org/project/cloup/" _blank
click colorama "https://pypi.org/project/colorama/" _blank
click coverage "https://pypi.org/project/coverage/" _blank
click cyclonedx_python_lib "https://pypi.org/project/cyclonedx-python-lib/" _blank
click deepmerge "https://pypi.org/project/deepmerge/" _blank
click defusedxml "https://pypi.org/project/defusedxml/" _blank
click docutils "https://pypi.org/project/docutils/" _blank
click exceptiongroup "https://pypi.org/project/exceptiongroup/" _blank
click execnet "https://pypi.org/project/execnet/" _blank
click extra_platforms "https://pypi.org/project/extra-platforms/" _blank
click fqdn "https://pypi.org/project/fqdn/" _blank
click furo "https://pypi.org/project/furo/" _blank
click h11 "https://pypi.org/project/h11/" _blank
click hjson "https://pypi.org/project/hjson/" _blank
click httpcore "https://pypi.org/project/httpcore/" _blank
click httpx "https://pypi.org/project/httpx/" _blank
click idna "https://pypi.org/project/idna/" _blank
click imagesize "https://pypi.org/project/imagesize/" _blank
click iniconfig "https://pypi.org/project/iniconfig/" _blank
click isodate "https://pypi.org/project/isodate/" _blank
click isoduration "https://pypi.org/project/isoduration/" _blank
click jinja2 "https://pypi.org/project/jinja2/" _blank
click json_with_comments "https://pypi.org/project/json-with-comments/" _blank
click json5 "https://pypi.org/project/json5/" _blank
click jsonpointer "https://pypi.org/project/jsonpointer/" _blank
click jsonschema "https://pypi.org/project/jsonschema/" _blank
click jsonschema_specifications "https://pypi.org/project/jsonschema-specifications/" _blank
click lark "https://pypi.org/project/lark/" _blank
click license_expression "https://pypi.org/project/license-expression/" _blank
click lxml "https://pypi.org/project/lxml/" _blank
click markdown_it_py "https://pypi.org/project/markdown-it-py/" _blank
click markupsafe "https://pypi.org/project/markupsafe/" _blank
click mdit_py_plugins "https://pypi.org/project/mdit-py-plugins/" _blank
click mdurl "https://pypi.org/project/mdurl/" _blank
click meta_package_manager "https://pypi.org/project/meta-package-manager/" _blank
click myst_parser "https://pypi.org/project/myst-parser/" _blank
click packageurl_python "https://pypi.org/project/packageurl-python/" _blank
click packaging "https://pypi.org/project/packaging/" _blank
click platformdirs "https://pypi.org/project/platformdirs/" _blank
click pluggy "https://pypi.org/project/pluggy/" _blank
click ply "https://pypi.org/project/ply/" _blank
click psutil "https://pypi.org/project/psutil/" _blank
click py_serializable "https://pypi.org/project/py-serializable/" _blank
click pygments "https://pypi.org/project/pygments/" _blank
click pyparsing "https://pypi.org/project/pyparsing/" _blank
click pyproject_fmt "https://pypi.org/project/pyproject-fmt/" _blank
click pytest "https://pypi.org/project/pytest/" _blank
click pytest_cov "https://pypi.org/project/pytest-cov/" _blank
click pytest_github_actions_annotate_failures "https://pypi.org/project/pytest-github-actions-annotate-failures/" _blank
click pytest_randomly "https://pypi.org/project/pytest-randomly/" _blank
click pytest_xdist "https://pypi.org/project/pytest-xdist/" _blank
click python_dateutil "https://pypi.org/project/python-dateutil/" _blank
click pyyaml "https://pypi.org/project/pyyaml/" _blank
click rdflib "https://pypi.org/project/rdflib/" _blank
click referencing "https://pypi.org/project/referencing/" _blank
click requests "https://pypi.org/project/requests/" _blank
click respx "https://pypi.org/project/respx/" _blank
click rfc3339_validator "https://pypi.org/project/rfc3339-validator/" _blank
click rfc3986_validator "https://pypi.org/project/rfc3986-validator/" _blank
click rfc3987_syntax "https://pypi.org/project/rfc3987-syntax/" _blank
click roman_numerals "https://pypi.org/project/roman-numerals/" _blank
click rpds_py "https://pypi.org/project/rpds-py/" _blank
click semantic_version "https://pypi.org/project/semantic-version/" _blank
click six "https://pypi.org/project/six/" _blank
click snowballstemmer "https://pypi.org/project/snowballstemmer/" _blank
click sortedcontainers "https://pypi.org/project/sortedcontainers/" _blank
click soupsieve "https://pypi.org/project/soupsieve/" _blank
click spdx_tools "https://pypi.org/project/spdx-tools/" _blank
click sphinx "https://pypi.org/project/sphinx/" _blank
click sphinx_autodoc_typehints "https://pypi.org/project/sphinx-autodoc-typehints/" _blank
click sphinx_basic_ng "https://pypi.org/project/sphinx-basic-ng/" _blank
click sphinx_copybutton "https://pypi.org/project/sphinx-copybutton/" _blank
click sphinx_datatables "https://pypi.org/project/sphinx-datatables/" _blank
click sphinx_design "https://pypi.org/project/sphinx-design/" _blank
click sphinxcontrib_applehelp "https://pypi.org/project/sphinxcontrib-applehelp/" _blank
click sphinxcontrib_devhelp "https://pypi.org/project/sphinxcontrib-devhelp/" _blank
click sphinxcontrib_htmlhelp "https://pypi.org/project/sphinxcontrib-htmlhelp/" _blank
click sphinxcontrib_jquery "https://pypi.org/project/sphinxcontrib-jquery/" _blank
click sphinxcontrib_jsmath "https://pypi.org/project/sphinxcontrib-jsmath/" _blank
click sphinxcontrib_mermaid "https://pypi.org/project/sphinxcontrib-mermaid/" _blank
click sphinxcontrib_qthelp "https://pypi.org/project/sphinxcontrib-qthelp/" _blank
click sphinxcontrib_serializinghtml "https://pypi.org/project/sphinxcontrib-serializinghtml/" _blank
click sphinxext_opengraph "https://pypi.org/project/sphinxext-opengraph/" _blank
click tabulate "https://pypi.org/project/tabulate/" _blank
click tomli "https://pypi.org/project/tomli/" _blank
click tomli_w "https://pypi.org/project/tomli-w/" _blank
click tomlkit "https://pypi.org/project/tomlkit/" _blank
click types_boltons "https://pypi.org/project/types-boltons/" _blank
click types_pyyaml "https://pypi.org/project/types-pyyaml/" _blank
click types_xmltodict "https://pypi.org/project/types-xmltodict/" _blank
click typing_extensions "https://pypi.org/project/typing-extensions/" _blank
click tzdata "https://pypi.org/project/tzdata/" _blank
click uri_template "https://pypi.org/project/uri-template/" _blank
click uritools "https://pypi.org/project/uritools/" _blank
click urllib3 "https://pypi.org/project/urllib3/" _blank
click wcmatch "https://pypi.org/project/wcmatch/" _blank
click wcwidth "https://pypi.org/project/wcwidth/" _blank
click webcolors "https://pypi.org/project/webcolors/" _blank
click xmltodict "https://pypi.org/project/xmltodict/" _blank
click ext_sbom-offline_spdx_tools "https://pypi.org/project/spdx-tools/" _blank
click ext_sbom-offline_cyclonedx_python_lib "https://pypi.org/project/cyclonedx-python-lib/" _blank
click ext_sbom-online_httpx "https://pypi.org/project/httpx/" _blank
style meta_package_manager stroke-width:3px
style backports_strenum stroke-width:3px
style boltons stroke-width:3px
style click_extra stroke-width:3px
style coverage stroke-width:3px
style cyclonedx_python_lib stroke-width:3px
style extra_platforms stroke-width:3px
style furo stroke-width:3px
style httpx stroke-width:3px
style myst_parser stroke-width:3px
style packageurl_python stroke-width:3px
style platformdirs stroke-width:3px
style pyproject_fmt stroke-width:3px
style pytest stroke-width:3px
style pytest_cov stroke-width:3px
style pytest_github_actions_annotate_failures stroke-width:3px
style pytest_randomly stroke-width:3px
style pytest_xdist stroke-width:3px
style pyyaml stroke-width:3px
style respx stroke-width:3px
style spdx_tools stroke-width:3px
style sphinx stroke-width:3px
style sphinx_autodoc_typehints stroke-width:3px
style sphinx_copybutton stroke-width:3px
style sphinx_datatables stroke-width:3px
style sphinx_design stroke-width:3px
style sphinxcontrib_mermaid stroke-width:3px
style sphinxext_opengraph stroke-width:3px
style tomli stroke-width:3px
style tomli_w stroke-width:3px
style tomlkit stroke-width:3px
style types_boltons stroke-width:3px
style types_pyyaml stroke-width:3px
style types_xmltodict stroke-width:3px
style xmltodict stroke-width:3px
style ext_sbom-offline_spdx_tools stroke-width:3px,stroke-dasharray:5 5
style ext_sbom-offline_cyclonedx_python_lib stroke-width:3px,stroke-dasharray:5 5
style ext_sbom-online_httpx stroke-width:3px,stroke-dasharray:5 5
style primary-deps fill:#1565C020,stroke:#42A5F5
style ext_sbom-offline fill:#7B1FA220,stroke:#BA68C8
style ext_sbom-online fill:#7B1FA220,stroke:#BA68C8
style grp_docs fill:#546E7A20,stroke:#90A4AE
style grp_test fill:#546E7A20,stroke:#90A4AE
style grp_typing fill:#546E7A20,stroke:#90A4AE
The extra dependencies table lists the optional extras and the features they unlock.
click-extra compatibilityΒΆ
mpm builds its CLI on click-extra, and the two evolve in lockstep: most mpm releases raise their click-extra floor to pick up features and fixes. The table below shows which click-extra versions each mpm release range accepts at install time, derived from the click-extra requirement specifier across release tags. Columns are minor-grouped where the specifiers only distinguish minors, and split per patch where a floor pins a specific patch; the right edge is the click-extra version currently resolved in uv.lock. Rows start at 6.0.0 to keep the column set readable, and the table is regenerated by the same matrix mechanism as the Python compatibility one:
|
Released |
Spec |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
2026-07-17 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-07-09 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-07-07 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-06-26 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-06-17 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-05-25 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-05-04 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-04-27 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-03-26 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-03-25 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2026-02-05 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
|
2025-12-08 |
|
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
β |
ChannelsΒΆ
Where mpm stands on each distribution channel whose packaging is maintained from this repository, plus the community-maintained AUR entry. Channels needing no in-repo spec (PyPI, Homebrew, Scoop, GitHub Releases, Stew, ZeroBrew) are covered by the installation methods directly.
Channel |
Spec |
Upstream status |
CI check |
Release bump |
|---|---|---|---|---|
Alpine Linux |
aports submission in preparation |
|
manual |
|
Arch Linux (AUR) |
released |
|
n/a |
|
Chocolatey |
|
manual |
||
Guix |
|
automated |
||
MacPorts |
|
manual |
||
Nix |
|
automated |
||
Void Linux |
β |
manual |
The *-source jobs of tests-install.yaml build and install each in-repo spec on every change to it and on a weekly schedule. Automated bumps are performed by release.yaml jobs right after each release (see releasing); manual specs pin the released version and its source checksums, refreshed by hand at each release.
Alpine LinuxΒΆ
Build and install from the APKBUILD overlay maintained in the repository. It targets Alpine edge, the only branch shipping py3-uv-build (mpmβs build backend) and py3-boltons >= 25.
As a member of the abuild group, with a signing key set up:
$ doas apk add alpine-sdk
$ abuild-keygen --append --install -n
$ git clone https://github.com/kdeldycke/meta-package-manager.git
$ cd ./meta-package-manager/packaging/alpine
$ abuild -C ./py3-cloup -r
$ abuild -C ./py3-extra-platforms -r
$ abuild -C ./py3-packageurl -r
$ abuild -C ./py3-click-extra -r
$ abuild -C ./meta-package-manager -r
$ doas apk add --repository ~/.local/share/abuild/alpine meta-package-manager
Each abuild run drops its packages in ~/.local/share/abuild/alpine (abuildβs default REPODEST), where the next builds and the final apk add pick them up.
The overlay carries the 4 dependency packages missing from the official aports tree (py3-click-extra, py3-cloup, py3-extra-platforms, py3-packageurl).
ChocolateyΒΆ
Build and install from the nuspec maintained in the repository:
> git clone https://github.com/kdeldycke/meta-package-manager.git
> cd meta-package-manager\packaging\choco\meta-package-manager
> choco pack
> choco install meta-package-manager --source .
This is the only supported install route: the Chocolatey community repository rejected the package over antivirus false positives on the bundled Windows binary.
GuixΒΆ
mpm landed in GNU Guix on 2026-06-28, so the in-repo definition is only needed to build the bleeding-edge version:
$ git clone https://github.com/kdeldycke/meta-package-manager.git
$ guix install --load-path=./meta-package-manager/packaging/guix meta-package-manager
MacPortsΒΆ
Build and install from the Portfile overlay maintained in the repository:
$ git clone https://github.com/kdeldycke/meta-package-manager.git
$ portindex ./meta-package-manager/packaging/macports
Then register the overlay as your first ports tree, by adding its absolute path at the top of /opt/local/etc/macports/sources.conf:
file:///path/to/meta-package-manager/packaging/macports
Finally:
$ sudo port install meta-package-manager
The overlay carries the 5 dependency ports missing from the official tree (py-click-extra, py-cloup, py-deepmerge, py-extra-platforms, py-packageurl-python), plus a py-boltons version bump.
Help land it in MacPorts
The port is pending review at macports/macports-ports#33609. Once merged, installation will be a one-liner:
$ sudo port install meta-package-manager
You can help move it forward by showing your support on the pull request.
NixΒΆ
Build and install from the definition maintained in the repository:
$ git clone https://github.com/kdeldycke/meta-package-manager.git
$ nix-env -f ./meta-package-manager/packaging/nix -i
On flake-enabled systems:
$ nix run github:kdeldycke/meta-package-manager?dir=packaging/nix -- --version
Help land it in nixpkgs
The nixpkgs package is pending review at NixOS/nixpkgs#506145. Once merged, installation will be a one-liner:
$ nix-env --install --attr nixpkgs.meta-package-manager
Or, without installing:
$ nix-shell -p meta-package-manager --run "mpm --version"
On flake-enabled systems:
$ nix run nixpkgs#meta-package-manager -- --version
You can help move it forward by showing your support on the pull request.
Void LinuxΒΆ
While the package is pending upstream review, build and install it from my forkβs mpm branch:
$ git clone --depth 1 --branch mpm https://github.com/kdeldycke/void-packages.git
$ cd ./void-packages
$ ./xbps-src binary-bootstrap
$ ./xbps-src pkg mpm
$ sudo xbps-install --repository=./hostdir/binpkgs/mpm mpm
./xbps-src pkg mpm cascades through and builds the 16 dependency packages introduced by the fork (15 new Python packages plus an in-place bump of python3-boltons from 20.2.1 to 25.0.0 for Python 3.14 compatibility).
Help land it in void-packages
The Void package is pending review at void-linux/void-packages#60532. Once merged, installation will be a one-liner:
$ xbps-install --sync mpm
You can help move it forward by showing your support on the pull request.