meta_package_manager.summary module¶
End-of-run summary printing for mpm subcommands.
Every long-running subcommand (installed, outdated, search,
dump, sbom) closes with a one-line summary written to stderr:
223 packages total (brew: 223).
Plus optional follow-up lines specific to that subcommand (the SBOM
writer surfaces upstream-document merge counts and dependency-graph
edge counts here). The whole summary is gated by the global
--summary/--no-summary flag and respects the user’s choice across
every subcommand uniformly.
Vocabulary note: “summary” describes the rendered text that lands on
stderr. “Stats” describes the raw numbers fed into it
(meta_package_manager.sbom.base.SBOM.stats() returns a dict of
counts). The two terms stay distinct deliberately: the
flag/module/function name reflects what the user sees; the data-side
method keeps the unambiguous stats name.
This module is the single home of the summary contract:
print_summary()is the renderer.package_counts()collapses the boilerplateCounter({manager_id: len(payload[manager_id]["packages"]) for ...})pattern thatinstalled,outdated, andsearchall share.sbom_summary()adaptsmeta_package_manager.sbom.base.SBOM.stats()to the(counter, notes)shapeprint_summary()consumes, conditional on what the run actually did.
The renderer stays in this module rather than scattered across each subcommand so the visual format is unique and obvious to find. The adapters live here too because their job is to translate subcommand-native shapes into the print contract, which is also summary-domain logic.
- meta_package_manager.summary.print_summary(counts, notes=())[source]¶
Print a one-line per-category count to stderr, plus optional follow-up notes.
countsis acollections.Counterkeyed by an opaque category label. The label is usually a package manager id, but thedump --brewfilesubcommand uses Brewfile entry types and any future caller is free to use whatever bucket makes sense. The parameter is namedcountsrather thanmanager_statsto avoid lying about the key’s meaning.Prints something like:
10 packages total (brew: 2, pip: 2, gem: 2, vscode: 2, npm: 2, composer: 0).
notesis an iterable of follow-up lines printed verbatim under the count line.mpm sbomuses it to surface facts that don’t fit the per-category-Counter shape: number of upstream SBOM documents merged into the aggregate, enrichment ratios, dependency-graph edge counts. Other subcommands today pass no notes; the count line is enough.Always writes to stderr so the call site is free to pipe stdout elsewhere (a generated SBOM document, a TOML manifest, a Brewfile) without the summary polluting the output. Gated upstream by the global
--summary/--no-summaryflag; this function itself is unconditional once called.- Return type:
- meta_package_manager.summary.package_counts(payload)[source]¶
Build a per-manager
Counterfrom a typical subcommand payload.installed,outdated, andsearchall stash their results in a{manager_id: {"packages": [...]}}dict. This helper turns that into the count-by-manager-idCounterthatprint_summary()accepts, eliminating theCounter({k: len(v["packages"]) for k, v in payload.items()})boilerplate that appeared verbatim at three CLI call sites.Mismatched payloads (an extractor that stashes packages under a different key, the
dump --brewfileline-counter pass) build theirCounterinline rather than wedging this helper into serving every shape.
- meta_package_manager.summary.sbom_summary(sbom, bundled)[source]¶
Adapt
meta_package_manager.sbom.base.SBOM.stats()to theprint_summary()shape.SBOM stats live on the renderer because the renderer knows what actually landed in the document (after dedup, after merge). This adapter flattens that structured dict into the count-line + follow-up-notes shape
print_summary()consumes, conditioning each note on what the run actually did so--minimalscans, casks-only runs, and formats without a merge concept all stay tidy.The function lives in this module (rather than next to the SBOM renderers) because its job is translating between two different data shapes: SBOM stats on one side, the print contract on the other. Summary-domain glue, not SBOM-domain logic.