From 5d37978ac0912f9ae6c31c46d727eb424b7ca234 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Dec 03 2025 14:59:59 +0000 Subject: [PATCH 1/2] write-signed-rpm: fix nvr fallback --- diff --git a/cli/koji_cli/commands.py b/cli/koji_cli/commands.py index 42d9339..6eddb50 100644 --- a/cli/koji_cli/commands.py +++ b/cli/koji_cli/commands.py @@ -1865,33 +1865,55 @@ def handle_write_signed_rpm(goptions, session, args): elif options.buildid: rpms = session.listRPMs(int(options.buildid)) else: - nvrs = [] - rpms = [] + # for historical reasons, we accept either rpms or builds on command line + rpm_args = [] + build_args = [] + + # first filter out invalid nvras, as getRPM will error on them + for arg in args: + if arg.isdigit(): + # we also accept rpm ids + rpm_args.append(int(arg)) + else: + try: + koji.parse_NVRA(arg) + rpm_args.append(arg) + # note that this is not perfect, many NVRs will succeed here + except koji.GenericError: + build_args.append(arg) + # look up rpms on hub + rpms = [] with session.multicall() as m: - result = [m.getRPM(nvra, strict=False) for nvra in args] - for rpm, nvra in zip(result, args): - rpm = rpm.result - if rpm: - rpms.append(rpm) + calls = [m.getRPM(r, strict=False) for r in rpm_args] + for call in calls: + rpminfo = call.result + if rpminfo: + rpms.append(rpminfo) else: - nvrs.append(nvra) + # fetch the unmatched arg from call args + build_args.append(call.args[0]) - # for historical reasons, we also accept nvrs - with session.multicall() as m: - result = [m.getBuild(nvr, strict=True) for nvr in nvrs] + # look up builds on hub builds = [] - for nvr, build in zip(nvrs, result): + with session.multicall() as m: + calls = [m.getBuild(nvr, strict=True) for nvr in build_args] + for call in calls: try: - builds.append(build.result['id']) + builds.append(call.result['id']) except koji.GenericError: - raise koji.GenericError("No such rpm or build: %s" % nvr) + # fetch the unmatched arg from call args + raise koji.GenericError("No such rpm or build: %s" % call.args[0]) + # look up rpms for builds with session.multicall() as m: rpm_lists = [m.listRPMs(buildID=build_id) for build_id in builds] for rpm_list in rpm_lists: rpms.extend(rpm_list.result) + if not rpms: + warn('No rpms found') + with session.multicall(strict=True) as m: for i, rpminfo in enumerate(rpms): nvra = "%(name)s-%(version)s-%(release)s.%(arch)s" % rpminfo From 126cb52e5e9696014ea6495056ecd1fa2e144c96 Mon Sep 17 00:00:00 2001 From: Mike McLean Date: Dec 03 2025 14:59:59 +0000 Subject: [PATCH 2/2] fix unit test --- diff --git a/tests/test_cli/test_write_signed_rpm.py b/tests/test_cli/test_write_signed_rpm.py index d12128f..3816336 100644 --- a/tests/test_cli/test_write_signed_rpm.py +++ b/tests/test_cli/test_write_signed_rpm.py @@ -128,8 +128,11 @@ class TestWriteSignedRPM(utils.CliTestCase): session = mock.MagicMock() mcall = session.multicall.return_value.__enter__.return_value - def vm(result): - m = koji.VirtualCall('mcall_method', [], {}) + # helper function for mocking multicall + def vm(result, args=None): + if args is None: + args = [] + m = koji.VirtualCall('mcall_method', args, {}) if isinstance(result, dict) and result.get('faultCode'): m._result = result else: @@ -151,7 +154,7 @@ class TestWriteSignedRPM(utils.CliTestCase): mcall.getRPM.side_effect = [ vm(rpm_data[0]), # bash-4.4.12-5.fc26.src - vm(None), # bash-4.4.12-5.fc26 + vm(None, args=['bash-4.4.12-5.fc26']), # bash-4.4.12-5.fc26 ] mcall.getBuild.return_value = vm({ 'package_name': 'bash', @@ -207,8 +210,9 @@ class TestWriteSignedRPM(utils.CliTestCase): # result: raise koji.GenericError mcall.writeSignedRPM.reset_mock() mcall.getRPM.side_effect = None - mcall.getRPM.return_value = vm(None) - mcall.getBuild.return_value = vm({'faultCode': 1000, 'faultString': 'x'}) + mcall.getRPM.return_value = vm(None, args=['gawk-4.1.4-3.fc26.x86_64']) + mcall.getBuild.return_value = vm({'faultCode': 1000, 'faultString': 'x'}, + args=['gawk-4.1.4-3.fc26.x86_64']) args = arguments + ['gawk-4.1.4-3.fc26.x86_64'] with self.assertRaises(koji.GenericError) as cm: