~postmarketos/pmbootstrap

43b0cf2b6be1a907ab5b795e155f5b965369f05b — Clayton Craft 8 months ago 23e99ed craftyguy/pmb_recommends_all
pmb.install: support pmb_recommends for any package

This refactors the get_recommends function that was originally used for
UI packages to support pmb_recommends for any package (and subpackage).
3 files changed, 44 insertions(+), 35 deletions(-)

M pmb/config/__init__.py
M pmb/install/_install.py
M pmb/install/ui.py
M pmb/config/__init__.py => pmb/config/__init__.py +3 -3
@@ 696,9 696,9 @@ apkbuild_package_attributes = {
    "install": {"array": True},
    "triggers": {"array": True},

    # UI meta-packages can specify apps in "_pmb_recommends" to be explicitly
    # installed by default, and not implicitly as dependency of the UI meta-
    # package ("depends"). This makes these apps uninstallable, without
    # Packages can specify soft dependencies in "_pmb_recommends" to be
    # explicitly installed by default, and not implicitly as a hard dependency
    # of the package ("depends"). This makes these apps uninstallable, without
    # removing the meta-package. (#1933). To disable this feature, use:
    # "pmbootstrap install --no-recommends".
    "_pmb_recommends": {"array": True},

M pmb/install/_install.py => pmb/install/_install.py +41 -2
@@ 1054,6 1054,44 @@ def get_selected_providers(args, packages):
    return providers


def get_recommends(args, packages):
    """
        Look through the specified packages and collect additional packages
        specified under _pmb_recommends in them. This is recursive, so it will
        dive into packages that are listed under recommends to collect any
        packages they might also have listed under their own _pmb_recommends.

        If running with pmbootstrap install --no-recommends, this function
        returns an empty list.

        :returns: list of pkgnames, e.g. ["chatty", "gnome-contacts"] """
    ret = []
    if not args.install_recommends:
        return ret

    for package in packages:
        # Note that this ignores packages that don't exist. This means they
        # aren't in pmaports. This is fine, with the assumption that
        # installation will fail later in some other method if they truly don't
        # exist in any repo.
        apkbuild = pmb.helpers.pmaports.get(args, package, must_exist=False)
        if not apkbuild:
            continue
        if package in apkbuild["subpackages"]:
            # Just focus on the subpackage
            apkbuild = apkbuild["subpackages"][package]
        recommends = apkbuild["_pmb_recommends"]
        if recommends:
            logging.debug(f"{package}: install _pmb_recommends:"
                          f" {', '.join(recommends)}")
            ret += recommends
            # Call recursively in case recommends have pmb_recommends of their
            # own.
            ret += get_recommends(args, recommends)

    return ret


def create_device_rootfs(args, step, steps):
    # List all packages to be installed (including the ones specified by --add)
    # and upgrade the installed packages/apkindexes


@@ 1082,8 1120,6 @@ def create_device_rootfs(args, step, steps):
    if args.ui.lower() != "none":
        if args.ui_extras:
            install_packages += ["postmarketos-ui-" + args.ui + "-extras"]
        if args.install_recommends:
            install_packages += pmb.install.ui.get_recommends(args)
    if args.extra_packages.lower() != "none":
        install_packages += args.extra_packages.split(",")
    if args.add:


@@ 1112,6 1148,9 @@ def create_device_rootfs(args, step, steps):

    pmb.helpers.repo.update(args, args.deviceinfo["arch"])

    # Install uninstallable "dependencies" by default
    install_packages += get_recommends(args, install_packages)

    # Explicitly call build on the install packages, to re-build them or any
    # dependency, in case the version increased
    if args.build_pkgs_on_install:

M pmb/install/ui.py => pmb/install/ui.py +0 -30
@@ 5,36 5,6 @@ import logging
import pmb.helpers.pmaports


def get_recommends(args):
    """ Get all packages listed in _pmb_recommends of the UI and UI-extras
        package, unless running with pmbootstrap install --no-recommends.

        :returns: list of pkgnames, e.g. ["chatty", "gnome-contacts"] """
    ret = []
    if not args.install_recommends or args.ui == "none":
        return ret

    # UI package
    meta = f"postmarketos-ui-{args.ui}"
    apkbuild = pmb.helpers.pmaports.get(args, meta)
    recommends = apkbuild["_pmb_recommends"]
    if recommends:
        logging.debug(f"{meta}: install _pmb_recommends:"
                      f" {', '.join(recommends)}")
        ret += recommends

    # UI-extras subpackage
    meta_extras = f"{meta}-extras"
    if args.ui_extras and meta_extras in apkbuild["subpackages"]:
        recommends = apkbuild["subpackages"][meta_extras]["_pmb_recommends"]
        if recommends:
            logging.debug(f"{meta_extras}: install _pmb_recommends:"
                          f" {', '.join(recommends)}")
            ret += recommends

    return ret


def get_groups(args):
    """ Get all groups to which the user additionally must be added.
        The list of groups are listed in _pmb_groups of the UI and