Skip to content
Draft

WIP #1342

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES/1315.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed warnings about parameters being used multiple times.
13 changes: 13 additions & 0 deletions src/pulp_cli/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ def __init__(
):
self.allowed_with_contexts = allowed_with_contexts
self.needs_plugins = needs_plugins
self.option_processors: list[t.Callable[[click.Context], None]] = []
super().__init__(*args, **kwargs)

def invoke(self, ctx: click.Context) -> t.Any:
Expand All @@ -408,6 +409,8 @@ def invoke(self, ctx: click.Context) -> t.Any:
assert pulp_ctx is not None
for plugin_requirement in self.needs_plugins:
pulp_ctx.needs_plugin(plugin_requirement)
for processor in self.option_processors:
processor(ctx)
return super().invoke(ctx)
except PulpException as e:
raise click.ClickException(str(e))
Expand Down Expand Up @@ -483,6 +486,16 @@ def pulp_command(
return click.command(name=name, cls=PulpCommand, **kwargs)


def option_processor(
*, callback: t.Callable[[click.Context], None]
) -> t.Callable[[PulpCommand], PulpCommand]:
def _inner(cmd: PulpCommand) -> PulpCommand:
cmd.option_processors.append(callback)
return cmd

return _inner


def pulp_group(name: str | None = None, **kwargs: t.Any) -> t.Callable[[_AnyCallable], PulpGroup]:
"""
Pulp command group factory.
Expand Down
7 changes: 2 additions & 5 deletions src/pulpcore/cli/ansible/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ def remote(ctx: click.Context, pulp_ctx: PulpCLIContext, /, remote_type: str) ->
nested_lookup_options = [remote_lookup_option]
remote_options = [
click.option("--policy", help=_("policy to use when downloading")),
]
collection_options = [
pulp_option(
"--requirements-file",
callback=yaml_callback,
Expand Down Expand Up @@ -96,9 +94,8 @@ def remote(ctx: click.Context, pulp_ctx: PulpCLIContext, /, remote_type: str) ->
allowed_with_contexts=collection_context,
),
]
ansible_remote_options = remote_options + collection_options
create_options = common_remote_create_options + remote_options + ansible_remote_options
update_options = common_remote_update_options + remote_options + ansible_remote_options
create_options = common_remote_create_options + remote_options
update_options = common_remote_update_options + remote_options

remote.add_command(list_command(decorators=remote_filter_options))
remote.add_command(show_command(decorators=lookup_options))
Expand Down
45 changes: 15 additions & 30 deletions src/pulpcore/cli/container/content.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import gettext
import typing as t

import click

from pulp_glue.common.context import PluginRequirement, PulpEntityContext
from pulp_glue.common.context import PluginRequirement, PulpContentContext
from pulp_glue.container.context import (
PulpContainerBlobContext,
PulpContainerManifestContext,
PulpContainerTagContext,
)

from pulp_cli.generic import (
GroupOption,
PulpCLIContext,
content_filter_options,
href_option,
label_command,
list_command,
option_processor,
pass_pulp_context,
pulp_group,
pulp_option,
Expand All @@ -26,14 +25,18 @@
_ = gettext.gettext


def _content_callback(ctx: click.Context, param: click.Parameter, value: t.Any) -> None:
if value is not None:
entity_ctx = ctx.find_object(PulpEntityContext)
def _content_callback(ctx: click.Context) -> None:
lookup = {
key: value
for key, value in ((key, ctx.params.pop(key, None)) for key in ["name", "digest"])
if value is not None
}
if lookup:
entity_ctx = ctx.find_object(PulpContentContext)
assert entity_ctx is not None
if isinstance(entity_ctx, PulpContainerTagContext):
entity_ctx.entity = value
else:
entity_ctx.entity = {"digest": value}
if isinstance(entity_ctx, PulpContainerTagContext) and len(lookup) != 2:
raise click.UsageError(_("Both 'name' and 'digest' are needed to describe a tag."))
entity_ctx.entity = lookup


@pulp_group()
Expand Down Expand Up @@ -98,33 +101,15 @@ def content(ctx: click.Context, pulp_ctx: PulpCLIContext, /, content_type: str)
lookup_options = [
pulp_option(
"--digest",
expose_value=False,
help=_("Digest associated with {entity}"),
callback=_content_callback,
allowed_with_contexts=(PulpContainerBlobContext, PulpContainerManifestContext),
),
click.option(
"--digest",
expose_value=False,
help=_("Digest associated with {entity}"),
callback=_content_callback,
allowed_with_contexts=(PulpContainerTagContext,),
group=[
"name",
],
cls=GroupOption,
),
click.option(
pulp_option(
"--name",
expose_value=False,
help=_("Name of {entity}"),
allowed_with_contexts=(PulpContainerTagContext,),
group=[
"digest",
],
cls=GroupOption,
),
href_option,
option_processor(callback=_content_callback),
]

content.add_command(list_command(decorators=list_options))
Expand Down
20 changes: 11 additions & 9 deletions src/pulpcore/cli/core/content_guard.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ def x509(ctx: click.Context, pulp_ctx: PulpCLIContext, /) -> None:


certguard_create_options = common_create_options + [
click.option("--description"),
click.option(
"--ca-certificate",
help=_("a PEM encoded CA certificate or @file containing same"),
Expand All @@ -212,14 +211,17 @@ def x509(ctx: click.Context, pulp_ctx: PulpCLIContext, /) -> None:
),
]

certguard_update_options = lookup_options + [
click.option("--description"),
click.option(
"--ca-certificate",
help=_("a PEM encoded CA certificate or @file containing same"),
callback=load_string_callback,
),
]
certguard_update_options = (
lookup_options
+ common_update_options
+ [
click.option(
"--ca-certificate",
help=_("a PEM encoded CA certificate or @file containing same"),
callback=load_string_callback,
),
]
)


x509.add_command(list_command(decorators=filter_options))
Expand Down
44 changes: 25 additions & 19 deletions src/pulpcore/cli/file/repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
)

from pulp_cli.generic import (
GroupOption,
PulpCLIContext,
create_command,
create_content_json_callback,
Expand All @@ -29,6 +28,7 @@
list_command,
load_file_wrapper,
name_option,
option_processor,
pass_pulp_context,
pass_repository_context,
pulp_group,
Expand Down Expand Up @@ -60,12 +60,20 @@
)


def _content_callback(ctx: click.Context, param: click.Parameter, value: t.Any) -> t.Any:
if value:
pulp_ctx = ctx.find_object(PulpCLIContext)
assert pulp_ctx is not None
ctx.obj = PulpFileContentContext(pulp_ctx, entity=value)
return value
def _content_callback(ctx: click.Context) -> t.Any:
lookup = {
key: value
for key, value in ((key, ctx.params.pop(key, None)) for key in ["sha256", "relative_path"])
if value is not None
}
if lookup:
if len(lookup) != 2:
raise click.UsageError(
_("Both 'sha256' and 'relative-path' must be provided to specify a file content.")
)
entity_ctx = ctx.find_object(PulpFileContentContext)
assert entity_ctx is not None
entity_ctx.entity = lookup


CONTENT_LIST_SCHEMA = s.Schema([{"sha256": str, "relative_path": s.And(str, len)}])
Expand Down Expand Up @@ -119,15 +127,10 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)
pulp_labels_option,
]
create_options = update_options + [click.option("--name", required=True)]
file_options = [
click.option("--sha256", cls=GroupOption, expose_value=False, group=["relative_path"]),
click.option(
"--relative-path",
cls=GroupOption,
expose_value=False,
group=["sha256"],
callback=_content_callback,
),
file_content_options = [
click.option("--sha256"),
click.option("--relative-path"),
option_processor(callback=_content_callback),
]
content_json_callback = create_content_json_callback(
PulpFileContentContext, schema=CONTENT_LIST_SCHEMA
Expand Down Expand Up @@ -155,7 +158,10 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)

repository.add_command(
list_command(
decorators=[label_select_option, click.option("--name-startswith", "name__startswith")]
decorators=[
label_select_option,
click.option("--name-startswith", "name__startswith"),
]
)
)
repository.add_command(show_command(decorators=lookup_options))
Expand All @@ -170,8 +176,8 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)
contexts={"file": PulpFileContentContext},
base_default_plugin="file",
base_default_type="file",
add_decorators=file_options,
remove_decorators=file_options,
add_decorators=file_content_options,
remove_decorators=file_content_options,
modify_decorators=modify_options,
)
)
Expand Down
14 changes: 5 additions & 9 deletions src/pulpcore/cli/rpm/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,15 +354,11 @@ def content() -> None:
@pulp_option(
"--file",
type=click.File("rb"),
required=True,
help=_("An advisory JSON file."),
allowed_with_contexts=(PulpRpmAdvisoryContext,),
)
@pulp_option(
"--file",
type=click.File("rb"),
help=_("An RPM binary. One of --file or --directory is required."),
allowed_with_contexts=(PulpRpmPackageContext,),
help=_("A file to upload. One of --file or --directory is required."),
allowed_with_contexts=(
PulpRpmAdvisoryContext,
PulpRpmPackageContext,
),
required=False,
)
@pulp_option(
Expand Down
1 change: 1 addition & 0 deletions tests/test_help_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def getter(self: t.Any) -> None:


@pytest.mark.help_page(base_cmd=[])
@pytest.mark.filterwarnings("error::UserWarning:click")
def test_accessing_the_help_page_does_not_invoke_api(
no_api: None,
args: list[str],
Expand Down
Loading