Skip to content

Commit c807a0b

Browse files
committed
Handle duplicate filenames across multiple content
1 parent 32cf7aa commit c807a0b

1 file changed

Lines changed: 44 additions & 14 deletions

File tree

pulpcore/cli/python/repository.py

Lines changed: 44 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import typing as t
22

33
import click
4+
import schema as s
45
from pulp_glue.common.context import (
56
EntityFieldDefinition,
67
PluginRequirement,
@@ -15,14 +16,17 @@
1516
)
1617

1718
from pulp_cli.generic import (
19+
GroupOption,
1820
PulpCLIContext,
1921
create_command,
2022
create_content_json_callback,
2123
destroy_command,
2224
href_option,
25+
json_callback,
2326
label_command,
2427
label_select_option,
2528
list_command,
29+
load_file_wrapper,
2630
name_option,
2731
pass_pulp_context,
2832
pass_repository_context,
@@ -56,16 +60,35 @@
5660
)
5761

5862

59-
def _content_callback(
60-
ctx: click.Context, param: click.Parameter, value: t.Optional[str]
61-
) -> t.Optional[str]:
63+
def _content_callback(ctx: click.Context, param: click.Parameter, value: t.Any) -> t.Any:
6264
if value:
6365
pulp_ctx = ctx.find_object(PulpCLIContext)
6466
assert pulp_ctx is not None
65-
ctx.obj = PulpPythonContentContext(pulp_ctx, entity={"filename": value})
67+
ctx.obj = PulpPythonContentContext(pulp_ctx, entity=value)
6668
return value
6769

6870

71+
CONTENT_LIST_SCHEMA = s.Schema([{"sha256": str, "filename": s.And(str, len)}])
72+
73+
74+
@load_file_wrapper
75+
def _content_list_callback(
76+
ctx: click.Context, param: click.Parameter, value: t.Optional[str]
77+
) -> t.Any:
78+
if value is None:
79+
return None
80+
81+
result = json_callback(ctx, param, value)
82+
try:
83+
return CONTENT_LIST_SCHEMA.validate(result)
84+
except s.SchemaError as e:
85+
raise click.ClickException(
86+
_("Validation of '{parameter}' failed: {error}").format(
87+
parameter=param.name, error=str(e)
88+
)
89+
)
90+
91+
6992
@pulp_group()
7093
@click.option(
7194
"-t",
@@ -97,20 +120,27 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)
97120
pulp_labels_option,
98121
]
99122
create_options = update_options + [click.option("--name", required=True)]
100-
package_option = click.option(
101-
"--filename",
102-
callback=_content_callback,
103-
expose_value=False,
104-
help=_("Filename of the python package"),
123+
package_options = [
124+
click.option("--sha256", cls=GroupOption, expose_value=False, group=["filename"]),
125+
click.option(
126+
"--filename",
127+
callback=_content_callback,
128+
expose_value=False,
129+
cls=GroupOption,
130+
group=["sha256"],
131+
help=_("Filename of the python package"),
132+
),
133+
]
134+
content_json_callback = create_content_json_callback(
135+
PulpPythonContentContext, schema=CONTENT_LIST_SCHEMA
105136
)
106-
content_json_callback = create_content_json_callback(PulpPythonContentContext)
107137
modify_options = [
108138
click.option(
109139
"--add-content",
110140
callback=content_json_callback,
111141
help=_(
112142
"""JSON string with a list of objects to add to the repository.
113-
Each object should have the key: "filename"
143+
Each object must contain the following keys: "sha256", "filename".
114144
The argument prefixed with the '@' can be the path to a JSON file with a list of objects."""
115145
),
116146
),
@@ -119,7 +149,7 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)
119149
callback=content_json_callback,
120150
help=_(
121151
"""JSON string with a list of objects to remove from the repository.
122-
Each object should have the key: "filename"
152+
Each object must contain the following keys: "sha256", "filename".
123153
The argument prefixed with the '@' can be the path to a JSON file with a list of objects."""
124154
),
125155
),
@@ -136,8 +166,8 @@ def repository(ctx: click.Context, pulp_ctx: PulpCLIContext, /, repo_type: str)
136166
repository.add_command(
137167
repository_content_command(
138168
contexts={"package": PulpPythonContentContext},
139-
add_decorators=[package_option],
140-
remove_decorators=[package_option],
169+
add_decorators=package_options,
170+
remove_decorators=package_options,
141171
modify_decorators=modify_options,
142172
base_default_plugin="python",
143173
base_default_type="python",

0 commit comments

Comments
 (0)