Skip to content

Commit 7d68e14

Browse files
committed
Add pulp_rust CLI impl + tests
Assisted-By: claude-opus-4.6
1 parent 0d49d13 commit 7d68e14

13 files changed

Lines changed: 471 additions & 0 deletions

File tree

CHANGES/+rust-cli.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added CLI support for the unreleased / tech-preview "pulp_rust" plugin, for creating local private registries and mirrors of public registries (i.e. crates.io) for Rust package content.

pulp-glue/src/pulp_glue/rust/__init__.py

Whitespace-only changes.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
from pulp_glue.common.context import (
2+
PluginRequirement,
3+
PulpContentContext,
4+
PulpDistributionContext,
5+
PulpRemoteContext,
6+
PulpRepositoryContext,
7+
PulpRepositoryVersionContext,
8+
)
9+
from pulp_glue.common.i18n import get_translation
10+
11+
translation = get_translation(__package__)
12+
_ = translation.gettext
13+
14+
15+
class PulpRustContentContext(PulpContentContext):
16+
PLUGIN = "rust"
17+
RESOURCE_TYPE = "packages"
18+
ENTITY = _("rust package")
19+
ENTITIES = _("rust packages")
20+
HREF = "rust_rust_package_content_href"
21+
ID_PREFIX = "content_rust_packages"
22+
NEEDS_PLUGINS = [PluginRequirement("rust")]
23+
24+
25+
class PulpRustDistributionContext(PulpDistributionContext):
26+
PLUGIN = "rust"
27+
RESOURCE_TYPE = "rust"
28+
ENTITY = _("rust distribution")
29+
ENTITIES = _("rust distributions")
30+
HREF = "rust_rust_distribution_href"
31+
ID_PREFIX = "distributions_rust_rust"
32+
NEEDS_PLUGINS = [PluginRequirement("rust")]
33+
34+
35+
class PulpRustRemoteContext(PulpRemoteContext):
36+
PLUGIN = "rust"
37+
RESOURCE_TYPE = "rust"
38+
ENTITY = _("rust remote")
39+
ENTITIES = _("rust remotes")
40+
HREF = "rust_rust_remote_href"
41+
ID_PREFIX = "remotes_rust_rust"
42+
NEEDS_PLUGINS = [PluginRequirement("rust")]
43+
44+
45+
class PulpRustRepositoryVersionContext(PulpRepositoryVersionContext):
46+
HREF = "rust_rust_repository_version_href"
47+
ID_PREFIX = "repositories_rust_rust_versions"
48+
NEEDS_PLUGINS = [PluginRequirement("rust")]
49+
50+
51+
class PulpRustRepositoryContext(PulpRepositoryContext):
52+
PLUGIN = "rust"
53+
RESOURCE_TYPE = "rust"
54+
HREF = "rust_rust_repository_href"
55+
ENTITY = _("rust repository")
56+
ENTITIES = _("rust repositories")
57+
ID_PREFIX = "repositories_rust_rust"
58+
VERSION_CONTEXT = PulpRustRepositoryVersionContext
59+
CAPABILITIES = {}
60+
NULLABLES = PulpRepositoryContext.NULLABLES | {"remote"}
61+
NEEDS_PLUGINS = [PluginRequirement("rust")]

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ core = "pulpcore.cli.core"
5151
file = "pulpcore.cli.file"
5252
python = "pulpcore.cli.python"
5353
rpm = "pulpcore.cli.rpm"
54+
rust = "pulpcore.cli.rust"
5455

