diff --git a/.ci/ansible/filter/repr.py b/.ci/ansible/filter/repr.py index 8455c34..c8c1678 100644 --- a/.ci/ansible/filter/repr.py +++ b/.ci/ansible/filter/repr.py @@ -1,4 +1,5 @@ from __future__ import absolute_import, division, print_function + from packaging.version import parse as parse_version __metaclass__ = type diff --git a/.ci/scripts/calc_constraints.py b/.ci/scripts/calc_constraints.py index b8acb95..2341ccc 100755 --- a/.ci/scripts/calc_constraints.py +++ b/.ci/scripts/calc_constraints.py @@ -7,11 +7,12 @@ import argparse import fileinput -import urllib.request import sys +import urllib.request + +import yaml from packaging.requirements import Requirement from packaging.version import Version -import yaml try: import tomllib diff --git a/.ci/scripts/check_gettext.sh b/.ci/scripts/check_gettext.sh deleted file mode 100755 index 9be3c93..0000000 --- a/.ci/scripts/check_gettext.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/bash - -# WARNING: DO NOT EDIT! -# -# This file was generated by plugin_template, and is managed by it. Please use -# './plugin-template --github pulp_rust' to update this file. -# -# For more info visit https://github.com/pulp/plugin_template - -# make sure this script runs at the repo root -cd "$(dirname "$(realpath -e "$0")")"/../.. - -set -uv - -MATCHES=$(grep -n -r --include \*.py "_(f") - -if [ $? -ne 1 ]; then - printf "\nERROR: Detected mix of f-strings and gettext:\n" - echo "$MATCHES" - exit 1 -fi diff --git a/.ci/scripts/check_pulpcore_imports.sh b/.ci/scripts/check_pulpcore_imports.sh index 9395913..fb61e12 100755 --- a/.ci/scripts/check_pulpcore_imports.sh +++ b/.ci/scripts/check_pulpcore_imports.sh @@ -10,10 +10,10 @@ # make sure this script runs at the repo root cd "$(dirname "$(realpath -e "$0")")"/../.. -set -uv +set -u # check for imports not from pulpcore.plugin. exclude tests -MATCHES=$(grep -n -r --include \*.py "from pulpcore.*import" . | grep -v "tests\|plugin") +MATCHES="$(grep -n -r --include \*.py "from pulpcore.*import" pulp_rust | grep -v "tests\|plugin")" if [ $? -ne 1 ]; then printf "\nERROR: Detected bad imports from pulpcore:\n" diff --git a/.ci/scripts/check_release.py b/.ci/scripts/check_release.py index 6e07999..0825480 100755 --- a/.ci/scripts/check_release.py +++ b/.ci/scripts/check_release.py @@ -9,16 +9,16 @@ # /// import argparse -import re import os +import re import sys import tomllib import typing as t from pathlib import Path import yaml -from packaging.version import Version from git import Repo +from packaging.version import Version RELEASE_BRANCH_REGEX = r"^([0-9]+)\.([0-9]+)$" Y_CHANGELOG_EXTS = [".feature"] @@ -157,9 +157,9 @@ def main(options: argparse.Namespace, template_config: dict[str, t.Any]) -> int: if reasons: curr_version = Version(last_tag) - assert curr_version.base_version.startswith( - branch - ), "Current-version has to belong to the current branch!" + assert curr_version.base_version.startswith(branch), ( + "Current-version has to belong to the current branch!" + ) next_version = Version(f"{branch}.{curr_version.micro + 1}") print( f"A Z-release is needed for {branch}, " diff --git a/.ci/scripts/check_requirements.py b/.ci/scripts/check_requirements.py index 3a8a31d..2f99b50 100755 --- a/.ci/scripts/check_requirements.py +++ b/.ci/scripts/check_requirements.py @@ -7,12 +7,12 @@ import tomllib import warnings + from packaging.requirements import Requirement CHECK_MATRIX = [ ("pyproject.toml", True, True, True), ("requirements.txt", True, True, True), - ("dev_requirements.txt", False, True, False), ("ci_requirements.txt", False, True, True), ("doc_requirements.txt", False, True, False), ("lint_requirements.txt", False, True, True), diff --git a/.ci/scripts/skip_tests.py b/.ci/scripts/skip_tests.py index a68d000..380a3da 100755 --- a/.ci/scripts/skip_tests.py +++ b/.ci/scripts/skip_tests.py @@ -15,12 +15,13 @@ *: Error """ -import sys +import argparse import os import re -import git +import sys import textwrap -import argparse + +import git DOC_PATTERNS = [ r"^docs/", diff --git a/.ci/scripts/validate_commit_message.py b/.ci/scripts/validate_commit_message.py index a4dc900..2aab908 100644 --- a/.ci/scripts/validate_commit_message.py +++ b/.ci/scripts/validate_commit_message.py @@ -6,9 +6,9 @@ import subprocess import sys import tomllib -import yaml from pathlib import Path +import yaml from github import Github diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 18c6107..0000000 --- a/.flake8 +++ /dev/null @@ -1,34 +0,0 @@ -# WARNING: DO NOT EDIT! -# -# This file was generated by plugin_template, and is managed by it. Please use -# './plugin-template --github pulp_rust' to update this file. -# -# For more info visit https://github.com/pulp/plugin_template -[flake8] -exclude = ./docs/*,*/migrations/* -per-file-ignores = */__init__.py: F401 - -ignore = E203,W503,Q000,Q003,D100,D104,D106,D200,D205,D400,D401,D402,F824 -max-line-length = 100 - -# Flake8 builtin codes -# -------------------- -# E203: no whitespace around ':'. disabled until https://github.com/PyCQA/pycodestyle/issues/373 is fixed -# W503: This enforces operators before line breaks which is not pep8 or black compatible. -# F824: 'nonlocal' is unused: name is never assigned in scope - -# Flake8-quotes extension codes -# ----------------------------- -# Q000: double or single quotes only, default is double (don't want to enforce this) -# Q003: Change outer quotes to avoid escaping inner quotes - -# Flake8-docstring extension codes -# -------------------------------- -# D100: missing docstring in public module -# D104: missing docstring in public package -# D106: missing docstring in public nested class (complains about "class Meta:" and documenting those is silly) -# D200: one-line docstring should fit on one line with quotes -# D205: 1 blank line required between summary line and description -# D400: First line should end with a period -# D401: first line should be imperative (nitpicky) -# D402: first line should not be the function’s “signature” (false positives) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 7bda1ec..732b53f 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -36,20 +36,13 @@ jobs: run: | yamllint -s -d '{extends: relaxed, rules: {line-length: disable}}' .github/workflows - # run black separately from flake8 to get a diff - - name: "Run black" + - name: "Check formating" run: | - black --version - black --check --diff . + ruff format --check --diff - # Lint code. - - name: "Run flake8" + - name: "Lint code" run: | - flake8 - - - name: "Check for common gettext problems" - run: | - sh .ci/scripts/check_gettext.sh + ruff check - name: "Run extra lint checks" run: | diff --git a/.github/workflows/scripts/stage-changelog-for-default-branch.py b/.github/workflows/scripts/stage-changelog-for-default-branch.py index d20df32..d0cf11f 100755 --- a/.github/workflows/scripts/stage-changelog-for-default-branch.py +++ b/.github/workflows/scripts/stage-changelog-for-default-branch.py @@ -12,13 +12,15 @@ from git import Repo from git.exc import GitCommandError -helper = textwrap.dedent("""\ +helper = textwrap.dedent( + """\ Stage the changelog for a release on main branch. Example: $ python .github/workflows/scripts/stage-changelog-for-default-branch.py 3.4.0 - """) + """ +) parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, description=helper) diff --git a/.github/workflows/scripts/update_backport_labels.py b/.github/workflows/scripts/update_backport_labels.py index 9f1f9de..73ed732 100755 --- a/.github/workflows/scripts/update_backport_labels.py +++ b/.github/workflows/scripts/update_backport_labels.py @@ -5,10 +5,11 @@ # # For more info visit https://github.com/pulp/plugin_template +import os +import random + import requests import yaml -import random -import os def random_color(): diff --git a/dev_requirements.txt b/dev_requirements.txt deleted file mode 100644 index a29b796..0000000 --- a/dev_requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -check-manifest -flake8 -flake8-black diff --git a/lint_requirements.txt b/lint_requirements.txt index 8cda1d2..1788224 100644 --- a/lint_requirements.txt +++ b/lint_requirements.txt @@ -5,10 +5,8 @@ # # For more info visit https://github.com/pulp/plugin_template -black~=26.3 # Pin style to the year. https://black.readthedocs.io/en/stable/faq.html#how-stable-is-black-s-style bump-my-version check-manifest -flake8 -flake8-black packaging +ruff yamllint diff --git a/pulp_rust/app/models.py b/pulp_rust/app/models.py index 4b6352d..1ad9dea 100755 --- a/pulp_rust/app/models.py +++ b/pulp_rust/app/models.py @@ -3,22 +3,22 @@ from logging import getLogger from django.db import models -from django_lifecycle import hook, AFTER_CREATE - -from pulp_rust.app.utils import ( - canonicalize_crate_name, - extract_cargo_toml, - extract_dependencies, -) +from django_lifecycle import AFTER_CREATE, hook from pulpcore.plugin.models import ( Content, + Distribution, Remote, Repository, - Distribution, ) from pulpcore.plugin.util import get_domain_pk +from pulp_rust.app.utils import ( + canonicalize_crate_name, + extract_cargo_toml, + extract_dependencies, +) + logger = getLogger(__name__) # Cache for the "dl" template from each registry's config.json. diff --git a/pulp_rust/app/serializers.py b/pulp_rust/app/serializers.py index 68f5778..acc854a 100755 --- a/pulp_rust/app/serializers.py +++ b/pulp_rust/app/serializers.py @@ -1,6 +1,6 @@ import logging - from gettext import gettext as _ + from rest_framework import serializers from pulpcore.plugin import models as core_models diff --git a/pulp_rust/app/tasks/synchronizing.py b/pulp_rust/app/tasks/synchronizing.py index 2ec9a71..1d0edd5 100755 --- a/pulp_rust/app/tasks/synchronizing.py +++ b/pulp_rust/app/tasks/synchronizing.py @@ -1,5 +1,5 @@ -from gettext import gettext as _ import logging +from gettext import gettext as _ from pulpcore.plugin.models import Artifact, ProgressReport, Remote, Repository # noqa from pulpcore.plugin.stages import ( diff --git a/pulp_rust/app/urls.py b/pulp_rust/app/urls.py index 3d3e45a..d20514d 100644 --- a/pulp_rust/app/urls.py +++ b/pulp_rust/app/urls.py @@ -2,11 +2,11 @@ from django.urls import path from pulp_rust.app.views import ( - IndexRoot, - CargoIndexApiViewSet, CargoDownloadApiView, + CargoIndexApiViewSet, CargoMeApiView, CargoPublishApiView, + IndexRoot, ) if settings.DOMAIN_ENABLED: diff --git a/pulp_rust/app/utils.py b/pulp_rust/app/utils.py index dcd6921..70a4fc5 100644 --- a/pulp_rust/app/utils.py +++ b/pulp_rust/app/utils.py @@ -136,7 +136,7 @@ def validate_crate_version(version): if not version: return "crate version must not be empty" if not SEMVER_RE.match(version): - return f"invalid semver: `{version}` " "(expected MAJOR.MINOR.PATCH[-prerelease][+build])" + return f"invalid semver: `{version}` (expected MAJOR.MINOR.PATCH[-prerelease][+build])" return None diff --git a/pulp_rust/app/views.py b/pulp_rust/app/views.py index 3bf458e..af581cb 100644 --- a/pulp_rust/app/views.py +++ b/pulp_rust/app/views.py @@ -3,50 +3,49 @@ import os import struct import tempfile -import urllib.request import urllib.error +import urllib.request +from urllib.parse import urljoin -from rest_framework.renderers import BaseRenderer, JSONRenderer -from rest_framework.views import APIView -from rest_framework.viewsets import ViewSet -from rest_framework.exceptions import Throttled from django.core.exceptions import ObjectDoesNotExist -from django.shortcuts import redirect, get_object_or_404 - from django.http.response import ( Http404, - HttpResponseNotFound, HttpResponse, + HttpResponseNotFound, ) +from django.shortcuts import get_object_or_404, redirect from drf_spectacular.utils import extend_schema from dynaconf import settings -from urllib.parse import urljoin +from rest_framework.exceptions import Throttled +from rest_framework.renderers import BaseRenderer, JSONRenderer +from rest_framework.views import APIView +from rest_framework.viewsets import ViewSet -from pulpcore.plugin.util import get_domain from pulpcore.plugin.tasking import dispatch +from pulpcore.plugin.util import get_domain +from pulp_rust.app.auth import require_cargo_token from pulp_rust.app.models import ( - RustDistribution, RustContent, + RustDistribution, RustPackageYank, _strip_sparse_prefix, ) -from pulp_rust.app.auth import require_cargo_token -from pulp_rust.app.utils import ( - validate_crate_name, - validate_crate_version, - canonicalize_crate_name, - strip_semver_build_metadata, +from pulp_rust.app.serializers import ( + IndexRootSerializer, + RustContentSerializer, ) from pulp_rust.app.tasks import ( - ayank_package, - aunyank_package, apublish_package, + aunyank_package, + ayank_package, parse_cargo_publish_body, ) -from pulp_rust.app.serializers import ( - IndexRootSerializer, - RustContentSerializer, +from pulp_rust.app.utils import ( + canonicalize_crate_name, + strip_semver_build_metadata, + validate_crate_name, + validate_crate_version, ) log = logging.getLogger(__name__) @@ -195,7 +194,7 @@ def retrieve(self, request, path, **kwargs): ) except (urllib.error.URLError, TimeoutError) as e: log.warning( - "Upstream index request failed for %s: %s, " "falling back to cached content", + "Upstream index request failed for %s: %s, falling back to cached content", upstream_url, e, ) diff --git a/pulp_rust/app/viewsets.py b/pulp_rust/app/viewsets.py index a091e8d..3499a2d 100755 --- a/pulp_rust/app/viewsets.py +++ b/pulp_rust/app/viewsets.py @@ -5,15 +5,15 @@ from rest_framework.decorators import action from rest_framework.response import Response -from pulpcore.plugin.viewsets import RemoteFilter from pulpcore.plugin import viewsets as core from pulpcore.plugin.actions import ModifyRepositoryActionMixin +from pulpcore.plugin.models import ContentArtifact from pulpcore.plugin.serializers import ( AsyncOperationResponseSerializer, RepositorySyncURLSerializer, ) from pulpcore.plugin.tasking import dispatch -from pulpcore.plugin.models import ContentArtifact +from pulpcore.plugin.viewsets import RemoteFilter from . import models, serializers, tasks diff --git a/pulp_rust/tests/functional/api/test_cargo_api.py b/pulp_rust/tests/functional/api/test_cargo_api.py index 35c1b50..1a2aea8 100644 --- a/pulp_rust/tests/functional/api/test_cargo_api.py +++ b/pulp_rust/tests/functional/api/test_cargo_api.py @@ -6,6 +6,7 @@ import pytest from aiohttp.client_exceptions import ClientResponseError + from pulpcore.client.pulp_rust.exceptions import ApiException from pulp_rust.tests.functional.utils import CRATES_IO_URL, download_file diff --git a/pulp_rust/tests/functional/api/test_publish.py b/pulp_rust/tests/functional/api/test_publish.py index 8060b84..f054ef1 100644 --- a/pulp_rust/tests/functional/api/test_publish.py +++ b/pulp_rust/tests/functional/api/test_publish.py @@ -402,6 +402,6 @@ def test_cargo_publish_cross_repo_reuses_pull_through_content( ) assert pub_content.count == 1, "Content not found in private registry" - assert ( - pt_content.results[0].pulp_href == pub_content.results[0].pulp_href - ), "Pull-through and publish created separate content objects — expected reuse" + assert pt_content.results[0].pulp_href == pub_content.results[0].pulp_href, ( + "Pull-through and publish created separate content objects — expected reuse" + ) diff --git a/pulp_rust/tests/functional/api/test_upload.py b/pulp_rust/tests/functional/api/test_upload.py index 8524003..bab3607 100644 --- a/pulp_rust/tests/functional/api/test_upload.py +++ b/pulp_rust/tests/functional/api/test_upload.py @@ -1,13 +1,13 @@ """Tests for uploading crate content via the Pulp REST API and verifying index fidelity.""" -from pulpcore.client.pulp_rust import RustRustContent, RustDependency +from pulpcore.client.pulp_rust import RustDependency, RustRustContent +from pulp_rust.app.utils import extract_cargo_toml, extract_dependencies from pulp_rust.tests.functional.utils import ( assert_index_entry_matches_upstream, download_crate_from_upstream, get_index_entry, ) -from pulp_rust.app.utils import extract_cargo_toml, extract_dependencies def test_upload_and_index_fidelity( diff --git a/pulp_rust/tests/functional/utils.py b/pulp_rust/tests/functional/utils.py index 7fb8fc9..8177b2b 100644 --- a/pulp_rust/tests/functional/utils.py +++ b/pulp_rust/tests/functional/utils.py @@ -1,12 +1,12 @@ +import asyncio import hashlib import json import struct import tempfile +from dataclasses import dataclass import aiohttp -import asyncio import requests -from dataclasses import dataclass from pulp_rust.app.auth import STUB_TOKEN from pulp_rust.app.utils import extract_cargo_toml, extract_dependencies @@ -220,9 +220,9 @@ def sort_key(d): pulp_deps = sorted(pulp_entry["deps"], key=sort_key) upstream_deps = sorted(upstream_entry["deps"], key=sort_key) - assert ( - pulp_deps == upstream_deps - ), f"deps mismatch:\n pulp={pulp_deps}\n upstream={upstream_deps}" + assert pulp_deps == upstream_deps, ( + f"deps mismatch:\n pulp={pulp_deps}\n upstream={upstream_deps}" + ) else: assert pulp_entry.get(field) == upstream_entry.get(field), ( f"{field} mismatch: pulp={pulp_entry.get(field)!r} " diff --git a/pulp_rust/tests/unit/test_models.py b/pulp_rust/tests/unit/test_models.py index 4549015..b6bebd3 100644 --- a/pulp_rust/tests/unit/test_models.py +++ b/pulp_rust/tests/unit/test_models.py @@ -5,9 +5,9 @@ django.setup() from pulp_rust.app.models import ( # noqa: E402 - _strip_sparse_prefix, - _parse_crate_relative_path, RustRemote, + _parse_crate_relative_path, + _strip_sparse_prefix, ) diff --git a/pulp_rust/tests/unit/test_utils.py b/pulp_rust/tests/unit/test_utils.py index 0589961..086fbee 100644 --- a/pulp_rust/tests/unit/test_utils.py +++ b/pulp_rust/tests/unit/test_utils.py @@ -10,13 +10,13 @@ django.setup() from pulp_rust.app.utils import ( # noqa: E402 + canonicalize_crate_name, extract_cargo_toml, extract_dependencies, parse_dep, + strip_semver_build_metadata, validate_crate_name, validate_crate_version, - canonicalize_crate_name, - strip_semver_build_metadata, ) @@ -214,7 +214,7 @@ def test_basic_extraction(self): def test_with_dependencies(self): toml_content = ( - b'[package]\nname = "bar"\nversion = "0.1.0"\n' b'\n[dependencies]\nserde = "1.0"\n' + b'[package]\nname = "bar"\nversion = "0.1.0"\n\n[dependencies]\nserde = "1.0"\n' ) path = _make_crate_tarball("bar", "0.1.0", toml_content) with open(path, "rb") as f: diff --git a/pyproject.toml b/pyproject.toml index 6285d99..1a175c3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -168,3 +168,30 @@ replace = "version = \"{new_version}\"" filename = "./pyproject.toml" search = "version = \"{current_version}\"" replace = "version = \"{new_version}\"" + + +[tool.ruff] +# This section is managed by the plugin template. Do not edit manually. +line-length = 100 +extend-exclude = [ + "docs/**", + "**/migrations/*.py", +] + +[tool.ruff.lint] +# This section is managed by the plugin template. Do not edit manually. +extend-select = [ + "I", + "INT", + "TID", + "T10", +] + +[tool.ruff.lint.flake8-tidy-imports.banned-api] +# This section is managed by the plugin template. Do not edit manually. +"pulpcore.app".msg = "The 'pulpcore' apis must only be consumed via 'pulpcore.plugin'." + +[tool.ruff.lint.isort] +# This section is managed by the plugin template. Do not edit manually. +sections = { second-party = ["pulpcore"] } +section-order = ["future", "standard-library", "third-party", "second-party", "first-party", "local-folder"] diff --git a/template_config.yml b/template_config.yml index d9bcb4e..00eae4e 100644 --- a/template_config.yml +++ b/template_config.yml @@ -6,9 +6,7 @@ # After editing this file please always reapply the plugin template before committing any changes. --- -black: true check_commit_message: true -check_gettext: true check_manifest: true check_stray_pulpcore_imports: true ci_base_image: "ghcr.io/pulp/pulp-ci-centos9" @@ -23,10 +21,9 @@ deploy_to_pypi: true disabled_redis_runners: [] docker_fixtures: false extra_files: [] -flake8: true -flake8_ignore: [] github_org: "pulp" latest_release_branch: "0.0" +lint_ignore: [] lint_requirements: true os_required_packages: [] parallel_test_workers: 8 @@ -88,7 +85,6 @@ pulp_settings_s3: BACKEND: "django.contrib.staticfiles.storage.StaticFilesStorage" api_root: "/rerouted/djnd/" domain_enabled: true -pydocstyle: true release_email: "pulp-infra@redhat.com" release_user: "pulpbot" stalebot: true