From 181ed88bfbabd105fea9d3f5fae66d2f39a4971a Mon Sep 17 00:00:00 2001 From: Daniel Alley Date: Thu, 23 Apr 2026 13:50:13 -0400 Subject: [PATCH] Rename RustContent to RustPackage --- .ci/scripts/check_release.py | 15 +- CLAUDE.md | 2 +- pulp_rust/app/migrations/0001_initial.py | 204 +++++++++++++----- .../0005_rename_rustcontent_rustpackage.py | 17 ++ pulp_rust/app/models.py | 22 +- pulp_rust/app/serializers.py | 31 +-- pulp_rust/app/tasks/publishing.py | 8 +- pulp_rust/app/tasks/synchronizing.py | 4 +- pulp_rust/app/tasks/yanking.py | 4 +- pulp_rust/app/urls.py | 6 +- pulp_rust/app/views.py | 12 +- pulp_rust/app/viewsets.py | 18 +- .../functional/api/test_download_content.py | 2 +- .../tests/functional/api/test_publish.py | 2 +- .../api/test_pull_through_caching.py | 8 +- pulp_rust/tests/unit/test_models.py | 4 +- 16 files changed, 247 insertions(+), 112 deletions(-) create mode 100644 pulp_rust/app/migrations/0005_rename_rustcontent_rustpackage.py diff --git a/.ci/scripts/check_release.py b/.ci/scripts/check_release.py index 0825480..3e07cf9 100755 --- a/.ci/scripts/check_release.py +++ b/.ci/scripts/check_release.py @@ -100,7 +100,8 @@ def main(options: argparse.Namespace, template_config: dict[str, t.Any]) -> int: # Warning: This will not work if branch names contain "/" but we don't really care here. heads = [h.split("/")[-1] for h in repo.git.branch("--remote").split("\n")] available_branches = sorted( - {h for h in heads if re.fullmatch(RELEASE_BRANCH_REGEX, h)}, key=lambda ver: Version(ver) + {h for h in heads if re.fullmatch(RELEASE_BRANCH_REGEX, h)}, + key=lambda ver: Version(ver), ) + [DEFAULT_BRANCH] branches = options.branches @@ -145,12 +146,20 @@ def main(options: argparse.Namespace, template_config: dict[str, t.Any]) -> int: last_tag = repo.git.describe("--tags", "--abbrev=0", f"{remote}/{branch}") req_txt_diff = repo.git.diff( - f"{last_tag}", f"{remote}/{branch}", "--name-only", "--", "requirements.txt" + f"{last_tag}", + f"{remote}/{branch}", + "--name-only", + "--", + "requirements.txt", ) if req_txt_diff: reasons.append("requirements.txt") pyproject_diff = repo.git.diff( - f"{last_tag}", f"{remote}/{branch}", "--name-only", "--", "pyproject.toml" + f"{last_tag}", + f"{remote}/{branch}", + "--name-only", + "--", + "pyproject.toml", ) if pyproject_diff: reasons.extend(check_pyproject_dependencies(repo, last_tag, f"{remote}/{branch}")) diff --git a/CLAUDE.md b/CLAUDE.md index b09f674..9ab69a0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,6 +63,6 @@ For understanding the Cargo registry protocol, refer to the upstream documentati ## Common pitfalls - **Cargo.toml is authoritative during publish**: When a crate is published, dependencies are extracted from the `Cargo.toml` inside the `.crate` tarball, NOT from the JSON metadata submitted alongside it. This is an intentional security measure (see rust-lang/cargo#14492). -- **RustDependency is NOT a Content type**: Unlike `RustContent` and `RustPackageYank`, `RustDependency` is a regular Django model with an FK to `RustContent`. Do not treat it as a Pulpcore Content subclass. +- **RustDependency is NOT a Content type**: Unlike `RustPackage` and `RustPackageYank`, `RustDependency` is a regular Django model with an FK to `RustPackage`. Do not treat it as a Pulpcore Content subclass. - **Django app label is `rust`, not `pulp_rust`**: When running Django management commands (e.g. `makemigrations`), use the app label `rust`. The Python package is `pulp_rust` but the Django app label is set to `rust` in `PulpRustPluginAppConfig`. diff --git a/pulp_rust/app/migrations/0001_initial.py b/pulp_rust/app/migrations/0001_initial.py index be69154..6942e4f 100644 --- a/pulp_rust/app/migrations/0001_initial.py +++ b/pulp_rust/app/migrations/0001_initial.py @@ -6,99 +6,197 @@ class Migration(migrations.Migration): - initial = True dependencies = [ - ('core', '0106_alter_artifactdistribution_distribution_ptr_and_more'), + ("core", "0106_alter_artifactdistribution_distribution_ptr_and_more"), ] operations = [ migrations.CreateModel( - name='RustContent', + name="RustContent", fields=[ - ('content_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.content')), - ('name', models.CharField(db_index=True, max_length=255)), - ('canonical_name', models.CharField(db_index=True, max_length=255)), - ('vers', models.CharField(db_index=True, max_length=64)), - ('cksum', models.CharField(db_index=True, max_length=64)), - ('features', models.JSONField(blank=True, default=dict)), - ('features2', models.JSONField(blank=True, default=dict, null=True)), - ('links', models.CharField(blank=True, max_length=255, null=True)), - ('rust_version', models.CharField(blank=True, max_length=32, null=True)), - ('v', models.IntegerField(default=1)), - ('_pulp_domain', models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, to='core.domain')), + ( + "content_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.content", + ), + ), + ("name", models.CharField(db_index=True, max_length=255)), + ("canonical_name", models.CharField(db_index=True, max_length=255)), + ("vers", models.CharField(db_index=True, max_length=64)), + ("cksum", models.CharField(db_index=True, max_length=64)), + ("features", models.JSONField(blank=True, default=dict)), + ("features2", models.JSONField(blank=True, default=dict, null=True)), + ("links", models.CharField(blank=True, max_length=255, null=True)), + ( + "rust_version", + models.CharField(blank=True, max_length=32, null=True), + ), + ("v", models.IntegerField(default=1)), + ( + "_pulp_domain", + models.ForeignKey( + default=pulpcore.app.util.get_domain_pk, + on_delete=django.db.models.deletion.PROTECT, + to="core.domain", + ), + ), ], options={ - 'default_related_name': '%(app_label)s_%(model_name)s', - 'unique_together': {('name', 'vers', 'cksum', '_pulp_domain')}, + "default_related_name": "%(app_label)s_%(model_name)s", + "unique_together": {("name", "vers", "cksum", "_pulp_domain")}, }, - bases=('core.content',), + bases=("core.content",), ), migrations.CreateModel( - name='RustDistribution', + name="RustDistribution", fields=[ - ('distribution_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.distribution')), - ('allow_uploads', models.BooleanField(default=False)), + ( + "distribution_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.distribution", + ), + ), + ("allow_uploads", models.BooleanField(default=False)), ], options={ - 'default_related_name': '%(app_label)s_%(model_name)s', + "default_related_name": "%(app_label)s_%(model_name)s", }, - bases=('core.distribution',), + bases=("core.distribution",), ), migrations.CreateModel( - name='RustRemote', + name="RustRemote", fields=[ - ('remote_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.remote')), + ( + "remote_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.remote", + ), + ), ], options={ - 'default_related_name': '%(app_label)s_%(model_name)s', + "default_related_name": "%(app_label)s_%(model_name)s", }, - bases=('core.remote',), + bases=("core.remote",), ), migrations.CreateModel( - name='RustRepository', + name="RustRepository", fields=[ - ('repository_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.repository')), + ( + "repository_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.repository", + ), + ), ], options={ - 'default_related_name': '%(app_label)s_%(model_name)s', + "default_related_name": "%(app_label)s_%(model_name)s", }, - bases=('core.repository',), + bases=("core.repository",), ), migrations.CreateModel( - name='RustDependency', + name="RustDependency", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=255)), - ('req', models.CharField(max_length=255)), - ('features', models.JSONField(blank=True, default=list)), - ('optional', models.BooleanField(default=False)), - ('default_features', models.BooleanField(default=True)), - ('target', models.CharField(blank=True, max_length=255, null=True)), - ('kind', models.CharField(choices=[('normal', 'Normal'), ('dev', 'Development'), ('build', 'Build')], default='normal', max_length=16)), - ('registry', models.CharField(blank=True, max_length=512, null=True)), - ('package', models.CharField(blank=True, max_length=255, null=True)), - ('content', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dependencies', to='rust.rustcontent')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=255)), + ("req", models.CharField(max_length=255)), + ("features", models.JSONField(blank=True, default=list)), + ("optional", models.BooleanField(default=False)), + ("default_features", models.BooleanField(default=True)), + ("target", models.CharField(blank=True, max_length=255, null=True)), + ( + "kind", + models.CharField( + choices=[ + ("normal", "Normal"), + ("dev", "Development"), + ("build", "Build"), + ], + default="normal", + max_length=16, + ), + ), + ("registry", models.CharField(blank=True, max_length=512, null=True)), + ("package", models.CharField(blank=True, max_length=255, null=True)), + ( + "content", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="dependencies", + to="rust.rustcontent", + ), + ), ], options={ - 'verbose_name_plural': 'rust dependencies', - 'default_related_name': '%(app_label)s_%(model_name)s', - 'indexes': [models.Index(fields=['content', 'kind'], name='rust_rustde_content_a46e30_idx'), models.Index(fields=['name'], name='rust_rustde_name_6a2db4_idx')], + "verbose_name_plural": "rust dependencies", + "default_related_name": "%(app_label)s_%(model_name)s", + "indexes": [ + models.Index( + fields=["content", "kind"], + name="rust_rustde_content_a46e30_idx", + ), + models.Index(fields=["name"], name="rust_rustde_name_6a2db4_idx"), + ], }, ), migrations.CreateModel( - name='RustPackageYank', + name="RustPackageYank", fields=[ - ('content_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.content')), - ('name', models.CharField(db_index=True, max_length=255)), - ('vers', models.CharField(db_index=True, max_length=64)), - ('_pulp_domain', models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, to='core.domain')), + ( + "content_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.content", + ), + ), + ("name", models.CharField(db_index=True, max_length=255)), + ("vers", models.CharField(db_index=True, max_length=64)), + ( + "_pulp_domain", + models.ForeignKey( + default=pulpcore.app.util.get_domain_pk, + on_delete=django.db.models.deletion.PROTECT, + to="core.domain", + ), + ), ], options={ - 'default_related_name': '%(app_label)s_%(model_name)s', - 'unique_together': {('name', 'vers', '_pulp_domain')}, + "default_related_name": "%(app_label)s_%(model_name)s", + "unique_together": {("name", "vers", "_pulp_domain")}, }, - bases=('core.content',), + bases=("core.content",), ), ] diff --git a/pulp_rust/app/migrations/0005_rename_rustcontent_rustpackage.py b/pulp_rust/app/migrations/0005_rename_rustcontent_rustpackage.py new file mode 100644 index 0000000..56a6854 --- /dev/null +++ b/pulp_rust/app/migrations/0005_rename_rustcontent_rustpackage.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.11 on 2026-04-23 17:49 + +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("core", "0149_distributedpublication"), + ("rust", "0004_alter_rustcargotoken_options_and_more"), + ] + + operations = [ + migrations.RenameModel( + old_name="RustContent", + new_name="RustPackage", + ), + ] diff --git a/pulp_rust/app/models.py b/pulp_rust/app/models.py index fa7bbbc..1231c6b 100755 --- a/pulp_rust/app/models.py +++ b/pulp_rust/app/models.py @@ -54,7 +54,7 @@ def _parse_crate_relative_path(relative_path): return crate_name, version -class RustContent(Content): +class RustPackage(Content): """ The "rust" content type representing a Cargo package version. @@ -134,7 +134,7 @@ class RustContent(Content): @staticmethod def init_from_artifact_and_relative_path(artifact, relative_path): """ - Create an unsaved RustContent from a downloaded .crate artifact. + Create an unsaved RustPackage from a downloaded .crate artifact. Called by pulpcore's content handler during pull-through caching. Extracts full metadata (dependencies, features, etc.) from the @@ -144,7 +144,7 @@ def init_from_artifact_and_relative_path(artifact, relative_path): with artifact.file.open("rb") as f: cargo_toml = extract_cargo_toml(f, crate_name, version) - content = RustContent( + content = RustPackage( name=crate_name, canonical_name=canonicalize_crate_name(crate_name), vers=version, @@ -175,7 +175,7 @@ class RustDependency(models.Model): """ Represents a dependency of a Cargo package version. - Each RustContent (package version) can have multiple dependencies. + Each RustPackage (package version) can have multiple dependencies. Dependencies are stored as separate records to enable efficient querying and relationship tracking. @@ -193,7 +193,7 @@ class RustDependency(models.Model): """ # The package version that declares this dependency - content = models.ForeignKey(RustContent, on_delete=models.CASCADE, related_name="dependencies") + content = models.ForeignKey(RustPackage, on_delete=models.CASCADE, related_name="dependencies") # Name of the dependency as used in the code (may differ from package name if renamed) name = models.CharField(max_length=255, blank=False, null=False) @@ -249,7 +249,7 @@ class Meta: class RustRemote(Remote, AutoAddObjPermsMixin): """ - A Remote for RustContent. + A Remote for RustPackage. The `url` field should point to the sparse index root, optionally prefixed with `sparse+` (e.g. `sparse+https://index.crates.io/`). @@ -287,7 +287,7 @@ def get_remote_artifact_url(self, relative_path=None, request=None): def get_remote_artifact_content_type(relative_path=None): """Return the content type for the given relative path.""" if relative_path and relative_path.endswith(".crate"): - return RustContent + return RustPackage return None class Meta: @@ -304,7 +304,7 @@ class RustPackageYank(Content): This is a per-repository marker: its presence in a repository version means the (name, vers) pair is yanked in that repository. Its absence means it is not yanked. This allows yanked status to vary across repositories without - mutating the global RustContent object. + mutating the global RustPackage object. """ TYPE = "rust_yank" @@ -322,12 +322,12 @@ class Meta: class RustRepository(Repository, AutoAddObjPermsMixin): """ - A Repository for RustContent. + A Repository for RustPackage. """ TYPE = "rust" - CONTENT_TYPES = [RustContent, RustPackageYank] + CONTENT_TYPES = [RustPackage, RustPackageYank] REMOTE_TYPES = [RustRemote] PULL_THROUGH_SUPPORTED = True @@ -341,7 +341,7 @@ class Meta: class RustDistribution(Distribution, AutoAddObjPermsMixin): """ - A Distribution for RustContent. + A Distribution for RustPackage. Define any additional fields for your new distribution if needed. """ diff --git a/pulp_rust/app/serializers.py b/pulp_rust/app/serializers.py index 510b1ca..8e94dc6 100755 --- a/pulp_rust/app/serializers.py +++ b/pulp_rust/app/serializers.py @@ -51,7 +51,9 @@ class RustDependencySerializer(serializers.ModelSerializer): ) optional = serializers.BooleanField( - default=False, required=False, help_text=_("Whether this is an optional dependency") + default=False, + required=False, + help_text=_("Whether this is an optional dependency"), ) default_features = serializers.BooleanField( @@ -102,9 +104,9 @@ class Meta: ) -class RustContentSerializer(core_serializers.SingleArtifactContentSerializer): +class RustPackageSerializer(core_serializers.SingleArtifactContentSerializer): """ - Serializer for RustContent (Cargo package version). + Serializer for RustPackage (Cargo package version). Represents a single version of a Rust crate as defined in the Cargo registry index specification. Includes package metadata, dependencies, and features. @@ -115,7 +117,9 @@ class RustContentSerializer(core_serializers.SingleArtifactContentSerializer): vers = serializers.CharField(help_text=_("Semantic version string (SemVer 2.0.0)")) dependencies = RustDependencySerializer( - many=True, required=False, help_text=_("List of dependencies for this package version") + many=True, + required=False, + help_text=_("List of dependencies for this package version"), ) cksum = serializers.CharField(help_text=_("SHA256 checksum of the .crate file (tarball)")) @@ -143,7 +147,9 @@ class RustContentSerializer(core_serializers.SingleArtifactContentSerializer): ) v = serializers.IntegerField( - default=1, required=False, help_text=_("Schema version of the index entry format") + default=1, + required=False, + help_text=_("Schema version of the index entry format"), ) rust_version = serializers.CharField( allow_null=True, @@ -152,7 +158,7 @@ class RustContentSerializer(core_serializers.SingleArtifactContentSerializer): ) def create(self, validated_data): - """Create RustContent and related dependencies.""" + """Create RustPackage and related dependencies.""" dependencies_data = validated_data.pop("dependencies", []) validated_data["canonical_name"] = canonicalize_crate_name(validated_data["name"]) content = super().create(validated_data) @@ -164,7 +170,7 @@ def create(self, validated_data): return content def update(self, instance, validated_data): - """Update RustContent and related dependencies.""" + """Update RustPackage and related dependencies.""" dependencies_data = validated_data.pop("dependencies", None) instance = super().update(instance, validated_data) @@ -189,7 +195,7 @@ class Meta: "v", "rust_version", ) - model = models.RustContent + model = models.RustPackage class RustRemoteSerializer(core_serializers.RemoteSerializer): @@ -214,7 +220,6 @@ class RustRepositorySerializer(core_serializers.RepositorySerializer): A Serializer for RustRepository. Add any new fields if defined on RustRepository. - Similar to the example above, in RustContentSerializer. Additional validators can be added to the parent validators list For example:: @@ -234,7 +239,6 @@ class RustDistributionSerializer(core_serializers.DistributionSerializer): A Serializer for RustDistribution. Add any new fields if defined on RustDistribution. - Similar to the example above, in RustContentSerializer. Additional validators can be added to the parent validators list For example:: @@ -308,7 +312,10 @@ def validate(self, data): return data class Meta: - fields = core_serializers.DistributionSerializer.Meta.fields + ("allow_uploads", "remote") + fields = core_serializers.DistributionSerializer.Meta.fields + ( + "allow_uploads", + "remote", + ) model = models.RustDistribution @@ -329,7 +336,7 @@ class Meta: read_only_fields = ("token", "last_used") -class YankSerializer(serializers.Serializer): +class RustPackageYankSerializer(serializers.Serializer): """Serializer for yank/unyank operations on a repository.""" name = serializers.CharField( diff --git a/pulp_rust/app/tasks/publishing.py b/pulp_rust/app/tasks/publishing.py index 1204a9b..b1d8578 100644 --- a/pulp_rust/app/tasks/publishing.py +++ b/pulp_rust/app/tasks/publishing.py @@ -6,7 +6,7 @@ from pulpcore.plugin.models import Artifact, ContentArtifact from pulpcore.plugin.tasking import aadd_and_remove -from pulp_rust.app.models import RustContent, RustDependency, RustRepository +from pulp_rust.app.models import RustDependency, RustPackage, RustRepository from pulp_rust.app.utils import ( canonicalize_crate_name, extract_cargo_toml, @@ -52,7 +52,7 @@ async def apublish_package(repository_pk, metadata, crate_path): """ Publish a crate to a repository. - Creates the Artifact, RustContent, ContentArtifact, and RustDependency records, + Creates the Artifact, RustPackage, ContentArtifact, and RustDependency records, then adds the content to a new repository version. Args: @@ -98,7 +98,7 @@ async def apublish_package(repository_pk, metadata, crate_path): # multiple repositories. Including cksum in the lookup allows different # crates with the same name+version (e.g. a private crate shadowing a # public one) to coexist as separate content objects within a domain. - content = await RustContent.objects.filter( + content = await RustPackage.objects.filter( name=name, vers=vers, cksum=cksum, @@ -106,7 +106,7 @@ async def apublish_package(repository_pk, metadata, crate_path): ).afirst() if content is None: - content = RustContent( + content = RustPackage( name=name, canonical_name=canonical_name, vers=vers, diff --git a/pulp_rust/app/tasks/synchronizing.py b/pulp_rust/app/tasks/synchronizing.py index 1d0edd5..3866130 100755 --- a/pulp_rust/app/tasks/synchronizing.py +++ b/pulp_rust/app/tasks/synchronizing.py @@ -9,7 +9,7 @@ Stage, ) -from pulp_rust.app.models import RustContent, RustRemote +from pulp_rust.app.models import RustPackage, RustRemote log = logging.getLogger(__name__) @@ -75,7 +75,7 @@ async def run(self): raise NotImplementedError("Not implemented") for entry in self.read_my_metadata_file_somehow(result.path): - unit = RustContent(entry) # make the content unit in memory-only + unit = RustPackage(entry) # make the content unit in memory-only artifact = Artifact(entry) # make Artifact in memory-only da = DeclarativeArtifact( artifact, diff --git a/pulp_rust/app/tasks/yanking.py b/pulp_rust/app/tasks/yanking.py index 0ed70e3..8e6196b 100644 --- a/pulp_rust/app/tasks/yanking.py +++ b/pulp_rust/app/tasks/yanking.py @@ -1,6 +1,6 @@ from pulpcore.plugin.tasking import aadd_and_remove -from pulp_rust.app.models import RustContent, RustPackageYank, RustRepository +from pulp_rust.app.models import RustPackage, RustPackageYank, RustRepository from pulp_rust.app.utils import canonicalize_crate_name @@ -15,7 +15,7 @@ async def ayank_package(repository_pk, name, vers): latest = await repository.alatest_version() # Verify the package version exists in this repository - exists = await RustContent.objects.filter( + exists = await RustPackage.objects.filter( pk__in=latest.content, canonical_name=name, vers=vers ).aexists() if not exists: diff --git a/pulp_rust/app/urls.py b/pulp_rust/app/urls.py index d20514d..9e89e81 100644 --- a/pulp_rust/app/urls.py +++ b/pulp_rust/app/urls.py @@ -31,7 +31,11 @@ CargoDownloadApiView.as_view(), name="cargo-download-api", ), - path(CRATES_IO_URL + "config.json", IndexRoot.as_view({"get": "retrieve"}), name="index-root"), + path( + CRATES_IO_URL + "config.json", + IndexRoot.as_view({"get": "retrieve"}), + name="index-root", + ), path( CRATES_IO_URL + "", CargoIndexApiViewSet.as_view({"get": "retrieve"}), diff --git a/pulp_rust/app/views.py b/pulp_rust/app/views.py index 10ead26..9f168a4 100644 --- a/pulp_rust/app/views.py +++ b/pulp_rust/app/views.py @@ -27,14 +27,14 @@ from pulp_rust.app.auth import CargoTokenAuthentication from pulp_rust.app.models import ( - RustContent, RustDistribution, + RustPackage, RustPackageYank, _strip_sparse_prefix, ) from pulp_rust.app.serializers import ( IndexRootSerializer, - RustContentSerializer, + RustPackageSerializer, ) from pulp_rust.app.tasks import ( apublish_package, @@ -128,7 +128,7 @@ def get_repository_version(distribution): @staticmethod def get_content(repository_version): """Returns queryset of the content in this repository version.""" - return RustContent.objects.filter(pk__in=repository_version.content) + return RustPackage.objects.filter(pk__in=repository_version.content) def get_rvc(self): """Takes the base_path and returns the repository_version and content.""" @@ -175,7 +175,7 @@ class CargoIndexApiViewSet(ApiMixin, ViewSet): @extend_schema( tags=["Cargo: Metadata"], - responses={200: RustContentSerializer}, + responses={200: RustPackageSerializer}, summary="Get package metadata", ) def retrieve(self, request, path, **kwargs): @@ -390,7 +390,7 @@ def put(self, request, **kwargs): canonical = canonicalize_crate_name(name) vers_base = strip_semver_build_metadata(vers) repo_version = distro.repository.latest_version() - if RustContent.objects.filter( + if RustPackage.objects.filter( pk__in=repo_version.content, canonical_name=canonical, vers=vers_base ).exists(): return cargo_error(f"crate version `{name}@{vers}` is already uploaded") @@ -495,7 +495,7 @@ def delete(self, request, name, version, rest, **kwargs): canonical = canonicalize_crate_name(name) repo_version = distro.repository.latest_version() - if not RustContent.objects.filter( + if not RustPackage.objects.filter( pk__in=repo_version.content, canonical_name=canonical, vers=version ).exists(): return HttpResponse( diff --git a/pulp_rust/app/viewsets.py b/pulp_rust/app/viewsets.py index c065de6..12e72f6 100755 --- a/pulp_rust/app/viewsets.py +++ b/pulp_rust/app/viewsets.py @@ -19,9 +19,9 @@ from . import models, serializers, tasks -class RustContentFilter(core.ContentFilter): +class RustPackageFilter(core.ContentFilter): """ - FilterSet for RustContent (Cargo packages). + FilterSet for RustPackage (Cargo packages). Provides filtering capabilities for package name, version, and checksum. """ @@ -39,7 +39,7 @@ class RustContentFilter(core.ContentFilter): rust_version = CharFilter(field_name="rust_version") class Meta: - model = models.RustContent + model = models.RustPackage fields = [ "name", "vers", @@ -48,9 +48,9 @@ class Meta: ] -class RustContentViewSet(core.ReadOnlyContentViewSet): +class RustPackageViewSet(core.ReadOnlyContentViewSet): """ - A read-only ViewSet for RustContent (Cargo package versions). + A read-only ViewSet for RustPackage (Cargo package versions). Content is created via ``cargo publish`` (the Cargo registry API), not through this viewset. @@ -59,9 +59,9 @@ class RustContentViewSet(core.ReadOnlyContentViewSet): """ endpoint_name = "packages" - queryset = models.RustContent.objects.prefetch_related("dependencies").all() - serializer_class = serializers.RustContentSerializer - filterset_class = RustContentFilter + queryset = models.RustPackage.objects.prefetch_related("dependencies").all() + serializer_class = serializers.RustPackageSerializer + filterset_class = RustPackageFilter DEFAULT_ACCESS_POLICY = { "statements": [ @@ -330,7 +330,7 @@ def add_cached_content(self, request, pk): Add to the repository any new content that was cached using the remote since the last repository version was created. - The ``repository`` field has to be provided. + The `repository` field has to be provided. """ serializer = serializers.RepositoryAddCachedContentSerializer( data=request.data, context={"request": request, "repository_pk": pk} diff --git a/pulp_rust/tests/functional/api/test_download_content.py b/pulp_rust/tests/functional/api/test_download_content.py index 0c374be..6d815fe 100644 --- a/pulp_rust/tests/functional/api/test_download_content.py +++ b/pulp_rust/tests/functional/api/test_download_content.py @@ -50,7 +50,7 @@ def test_download_content( repository = rust_repo_api_client.read(repository.pulp_href) assert not repository.latest_version_href.endswith("/versions/0/") - # Check that Pulp created a RustContent record + # Check that Pulp created a RustPackage record content_response = rust_content_api_client.list(name="itoa", vers="1.0.0") assert content_response.count == 1 diff --git a/pulp_rust/tests/functional/api/test_publish.py b/pulp_rust/tests/functional/api/test_publish.py index ac3c0c4..c381e65 100644 --- a/pulp_rust/tests/functional/api/test_publish.py +++ b/pulp_rust/tests/functional/api/test_publish.py @@ -380,7 +380,7 @@ def test_cargo_publish_cross_repo_reuses_pull_through_content( admin_auth_headers, ): """Publishing a crate that was already cached via pull-through should reuse - the same global RustContent object. + the same global RustPackage object. Content in Pulp is shared within a domain. When a crate is first cached via pull-through and then published to a private registry, the publish diff --git a/pulp_rust/tests/functional/api/test_pull_through_caching.py b/pulp_rust/tests/functional/api/test_pull_through_caching.py index 4025f82..08cc02c 100644 --- a/pulp_rust/tests/functional/api/test_pull_through_caching.py +++ b/pulp_rust/tests/functional/api/test_pull_through_caching.py @@ -99,7 +99,7 @@ def test_pull_through_on_demand_creates_content( rust_content_api_client, cargo_registry_url, ): - """on_demand pull-through should create a RustContent record and cache the artifact.""" + """on_demand pull-through should create a RustPackage record and cache the artifact.""" remote = rust_remote_factory(url=CRATES_IO_URL, policy="on_demand") repository = rust_repo_factory(remote=remote.pulp_href) distribution = rust_distribution_factory( @@ -111,7 +111,7 @@ def test_pull_through_on_demand_creates_content( downloaded = download_file(pulp_unit_url) assert downloaded.response_obj.status == 200 - # A RustContent record should have been created + # A RustPackage record should have been created content_response = rust_content_api_client.list(name="itoa", vers="1.0.0") assert content_response.count == 1 @@ -155,7 +155,7 @@ def test_pull_through_streamed_no_content_created( rust_content_api_client, cargo_registry_url, ): - """streamed: pull-through should NOT create a RustContent record.""" + """streamed: pull-through should NOT create a RustPackage record.""" remote = rust_remote_factory(url=CRATES_IO_URL, policy="streamed") repository = rust_repo_factory(remote=remote.pulp_href) distribution = rust_distribution_factory( @@ -167,7 +167,7 @@ def test_pull_through_streamed_no_content_created( downloaded = download_file(pulp_unit_url) assert downloaded.response_obj.status == 200 - # No RustContent record should have been created + # No RustPackage record should have been created content_response = rust_content_api_client.list(name="itoa", vers="1.0.0") assert content_response.count == 0 diff --git a/pulp_rust/tests/unit/test_models.py b/pulp_rust/tests/unit/test_models.py index b6bebd3..22faa5f 100644 --- a/pulp_rust/tests/unit/test_models.py +++ b/pulp_rust/tests/unit/test_models.py @@ -65,9 +65,9 @@ def test_two_digit_version(self): class TestGetRemoteArtifactContentType: def test_crate_file(self): - from pulp_rust.app.models import RustContent + from pulp_rust.app.models import RustPackage - assert RustRemote.get_remote_artifact_content_type("serde/serde-1.0.0.crate") is RustContent + assert RustRemote.get_remote_artifact_content_type("serde/serde-1.0.0.crate") is RustPackage def test_non_crate_file(self): assert RustRemote.get_remote_artifact_content_type("se/rd/serde") is None