5556
[dependency-groups]
5657
dev = [

src/pulpcore/cli/rust/__init__.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import typing as t
2+
3+
import click
4+
5+
from pulp_glue.common.i18n import get_translation
6+
7+
from pulp_cli.generic import pulp_group
8+
from pulpcore.cli.rust.content import content
9+
from pulpcore.cli.rust.distribution import distribution
10+
from pulpcore.cli.rust.remote import remote
11+
from pulpcore.cli.rust.repository import repository
12+
13+
translation = get_translation(__package__)
14+
_ = translation.gettext
15+
16+
17+
@pulp_group(name="rust")
18+
def rust_group() -> None:
19+
pass
20+
21+
22+
def mount(main: click.Group, **kwargs: t.Any) -> None:
23+
rust_group.add_command(repository)
24+
rust_group.add_command(remote)
25+
rust_group.add_command(distribution)
26+
rust_group.add_command(content)
27+
main.add_command(rust_group)

src/pulpcore/cli/rust/content.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import click
2+
3+
from pulp_glue.common.i18n import get_translation
4+
from pulp_glue.rust.context import PulpRustContentContext
5+
6+
from pulp_cli.generic import (
7+
content_filter_options,
8+
href_option,
9+
list_command,
10+
pulp_group,
11+
show_command,
12+
type_option,
13+
)
14+
15+
translation = get_translation(__package__)
16+
_ = translation.gettext
17+
18+
19+
@pulp_group()
20+
@type_option(
21+
choices={"rust": PulpRustContentContext},
22+
default="rust",
23+
)
24+
def content() -> None:
25+
pass
26+
27+
28+
lookup_options = [
29+
href_option,
30+
]
31+
32+
content.add_command(
33+
list_command(
34+
decorators=[
35+
click.option("--name"),
36+
click.option("--version"),
37+
*content_filter_options,
38+
]
39+
)
40+
)
41+
content.add_command(show_command(decorators=lookup_options))
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import click
2+
3+
from pulp_glue.common.i18n import get_translation
4+
from pulp_glue.rust.context import (
5+
PulpRustDistributionContext,
6+
PulpRustRemoteContext,
7+
PulpRustRepositoryContext,
8+
)
9+
10+
from pulp_cli.generic import (
11+
common_distribution_create_options,
12+
content_guard_option,
13+
create_command,
14+
destroy_command,
15+
distribution_filter_options,
16+
distribution_lookup_option,
17+
href_option,
18+
label_command,
19+
list_command,
20+
name_option,
21+
pulp_group,
22+
pulp_labels_option,
23+
pulp_option,
24+
resource_option,
25+
show_command,
26+
type_option,
27+
update_command,
28+
)
29+
30+
translation = get_translation(__package__)
31+
_ = translation.gettext
32+
33+
34+
repository_option = resource_option(
35+
"--repository",
36+
default_plugin="rust",
37+
default_type="rust",
38+
context_table={"rust:rust": PulpRustRepositoryContext},
39+
href_pattern=PulpRustRepositoryContext.HREF_PATTERN,
40+
help=_(
41+
"Repository to be used for auto-distributing."
42+
" Specified as '[[<plugin>:]<type>:]<name>' or as href."
43+
),
44+
)
45+
46+
47+
@pulp_group()
48+
@type_option(
49+
choices={"rust": PulpRustDistributionContext},
50+
default="rust",
51+
)
52+
def distribution() -> None:
53+
pass
54+
55+
56+
lookup_options = [href_option, name_option, distribution_lookup_option]
57+
nested_lookup_options = [distribution_lookup_option]
58+
update_options = [
59+
repository_option,
60+
pulp_option(
61+
"--version",
62+
type=int,
63+
help=_(
64+
"The repository version number to distribute."
65+
" When unset, the latest version of the repository will be auto-distributed."
66+
),
67+
),
68+
resource_option(
69+
"--remote",
70+
default_plugin="rust",
71+
default_type="rust",
72+
context_table={"rust:rust": PulpRustRemoteContext},
73+
href_pattern=PulpRustRemoteContext.HREF_PATTERN,
74+
help=_(
75+
"Remote to use for pull-through caching."
76+
" Specified as '[[<plugin>:]<type>:]<name>' or as href."
77+
),
78+
),
79+
content_guard_option,
80+
pulp_labels_option,
81+
pulp_option(
82+
"--allow-uploads/--no-allow-uploads",
83+
is_flag=True,
84+
default=None,
85+
help=_("Allow publishing crates via ``cargo publish``."),
86+
),
87+
]
88+
create_options = common_distribution_create_options + update_options
89+
90+
distribution.add_command(list_command(decorators=distribution_filter_options))
91+
distribution.add_command(show_command(decorators=lookup_options))
92+
distribution.add_command(create_command(decorators=create_options))
93+
distribution.add_command(
94+
update_command(decorators=lookup_options + update_options + [click.option("--base-path")])
95+
)
96+
distribution.add_command(destroy_command(decorators=lookup_options))
97+
distribution.add_command(label_command(decorators=nested_lookup_options))

src/pulpcore/cli/rust/remote.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import click
2+
3+
from pulp_glue.common.i18n import get_translation
4+
from pulp_glue.rust.context import PulpRustRemoteContext
5+
6+
from pulp_cli.generic import (
7+
common_remote_create_options,
8+
common_remote_update_options,
9+
create_command,
10+
destroy_command,
11+
href_option,
12+
label_command,
13+
list_command,
14+
name_option,
15+
pulp_group,
16+
remote_filter_options,
17+
remote_lookup_option,
18+
show_command,
19+
type_option,
20+
update_command,
21+
)
22+
23+
translation = get_translation(__package__)
24+
_ = translation.gettext
25+
26+
27+
@pulp_group()
28+
@type_option(
29+
choices={"rust": PulpRustRemoteContext},
30+
default="rust",
31+
)
32+
def remote() -> None:
33+
pass
34+
35+
36+
lookup_options = [href_option, name_option, remote_lookup_option]
37+
nested_lookup_options = [remote_lookup_option]
38+
rust_remote_options = [
39+
click.option(
40+
"--policy", type=click.Choice(["immediate", "on_demand", "streamed"], case_sensitive=False)
41+
),
42+
]
43+
44+
remote.add_command(list_command(decorators=remote_filter_options))
45+
remote.add_command(show_command(decorators=lookup_options))
46+
remote.add_command(create_command(decorators=common_remote_create_options + rust_remote_options))
47+
remote.add_command(
48+
update_command(decorators=lookup_options + common_remote_update_options + rust_remote_options)
49+
)
50+
remote.add_command(destroy_command(decorators=lookup_options))
51+
remote.add_command(label_command(decorators=nested_lookup_options))
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import click
2+
3+
from pulp_glue.common.context import (
4+
PulpRemoteContext,
5+
)
6+
from pulp_glue.common.i18n import get_translation
7+
from pulp_glue.rust.context import (
8+
PulpRustRemoteContext,
9+
PulpRustRepositoryContext,
10+
)
11+
12+
from pulp_cli.generic import (
13+
create_command,
14+
destroy_command,
15+
href_option,
16+
label_command,
17+
label_select_option,
18+
list_command,
19+
name_option,
20+
pulp_group,
21+
pulp_labels_option,
22+
repository_href_option,
23+
repository_lookup_option,
24+
resource_option,
25+
retained_versions_option,
26+
show_command,
27+
type_option,
28+
update_command,
29+
version_command,
30+
)
31+
from pulpcore.cli.core.generic import task_command
32+
33+
translation = get_translation(__package__)
34+
_ = translation.gettext
35+
36+
37+
remote_option = resource_option(
38+
"--remote",
39+
default_plugin="rust",
40+
default_type="rust",
41+
context_table={"rust:rust": PulpRustRemoteContext},
42+
href_pattern=PulpRemoteContext.HREF_PATTERN,
43+
help=_("Remote used for syncing in the form '[[<plugin>:]<resource_type>:]<name>' or by href."),
44+
)
45+
46+
47+
@pulp_group()
48+
@type_option(
49+
choices={"rust": PulpRustRepositoryContext},
50+
default="rust",
51+
)
52+
def repository() -> None:
53+
pass
54+
55+
56+
lookup_options = [href_option, name_option, repository_lookup_option]
57+
nested_lookup_options = [repository_href_option, repository_lookup_option]
58+
update_options = [
59+
click.option("--description"),
60+
remote_option,
61+
retained_versions_option,
62+
pulp_labels_option,
63+
]
64+
create_options = update_options + [click.option("--name", required=True)]
65+
66+
repository.add_command(
67+
list_command(
68+
decorators=[label_select_option, click.option("--name-startswith", "name__startswith")]
69+
)
70+
)
71+
repository.add_command(show_command(decorators=lookup_options))
72+
repository.add_command(create_command(decorators=create_options))
73+
repository.add_command(update_command(decorators=lookup_options + update_options))
74+
repository.add_command(destroy_command(decorators=lookup_options))
75+
repository.add_command(task_command(decorators=nested_lookup_options))
76+
repository.add_command(version_command(decorators=nested_lookup_options))
77+
repository.add_command(label_command(decorators=nested_lookup_options))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
3+
set -eu
4+
# shellcheck source=tests/scripts/config.source
5+
. "$(dirname "$(dirname "$(realpath "$0")")")"/config.source
6+
7+
pulp debug has-plugin --name "rust" || exit 23
8+
9+
expect_succ pulp rust content list
10+
expect_succ pulp rust content list --limit 5
11+
expect_succ pulp rust content list --name "itoa"
12+
expect_succ pulp rust content list --vers "1.0.0"

0 commit comments

Comments
 (0)