Skip to content

Commit e2f749f

Browse files
committed
Fix blocklist lookup for name-only entries
follow-up to #1391 Assisted By: Claude Opus 4.6
1 parent 727a472 commit e2f749f

4 files changed

Lines changed: 68 additions & 82 deletions

File tree

CHANGES/pulp-glue/1391.feature

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Added `PulpPythonBlocklistEntryContext` for `pulp_python>=3.30.0`.
1+
Added `PulpPythonBlocklistEntryContext` for `pulp_python>=3.30.2`.

pulp-glue/src/pulp_glue/python/context.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ class PulpPythonBlocklistEntryContext(PulpEntityContext):
174174
ENTITIES = _("blocklist entries")
175175
HREF = "python_python_python_blocklist_entry_href"
176176
ID_PREFIX = "repositories_python_python_blocklist_entries"
177-
NEEDS_PLUGINS = [PluginRequirement("python", specifier=">=3.30.0")]
177+
NEEDS_PLUGINS = [PluginRequirement("python", specifier=">=3.30.2")]
178178
repository_ctx: PulpPythonRepositoryContext
179179

180180
def __init__(

src/pulpcore/cli/python/repository.py

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
list_command,
3131
lookup_callback,
3232
name_option,
33-
pass_entity_context,
33+
option_group,
3434
pass_pulp_context,
3535
pass_repository_context,
3636
pulp_group,
@@ -155,7 +155,7 @@ def repository() -> None:
155155
)
156156

157157

