jw-pkg/src/python/jw/pkg/cmds/projects/CmdRequiredOsPkg.py
Jan Lindemann 2b951f7861
All checks were successful
CI / Packaging - Kali Linux (pull_request) Successful in 4m51s
CI / Packaging - OpenSUSE Tumbleweed (pull_request) Successful in 4m34s
CI / Packaging test (pull_request) Successful in 0s
CI / Packaging - Kali Linux (push) Successful in 4m40s
CI / Packaging - OpenSUSE Tumbleweed (push) Successful in 4m39s
CI / Packaging test (push) Successful in 0s
CmdRequiredOsPkg: Don't modify deps while iterating
--skip-excluded removed excluded modules from deps with
deps.remove() while iterating over deps. Removing an element
shifts the remaining elements to the left, so the loop skipped
the entry following each removed one, and consecutively
excluded modules survived the filter and leaked into the
output.

Build the filtered list with a comprehension instead.

Assisted-by: unsloth/Qwen3.8-27B-GGUF:Q4_K_M with pi.dev v0.84.2
Signed-off-by: Jan Lindemann <jan@janware.com>
2026-09-13 18:28:13 +02:00

71 lines
2.5 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING, override
from ...App import Scope
from ...lib.log import DEBUG, log
from .Cmd import Cmd, Parent
if TYPE_CHECKING:
from argparse import ArgumentParser, Namespace
# TODO: seems at least partly redundant to CmdPkgRequires / print_pkg_relations
class CmdRequiredOsPkg(Cmd): # export
def __init__(self, parent: Parent) -> None:
super().__init__(
parent,
'required-os-pkg',
help = 'List distribution packages required for a package',
)
@override
def add_arguments(self, parser: ArgumentParser) -> None:
super().add_arguments(parser)
parser.add_argument('flavours', help = 'Dependency flavours', default = 'build')
parser.add_argument('modules', nargs = '*', help = 'Modules')
parser.add_argument(
'--skip-excluded',
action = 'store_true',
default = False,
help = 'Output empty prerequisite list for excluded modules',
)
parser.add_argument(
'--quote',
action = 'store_true',
default = False,
help = 'Put double quotes around each listed dependency',
)
@override
async def _run(self, args: Namespace) -> None:
modules = args.modules
flavours = set(args.flavours.split(','))
if 'build' in flavours:
# TODO: This adds too much. Only the run dependencies of the build
# dependencies would be needed.
flavours.add('run')
if 'release' in flavours:
flavours |= set(['run', 'devel', 'build'])
log(DEBUG, 'flavours = ' + args.flavours)
deps = self.app.get_project_refs(
modules,
['pkg.requires.jw'],
list(flavours),
scope = Scope.Subtree,
add_self = True,
names_only = True,
)
if args.skip_excluded:
deps = [d for d in deps if self.app.is_excluded_from_build(d) is None]
subsecs = self.app.distro.os_cascade
log(DEBUG, 'subsecs = ', subsecs)
requires: set[str] = set()
for sec in subsecs:
for flavour in flavours:
vals = self.app.get_values(deps, ['pkg.requires.' + sec], [flavour])
if vals:
requires |= set(vals)
out = [f'"{dep}"' for dep in requires] if args.quote else requires
# TODO: add all not in build tree as -devel
print(' '.join(out))