Source code for meta_package_manager.inventory

# Copyright Kevin Deldycke <kevin@deldycke.com> and contributors.
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
"""Introspection utilities to produce comparison matrixes between managers."""

from __future__ import annotations

from pathlib import Path

from click_extra.docs_update import replace_content
from tabulate import tabulate

from .base import Operations
from .platforms import PLATFORM_GROUPS
from .pool import pool


[docs]def operation_matrix() -> str: """Inspect manager and print a matrix of their current implementation.""" # Build up the column titles. headers = [ "Package manager", "Min. version", ] # Footnotes are used to details the OSes covered by each platform group. footnotes = [] for group in PLATFORM_GROUPS: header_title = group.name # Add footnote for groups with more than one platform. if len(group.platforms) > 1: footnote_tag = f"[^{group.id}]" header_title += footnote_tag platforms_string = ", ".join( sorted((p.name for p in group.platforms), key=str.casefold), ) footnotes.append(f"{footnote_tag}: {group.name}: {platforms_string}.") headers.append(header_title) headers.extend(f"`{op.name}`" for op in Operations) table = [] for mid, m in sorted(pool.items()): line = [ f"[`{mid}`]({m.homepage_url})" + ("" if not m.deprecated else f" [⚠️]({m.deprecation_url})"), f"{m.requirement}", ] for group in PLATFORM_GROUPS: line.append( group.icon if group.issubset(m.platforms) and group.icon else "", ) for op in Operations: line.append("βœ“" if m.implements(op) else "") table.append(line) # Set each column alignment. alignments = ["left", "left"] alignments.extend(["center"] * len(PLATFORM_GROUPS)) alignments.extend(["center"] * len(Operations)) rendered_table = tabulate( table, headers=headers, tablefmt="github", colalign=alignments, disable_numparse=True, ) # Manually produce Markdown alignment hints. This has been proposed upstream at: # https://github.com/astanin/python-tabulate/pull/261 # https://github.com/astanin/python-tabulate/issues/53 separators = [] for col_index, header in enumerate(headers): cells = [line[col_index] for line in table] + [header] max_len = max(len(c) for c in cells) align = alignments[col_index] if align == "center": sep = f":{'-' * (max_len - 2)}:" elif align == "right": sep = f"{'-' * (max_len - 1)}:" else: sep = "-" * max_len separators.append(sep) header_separator = f"| {' | '.join(separators)} |" lines = rendered_table.splitlines() lines[1] = header_separator output = "\n".join(lines) if footnotes: output += "\n\n" output += "\n\n".join(footnotes) return output
[docs]def update_readme() -> None: """Update `readme.md` at the root of the project with the implementation table for each manager we support.""" replace_content( Path(__file__).parent.parent.joinpath("readme.md"), "<!-- operation-matrix-start -->\n\n", "\n\n<!-- operation-matrix-end -->", operation_matrix(), )