158-
@repository.group(needs_plugins=[PluginRequirement("python", specifier=">=3.30.0")])
158+
@repository.group(needs_plugins=[PluginRequirement("python", specifier=">=3.30.2")])
159159
@pass_repository_context
160160
@pass_pulp_context
161161
@click.pass_context
@@ -172,77 +172,70 @@ def blocklist(
172172
ctx.obj = PulpPythonBlocklistEntryContext(pulp_ctx, repository_ctx)
173173

174174

175-
_HELP_BLOCKLIST_NAME = _("Package name to block. Required when 'filename' is not provided.")
176-
_HELP_BLOCKLIST_VERSION = _("Exact version to block. Only used when 'name' is set.")
177-
_HELP_BLOCKLIST_FILENAME = _("Exact filename to block. Required when 'name' is not provided.")
175+
def _blocklist_callback(ctx: click.Context, value: dict[str, t.Any]) -> t.Any:
176+
name = value.get("name")
177+
version = value.get("version")
178+
filename = value.get("filename")
179+
180+
if version and filename:
181+
raise click.ClickException(_("'version' cannot be used with 'filename'."))
182+
if version and not name:
183+
raise click.ClickException(_("'version' requires 'name' to be provided."))
184+
if name and filename:
185+
raise click.ClickException(_("Exactly one of 'name' or 'filename' must be provided."))
186+
187+
lookup: dict[str, t.Any] = {}
188+
if name and version:
189+
lookup = {"name": name, "version": version}
190+
elif name:
191+
lookup = {"name": name, "version__isnull": True}
192+
elif filename:
193+
lookup = {"filename": filename}
194+
195+
if lookup:
196+
entity_ctx = ctx.find_object(PulpEntityContext)
197+
assert entity_ctx is not None
198+
entity_ctx.entity = lookup
199+
178200

179201
blocklist_options = [
180-
click.option("--name", help=_HELP_BLOCKLIST_NAME),
181-
click.option("--version", help=_HELP_BLOCKLIST_VERSION),
182-
click.option("--filename", help=_HELP_BLOCKLIST_FILENAME),
183-
]
184-
blocklist_lookup_options = [
185-
pulp_option(
202+
click.option(
186203
"--name",
187-
help=_HELP_BLOCKLIST_NAME,
188-
callback=lookup_callback("name"),
189-
expose_value=False,
204+
help=_("Package name to block (all versions). Required when 'filename' is not provided."),
190205
),
191-
pulp_option(
192-
"--version",
193-
help=_HELP_BLOCKLIST_VERSION,
194-
callback=lookup_callback("version"),
195-
expose_value=False,
206+
click.option("--version", help=_("Package version to block. Only used when 'name' is set.")),
207+
click.option(
208+
"--filename", help=_("Package filename to block. Required when 'name' is not provided.")
196209
),
197-
pulp_option(
198-
"--filename",
199-
help=_HELP_BLOCKLIST_FILENAME,
200-
callback=lookup_callback("filename"),
210+
]
211+
blocklist_list_options = [
212+
click.option("--name", help="Package name to block."),
213+
click.option("--version", help="Package version to block."),
214+
click.option("--filename", help="Package filename to block."),
215+
]
216+
blocklist_lookup_options = blocklist_options + [
217+
option_group(
218+
"blocklist_lookup",
219+
["name", "version", "filename"],
220+
require_all=False,
201221
expose_value=False,
222+
callback=_blocklist_callback,
202223
),
203224
href_option,
204225
]
205226

206227
blocklist.add_command(
207228
create_command(name="add", decorators=nested_lookup_options + blocklist_options)
208229
)
209-
blocklist.add_command(list_command(decorators=nested_lookup_options + blocklist_options))
230+
blocklist.add_command(list_command(decorators=nested_lookup_options + blocklist_list_options))
210231
blocklist.add_command(show_command(decorators=nested_lookup_options + blocklist_lookup_options))
211-
212-
213-
@blocklist.command(name="remove")
214-
@repository_href_option
215-
@repository_lookup_option
216-
@click.option("--name", help=_HELP_BLOCKLIST_NAME)
217-
@click.option("--version", help=_HELP_BLOCKLIST_VERSION)
218-
@click.option("--filename", help=_HELP_BLOCKLIST_FILENAME)
219-
@href_option
220-
@pass_entity_context
221-
def blocklist_remove(
222-
entity_ctx: PulpEntityContext,
223-
/,
224-
name: str | None,
225-
version: str | None,
226-
filename: str | None,
227-
) -> None:
228-
"""
229-
Remove a blocklist entry.
230-
"""
231-
assert isinstance(entity_ctx, PulpPythonBlocklistEntryContext)
232-
if version and filename:
233-
raise click.ClickException(_("'version' cannot be used with 'filename'."))
234-
if version and not name:
235-
raise click.ClickException(_("'version' requires 'name' to be provided."))
236-
if name and filename:
237-
raise click.ClickException(_("Exactly one of 'name' or 'filename' must be provided."))
238-
239-
if name:
240-
entity_ctx.entity = {"name": name}
241-
if version:
242-
entity_ctx.entity = {"version": version}
243-
if filename:
244-
entity_ctx.entity = {"filename": filename}
245-
entity_ctx.delete()
232+
blocklist.add_command(
233+
destroy_command(
234+
name="remove",
235+
help=_("Remove a {entity}."),
236+
decorators=nested_lookup_options + blocklist_lookup_options,
237+
)
238+
)
246239

247240

248241
@repository.command()

tests/scripts/pulp_python/test_blocklist.sh

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -eu
44
# shellcheck source=tests/scripts/config.source
55
. "$(dirname "$(dirname "$(realpath "$0")")")"/config.source
66

7-
pulp debug has-plugin --name "python" --specifier ">=3.30.0" || exit 23
7+
pulp debug has-plugin --name "python" --specifier ">=3.30.2" || exit 23
88

99
cleanup() {
1010
pulp python repository destroy --name "cli_test_python_blocklist" || true
@@ -13,45 +13,38 @@ trap cleanup EXIT
1313

1414
expect_succ pulp python repository create --name "cli_test_python_blocklist"
1515

16-
# Test adding a blocklist entry by package name
16+
# Test adding blocklist entries
1717
expect_succ pulp python repository blocklist add --repository "cli_test_python_blocklist" --name "pkg"
1818
test "$(echo "$OUTPUT" | jq -r '.name')" = "pkg"
1919
test "$(echo "$OUTPUT" | jq -r '.version')" = "null"
2020
test "$(echo "$OUTPUT" | jq -r '.filename')" = "null"
2121
ENTRY_HREF="$(echo "$OUTPUT" | jq -r '.pulp_href')"
22+
expect_succ pulp python repository blocklist add --repository "cli_test_python_blocklist" --name "pkg" --version "2.0"
23+
expect_succ pulp python repository blocklist add --repository "cli_test_python_blocklist" --filename "pkg-3.0.tar.gz"
2224

2325
# Test listing blocklist entries
2426
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist"
25-
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "1"
27+
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "3"
2628
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist" --name "pkg"
27-
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "1"
29+
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "2"
2830
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist" --name "nonexistent"
2931
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "0"
3032

3133
# Test showing a specific blocklist entry
3234
expect_succ pulp python repository blocklist show --repository "cli_test_python_blocklist" --href "$ENTRY_HREF"
33-
expect_succ test "$(echo "$OUTPUT" | jq -r '.name')" = "pkg"
35+
test "$(echo "$OUTPUT" | jq -r '.name')" = "pkg"
36+
test "$(echo "$OUTPUT" | jq -r '.version')" = "null"
3437
expect_succ pulp python repository blocklist show --repository "cli_test_python_blocklist" --name "pkg"
35-
expect_succ test "$(echo "$OUTPUT" | jq -r '.name')" = "pkg"
38+
test "$(echo "$OUTPUT" | jq -r '.pulp_href')" = "$ENTRY_HREF"
3639

37-
# Test remove validation
38-
expect_fail pulp python repository blocklist remove --repository "cli_test_python_blocklist" --version "1.0" --filename "pkg-1.0.tar.gz"
39-
expect_fail pulp python repository blocklist remove --repository "cli_test_python_blocklist" --version "1.0"
40-
expect_fail pulp python repository blocklist remove --repository "cli_test_python_blocklist" --name "pkg" --filename "pkg-1.0.tar.gz"
40+
# Test input validation
41+
expect_fail pulp python repository blocklist show --repository "cli_test_python_blocklist" --version "1.0" --filename "pkg-1.0.tar.gz"
42+
expect_fail pulp python repository blocklist show --repository "cli_test_python_blocklist" --version "1.0"
43+
expect_fail pulp python repository blocklist show --repository "cli_test_python_blocklist" --name "pkg" --filename "pkg-1.0.tar.gz"
4144

42-
# Test removing a blocklist entry by href
45+
# Test removing blocklist entries
4346
expect_succ pulp python repository blocklist remove --repository "cli_test_python_blocklist" --href "$ENTRY_HREF"
44-
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist"
45-
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "0"
46-
47-
# Test removing a blocklist entry by package name + version
48-
expect_succ pulp python repository blocklist add --repository "cli_test_python_blocklist" --name "pkg" --version "2.0"
4947
expect_succ pulp python repository blocklist remove --repository "cli_test_python_blocklist" --name "pkg" --version "2.0"
50-
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist"
51-
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "0"
52-
53-
# Test removing a blocklist entry by package filename
54-
expect_succ pulp python repository blocklist add --repository "cli_test_python_blocklist" --filename "pkg-3.0.tar.gz"
5548
expect_succ pulp python repository blocklist remove --repository "cli_test_python_blocklist" --filename "pkg-3.0.tar.gz"
5649
expect_succ pulp python repository blocklist list --repository "cli_test_python_blocklist"
5750
expect_succ test "$(echo "$OUTPUT" | jq -r '.|length')" = "0"

0 commit comments

Comments
 (0)