From 50824b9ebab667db0077cc894ee8dac459b7fbc1 Mon Sep 17 00:00:00 2001 From: pulpbot Date: Sun, 21 Jun 2026 20:55:49 +0000 Subject: [PATCH] Update cookiecutter --- .ci/gen_certs.py | 24 +++-- .ci/scripts/calc_constraints.py | 119 ------------------------- .ci/scripts/collect_changes.py | 16 ++-- .ci/scripts/pr_labels.py | 2 +- .ci/scripts/validate_commit_message.py | 19 ++-- .github/workflows/build.yml | 21 ++--- .github/workflows/codeql.yml | 2 +- .github/workflows/collect_changes.yml | 17 ++-- .github/workflows/cookiecutter.yml | 16 ++-- .github/workflows/lint.yml | 22 ++--- .github/workflows/pr.yml | 25 +++--- .github/workflows/pr_checks.yml | 20 +++-- .github/workflows/publish.yml | 24 +++-- .github/workflows/release.yml | 13 +-- .github/workflows/release_branch.yml | 12 +-- .github/workflows/test.yml | 38 ++++---- .gitignore | 7 +- Makefile | 65 +++++++++++--- lint_requirements.txt | 14 --- pulp-glue-maven/pyproject.toml | 2 +- pyproject.toml | 47 +++++++++- test_requirements.txt | 7 -- 22 files changed, 235 insertions(+), 297 deletions(-) delete mode 100755 .ci/scripts/calc_constraints.py delete mode 100644 lint_requirements.txt delete mode 100644 test_requirements.txt diff --git a/.ci/gen_certs.py b/.ci/gen_certs.py index d55b0b9..e6eed98 100644 --- a/.ci/gen_certs.py +++ b/.ci/gen_certs.py @@ -6,8 +6,8 @@ # /// import argparse -import os import sys +from pathlib import Path import trustme @@ -17,14 +17,14 @@ def main() -> None: parser.add_argument( "-d", "--dir", - default=os.getcwd(), + default=".", help="Directory where certificates and keys are written to. Defaults to cwd.", ) args = parser.parse_args(sys.argv[1:]) - cert_dir = args.dir + cert_dir = Path(args.dir) - if not os.path.isdir(cert_dir): + if not cert_dir.is_dir(): raise ValueError(f"--dir={cert_dir} is not a directory") key_type = trustme.KeyType["ECDSA"] @@ -32,28 +32,26 @@ def main() -> None: # Generate the CA certificate ca = trustme.CA(key_type=key_type) # Write the certificate the client should trust - ca_cert_path = os.path.join(cert_dir, "ca.pem") + ca_cert_path = cert_dir / "ca.pem" ca.cert_pem.write_to_path(path=ca_cert_path) # Generate the server certificate server_cert = ca.issue_cert("localhost", "127.0.0.1", "::1", key_type=key_type) # Write the certificate and private key the server should use - server_key_path = os.path.join(cert_dir, "server.key") - server_cert_path = os.path.join(cert_dir, "server.pem") + server_key_path = cert_dir / "server.key" + server_cert_path = cert_dir / "server.pem" server_cert.private_key_pem.write_to_path(path=server_key_path) - with open(server_cert_path, mode="w") as f: - f.truncate() + server_cert_path.write_text("") for blob in server_cert.cert_chain_pems: blob.write_to_path(path=server_cert_path, append=True) # Generate the client certificate client_cert = ca.issue_cert("admin@example.com", common_name="admin", key_type=key_type) # Write the certificate and private key the client should use - client_key_path = os.path.join(cert_dir, "client.key") - client_cert_path = os.path.join(cert_dir, "client.pem") + client_key_path = cert_dir / "client.key" + client_cert_path = cert_dir / "client.pem" client_cert.private_key_pem.write_to_path(path=client_key_path) - with open(client_cert_path, mode="w") as f: - f.truncate() + client_cert_path.write_text("") for blob in client_cert.cert_chain_pems: blob.write_to_path(path=client_cert_path, append=True) diff --git a/.ci/scripts/calc_constraints.py b/.ci/scripts/calc_constraints.py deleted file mode 100755 index ca8e11e..0000000 --- a/.ci/scripts/calc_constraints.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/python3 -# /// script -# requires-python = ">=3.10" -# dependencies = [ -# "packaging>=25.0,<25.1", -# "tomli>=2.3.0,<2.4.0;python_version<'3.11'", -# ] -# /// - -import argparse -import fileinput -import sys - -from packaging.requirements import Requirement -from packaging.version import Version - -try: - import tomllib -except ImportError: - import tomli as tomllib - - -def split_comment(line): - split_line = line.split("#", maxsplit=1) - try: - comment = " # " + split_line[1].strip() - except IndexError: - comment = "" - return split_line[0].strip(), comment - - -def to_upper_bound(req): - try: - requirement = Requirement(req) - except ValueError: - return f"# UNPARSABLE: {req}" - else: - for spec in requirement.specifier: - if spec.operator == "~=": - return f"# NO BETTER CONSTRAINT: {req}" - if spec.operator == "<=": - operator = "==" - max_version = spec.version - return f"{requirement.name}{operator}{max_version}" - if spec.operator == "<": - operator = "~=" - version = Version(spec.version) - if version.micro != 0: - max_version = f"{version.major}.{version.minor}.{version.micro - 1}" - elif version.minor != 0: - max_version = f"{version.major}.{version.minor - 1}" - elif version.major != 0: - max_version = f"{version.major - 1}.0" - else: - return f"# NO BETTER CONSTRAINT: {req}" - return f"{requirement.name}{operator}{max_version}" - return f"# NO UPPER BOUND: {req}" - - -def to_lower_bound(req): - try: - requirement = Requirement(req) - except ValueError: - return f"# UNPARSABLE: {req}" - else: - for spec in requirement.specifier: - if spec.operator == ">=": - if requirement.name == "pulpcore": - # Currently an exception to allow for pulpcore bugfix releases. - # TODO Semver libraries should be allowed too. - operator = "~=" - else: - operator = "==" - min_version = spec.version - return f"{requirement.name}{operator}{min_version}" - return f"# NO LOWER BOUND: {req}" - - -def main(): - """Calculate constraints for the lower bound of dependencies where possible.""" - parser = argparse.ArgumentParser( - prog=sys.argv[0], - description="Calculate constraints for the lower or upper bound of dependencies where " - "possible.", - ) - parser.add_argument("-u", "--upper", action="store_true") - parser.add_argument("filename", nargs="*") - args = parser.parse_args() - - modifier = to_upper_bound if args.upper else to_lower_bound - - req_files = [filename for filename in args.filename if not filename.endswith("pyproject.toml")] - pyp_files = [filename for filename in args.filename if filename.endswith("pyproject.toml")] - if req_files: - with fileinput.input(files=req_files) as req_file: - for line in req_file: - if line.strip().startswith("#"): - # Shortcut comment only lines - print(line.strip()) - else: - req, comment = split_comment(line) - new_req = modifier(req) - print(new_req + comment) - for filename in pyp_files: - with open(filename, "rb") as fp: - pyproject = tomllib.load(fp) - for req in pyproject["project"]["dependencies"]: - new_req = modifier(req) - print(new_req) - optional_dependencies = pyproject["project"].get("optional-dependencies") - if optional_dependencies: - for opt in optional_dependencies.values(): - for req in opt: - new_req = modifier(req) - print(new_req) - - -if __name__ == "__main__": - main() diff --git a/.ci/scripts/collect_changes.py b/.ci/scripts/collect_changes.py index 499265c..80d7477 100755 --- a/.ci/scripts/collect_changes.py +++ b/.ci/scripts/collect_changes.py @@ -1,6 +1,6 @@ #!/bin/env python3 # /// script -# requires-python = ">=3.11" +# requires-python = ">=3.13" # dependencies = [ # "gitpython>=3.1.46,<3.2.0", # "packaging>=25.0,<25.1", @@ -8,15 +8,15 @@ # /// import itertools -import os import re +from pathlib import Path import tomllib from git import GitCommandError, Repo from packaging.version import parse as parse_version # Read Towncrier settings -with open("pyproject.toml", "rb") as fp: +with Path("pyproject.toml").open("rb") as fp: tc_settings = tomllib.load(fp)["tool"]["towncrier"] CHANGELOG_FILE = tc_settings.get("filename", "NEWS.rst") @@ -74,14 +74,13 @@ def split_changelog(changelog): def main(): - repo = Repo(os.getcwd()) + repo = Repo(Path.cwd()) remote = repo.remotes[0] branches = [ref for ref in remote.refs if re.match(r"^([0-9]+)\.([0-9]+)$", ref.remote_head)] branches.sort(key=lambda ref: parse_version(ref.remote_head), reverse=True) branches = [ref.name for ref in branches] - with open(CHANGELOG_FILE, "r") as f: - main_changelog = f.read() + main_changelog = Path(CHANGELOG_FILE).read_text() preamble, main_changes = split_changelog(main_changelog) old_length = len(main_changes) @@ -103,10 +102,9 @@ def main(): new_length = len(main_changes) if old_length < new_length: print(f"{new_length - old_length} new versions have been added.") - with open(CHANGELOG_FILE, "w") as fp: + with Path(CHANGELOG_FILE).open("w") as fp: fp.write(preamble) - for change in main_changes: - fp.write(change[1]) + fp.writelines(change[1] for change in main_changes) repo.git.commit("-m", "Update Changelog", CHANGELOG_FILE) diff --git a/.ci/scripts/pr_labels.py b/.ci/scripts/pr_labels.py index 49eb4ad..b2350b6 100755 --- a/.ci/scripts/pr_labels.py +++ b/.ci/scripts/pr_labels.py @@ -19,7 +19,7 @@ def main(): assert len(sys.argv) == 3 - with open("pyproject.toml", "rb") as fp: + with Path("pyproject.toml").open("rb") as fp: PYPROJECT_TOML = tomllib.load(fp) BLOCKING_REGEX = re.compile(r"DRAFT|WIP|NO\s*MERGE|DO\s*NOT\s*MERGE|EXPERIMENT") ISSUE_REGEX = re.compile(r"(?:fixes|closes)[\s:]+#(\d+)") diff --git a/.ci/scripts/validate_commit_message.py b/.ci/scripts/validate_commit_message.py index 8c258f7..839f7c8 100644 --- a/.ci/scripts/validate_commit_message.py +++ b/.ci/scripts/validate_commit_message.py @@ -12,9 +12,8 @@ from pathlib import Path import tomllib -from github import Github -with open("pyproject.toml", "rb") as fp: +with Path("pyproject.toml").open("rb") as fp: PYPROJECT_TOML = tomllib.load(fp) KEYWORDS = ["fixes", "closes"] BLOCKING_REGEX = [ @@ -33,14 +32,16 @@ if NOISSUE_MARKER in message: sys.exit("Do not add '[noissue]' in the commit message.") -if any((re.match(pattern, message) for pattern in BLOCKING_REGEX)): +if any(re.match(pattern, message) for pattern in BLOCKING_REGEX): sys.exit("This PR is not ready for consumption.") -g = Github(os.environ.get("GITHUB_TOKEN")) -repo = g.get_repo("pulp/pulp-cli-maven") +def check_status(issue: str) -> None: + from github import Github + + g = Github(os.environ.get("GITHUB_TOKEN")) + repo = g.get_repo("pulp/pulp-cli-maven") -def check_status(issue): gi = repo.get_issue(int(issue)) if gi.pull_request: sys.exit(f"Error: issue #{issue} is a pull request.") @@ -48,7 +49,7 @@ def check_status(issue): sys.exit(f"Error: issue #{issue} is closed.") -def check_changelog(issue): +def check_changelog(issue: str) -> None: matches = list(Path("CHANGES").rglob(f"{issue}.*")) if len(matches) < 1: @@ -58,7 +59,7 @@ def check_changelog(issue): sys.exit(f"Invalid extension for changelog entry '{match}'.") -print("Checking commit message for {sha}.".format(sha=sha[0:7])) +print(f"Checking commit message for {sha[0:7]}.") # validate the issue attached to the commit issue_regex = r"(?:{keywords})[\s:]+#(\d+)".format(keywords=("|").join(KEYWORDS)) @@ -72,4 +73,4 @@ def check_changelog(issue): check_status(issue) check_changelog(issue) -print("Commit message for {sha} passed.".format(sha=sha[0:7])) +print(f"Commit message for {sha[0:7]} passed.") diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a66f2b3..d7c6a4b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,30 +8,27 @@ jobs: build: runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" - - uses: "actions/cache@v5" - with: - path: "~/.cache/pip" - key: "${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/*constraints.lock', '**/setup.py', '**/pyproject.toml') }}" - restore-keys: | - ${{ runner.os }}-pip- - + - name: "Checkout" + uses: "actions/checkout@v6" - name: "Set up Python" uses: "actions/setup-python@v6" with: python-version: "3.14" - - name: "Install python dependencies" - run: | - pip install build setuptools wheel + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Build wheels" run: | make build + touch .root - name: "Upload wheels" uses: "actions/upload-artifact@v6" with: name: "pulp_cli_packages" path: | - pulp-glue-maven/dist/ + .root dist/ if-no-files-found: "error" retention-days: 5 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 3c8da25..facb1a8 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -17,7 +17,7 @@ jobs: security-events: "write" steps: - - name: "Checkout repository" + - name: "Checkout" uses: "actions/checkout@v6" - name: "Initialize CodeQL" uses: "github/codeql-action/init@v4" diff --git a/.github/workflows/collect_changes.yml b/.github/workflows/collect_changes.yml index f5ead77..5e08242 100644 --- a/.github/workflows/collect_changes.yml +++ b/.github/workflows/collect_changes.yml @@ -8,21 +8,26 @@ jobs: collect-changes: runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" with: - ref: "main" fetch-depth: 0 - - uses: "actions/setup-python@v6" + - name: "Set up Python" + uses: "actions/setup-python@v6" with: - python-version: "3.x" + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Setup git" run: | git config user.name pulpbot git config user.email pulp-infra@redhat.com - name: "Collect changes" run: | - pip install GitPython packaging - python3 .ci/scripts/collect_changes.py + uv run --script .ci/scripts/collect_changes.py - name: "Create Pull Request" uses: "peter-evans/create-pull-request@v8" id: "create_pr" diff --git a/.github/workflows/cookiecutter.yml b/.github/workflows/cookiecutter.yml index 981e67b..1d85efe 100644 --- a/.github/workflows/cookiecutter.yml +++ b/.github/workflows/cookiecutter.yml @@ -21,10 +21,6 @@ jobs: with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp-cli-maven" - - name: "Setup git" - run: | - git config user.name pulpbot - git config user.email pulp-infra@redhat.com - name: "Set up Python" uses: "actions/setup-python@v6" with: @@ -34,6 +30,10 @@ jobs: uses: "astral-sh/setup-uv@v7" with: enable-cache: true + - name: "Setup git" + run: | + git config user.name pulpbot + git config user.email pulp-infra@redhat.com - name: "Apply cookiecutter templates" run: | uv run ../pulp-cli/cookiecutter/apply_templates.py @@ -70,10 +70,6 @@ jobs: with: token: "${{ secrets.RELEASE_TOKEN }}" path: "pulp-cli-maven" - - name: "Setup git" - run: | - git config user.name pulpbot - git config user.email pulp-infra@redhat.com - name: "Set up Python" uses: "actions/setup-python@v6" with: @@ -83,6 +79,10 @@ jobs: uses: "astral-sh/setup-uv@v7" with: enable-cache: true + - name: "Setup git" + run: | + git config user.name pulpbot + git config user.email pulp-infra@redhat.com - name: "Apply cookiecutter templates" run: | uv run ../pulp-cli/cookiecutter/update_pulp_cli.py diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 40467b5..fee95cd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -14,25 +14,17 @@ jobs: - "3.11" - "3.14" steps: - - uses: "actions/checkout@v6" - - uses: "actions/cache@v5" - with: - path: "~/.cache/pip" - key: "${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/*constraints.lock', '**/setup.py', '**/pyproject.toml') }}" - restore-keys: | - ${{ runner.os }}-pip- - - - name: "Download wheels" - uses: "actions/download-artifact@v8" - with: - name: "pulp_cli_packages" + - name: "Checkout" + uses: "actions/checkout@v6" - name: "Set up Python" uses: "actions/setup-python@v6" with: python-version: "${{ matrix.python }}" - - name: "Install python dependencies" - run: | - pip install dist/pulp_cli_maven-*.whl pulp-glue-maven/dist/pulp_glue_maven-*.whl -r lint_requirements.txt + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Lint code" run: | make lint diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index e201323..5617875 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -9,15 +9,15 @@ concurrency: cancel-in-progress: true jobs: - build: - uses: "./.github/workflows/build.yml" lint: - needs: - - "build" uses: "./.github/workflows/lint.yml" - test: + build: needs: - "lint" + uses: "./.github/workflows/build.yml" + test: + needs: + - "build" uses: "./.github/workflows/test.yml" codeql: needs: @@ -26,16 +26,19 @@ jobs: check-commits: runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" with: fetch-depth: 0 - name: "Set up Python" uses: "actions/setup-python@v6" with: - python-version: "3.x" - - name: "Install python dependencies" - run: | - pip install toml pygithub + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Check commit message" env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" @@ -43,7 +46,7 @@ jobs: run: | for SHA in $(curl -H "Authorization: token $GITHUB_TOKEN" "$GITHUB_CONTEXT" | jq -r '.[].sha') do - python .ci/scripts/validate_commit_message.py "$SHA" + uv run -q .ci/scripts/validate_commit_message.py "$SHA" VALUE=$? if [ "$VALUE" -gt 0 ]; then exit "$VALUE" diff --git a/.github/workflows/pr_checks.yml b/.github/workflows/pr_checks.yml index 43f5c94..c031756 100644 --- a/.github/workflows/pr_checks.yml +++ b/.github/workflows/pr_checks.yml @@ -19,19 +19,25 @@ jobs: permissions: pull-requests: "write" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" with: fetch-depth: 0 - - uses: "actions/setup-python@v6" + - name: "Set up Python" + uses: "actions/setup-python@v6" with: - python-version: "3.x" + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Determine PR labels" run: | - pip install GitPython==3.1.42 git fetch origin ${{ github.event.pull_request.head.sha }} - python .ci/scripts/pr_labels.py "origin/${{ github.base_ref }}" "${{ github.event.pull_request.head.sha }}" >> "$GITHUB_ENV" - - uses: "actions/github-script@v8" - name: "Apply PR Labels" + uv run -q .ci/scripts/pr_labels.py "origin/${{ github.base_ref }}" "${{ github.event.pull_request.head.sha }}" >> "$GITHUB_ENV" + - name: "Apply PR Labels" + uses: "actions/github-script@v8" with: script: | const { ADD_LABELS, REMOVE_LABELS } = process.env; diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a5a5653..9256150 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -14,7 +14,8 @@ jobs: needs: "build" runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6" + - name: "Checkout" + uses: "actions/checkout@v6" - name: "Download wheels" uses: "actions/download-artifact@v8" with: @@ -22,18 +23,15 @@ jobs: - name: "Set up Python" uses: "actions/setup-python@v6" with: - python-version: "3.x" - - name: "Install dependencies" - run: | - python -m pip install --upgrade pip - pip install twine - - name: "Build and publish" + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true + - name: "Publish" env: - TWINE_USERNAME: "__token__" - TWINE_PASSWORD: "${{ secrets.PYPI_API_TOKEN }}" + UV_PUBLISH_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" run: | - cd pulp-glue-maven - twine upload dist/* - cd .. - twine upload dist/* + uv publish ... diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4cbd745..bda5708 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -15,16 +15,17 @@ jobs: - name: "Set up Python" uses: "actions/setup-python@v6" with: - python-version: "3.x" - - name: "Install dependencies" - run: | - python -m pip install --upgrade pip - pip install bump-my-version~=0.20.0 towncrier~=23.11.0 + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Setup git" run: | git config user.name pulpbot git config user.email pulp-infra@redhat.com - name: "Release" run: | - .ci/scripts/release.sh + uv run --with bump-my-version~=0.20.0 --with towncrier~=23.11.0 .ci/scripts/release.sh ... diff --git a/.github/workflows/release_branch.yml b/.github/workflows/release_branch.yml index a75f0f3..f20a5ef 100644 --- a/.github/workflows/release_branch.yml +++ b/.github/workflows/release_branch.yml @@ -13,17 +13,19 @@ jobs: - name: "Set up Python" uses: "actions/setup-python@v6" with: - python-version: "3.x" + python-version: "3.14" + allow-prereleases: true + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Setup git" run: | git config user.name pulpbot git config user.email pulp-infra@redhat.com - - name: "Install python dependencies" - run: | - pip install bump-my-version~=0.20.0 - name: "Create Release Branch" run: | - .ci/scripts/create_release_branch.sh + uv run --with bump-my-version~=0.20.0 .ci/scripts/create_release_branch.sh - name: "Create Pull Request" uses: "peter-evans/create-pull-request@v8" id: "create_pr" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3038af1..d7195f9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,14 +26,8 @@ jobs: lower_bounds: true python: "3.12" steps: - - uses: "actions/checkout@v6" - - uses: "actions/cache@v5" - with: - path: "~/.cache/pip" - key: "${{ runner.os }}-pip-${{ hashFiles('**/*requirements.txt', '**/*constraints.lock', '**/setup.py', '**/pyproject.toml') }}" - restore-keys: | - ${{ runner.os }}-pip- - + - name: "Checkout" + uses: "actions/checkout@v6" - name: "Download wheels" uses: "actions/download-artifact@v8" with: @@ -43,18 +37,10 @@ jobs: with: python-version: "${{ matrix.python }}" allow-prereleases: true - - name: "Install Python Test Dependencies" - run: | - if [ "${{matrix.lower_bounds}}" ] - then - pip install dist/pulp_cli_maven-*.whl pulp-glue-maven/dist/pulp_glue_maven-*.whl -r test_requirements.txt -c lower_bounds_constraints.lock - elif [ "${{matrix.upper_bounds}}" ] - then - .ci/scripts/calc_constraints.py pyproject.toml pulp-glue-maven/pyproject.toml --upper > upper_bounds_constraints.lock - pip install dist/pulp_cli_maven-*.whl pulp-glue-maven/dist/pulp_glue_maven-*.whl -r test_requirements.txt -c upper_bounds_constraints.lock - else - pip install dist/pulp_cli_maven-*.whl pulp-glue-maven/dist/pulp_glue_maven-*.whl -r test_requirements.txt - fi + - name: "Install uv" + uses: "astral-sh/setup-uv@v7" + with: + enable-cache: true - name: "Run tests" env: CONTAINER_RUNTIME: "${{ matrix.container_runtime }}" @@ -68,5 +54,15 @@ jobs: PULP_ENABLED_PLUGINS: "${{ matrix.pulp_enabled_plugins }}" OAS_VERSION: "${{ matrix.oas_version }}" run: | - .ci/run_container.sh make test + if [ "${{matrix.lower_bounds}}" ] + then + RESOLUTION=("--resolution" "lowest-direct") + elif [ "${{matrix.upper_bounds}}" ] + then + RESOLUTION=("--resolution" "highest") + else + RESOLUTION=() + fi + + uv run "${RESOLUTION[@]}" --isolated --with dist/pulp_glue*.whl --with dist/pulp_cli*.whl --only-group test .ci/run_container.sh make _test ... diff --git a/.gitignore b/.gitignore index ed761f6..4e13d34 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,11 @@ *.egg-info __pycache__/ build/ -tests/cli.toml -GPG-PRIVATE-KEY-fixture-signing site/ dist/ *.po~ +uv.lock + +tests/cli.toml +GPG-PRIVATE-KEY-fixture-signing +.root diff --git a/Makefile b/Makefile index 676514e..22811fd 100644 --- a/Makefile +++ b/Makefile @@ -11,45 +11,82 @@ info: .PHONY: build build: - cd pulp-glue-maven; pyproject-build -n - pyproject-build -n + uv build --all + +.PHONY: _format +_format: + ruff format + ruff check --select I --fix .PHONY: format format: - ruff format + uv run --isolated --group lint $(MAKE) _format + +.PHONY: _autofix +_autofix: ruff check --fix -.PHONY: lint -lint: +.PHONY: autofix +autofix: + uv run --isolated --group lint $(MAKE) _autofix + +.PHONY: _lint +_lint: find tests .ci -name '*.sh' -print0 | xargs -0 shellcheck -x ruff format --check --diff - ruff check --diff + ruff check --output-format concise .ci/scripts/check_cli_dependencies.py .ci/scripts/check_click_for_mypy.py mypy cd pulp-glue-maven; mypy @echo "🙊 Code 🙈 LGTM 🙉 !" +.PHONY: lint +lint: + uv run --isolated --group lint $(MAKE) _lint + tests/cli.toml: cp $@.example $@ @echo "In order to configure the tests to talk to your test server, you might need to edit $@ ." +.PHONY: _test +_test: | tests/cli.toml + pytest -v tests pulp-glue-maven/tests + .PHONY: test -test: | tests/cli.toml - python3 -m pytest -v tests pulp-glue-maven/tests +test: + uv run $(MAKE) _test + +PYTEST_MARK ?= live + +.PHONY: _livetest +_livetest: | tests/cli.toml + pytest -v tests pulp-glue-maven/tests -m "$(PYTEST_MARK)" .PHONY: livetest -livetest: | tests/cli.toml - python3 -m pytest -v tests pulp-glue-maven/tests -m live +livetest: + uv run $(MAKE) _livetest + +.PHONY: _paralleltest +_paralleltest: | tests/cli.toml + pytest -v tests pulp-glue-maven/tests -m live -n 8 .PHONY: paralleltest -paralleltest: | tests/cli.toml - python3 -m pytest -v tests pulp-glue-maven/tests -m live -n 8 +paralleltest: + uv run $(MAKE) _paralleltest + +.PHONY: _unittest +_unittest: + pytest -v tests pulp-glue-maven/tests -m "not live" .PHONY: unittest unittest: - python3 -m pytest -v tests pulp-glue-maven/tests -m "not live" + uv run $(MAKE) _unittest + +.PHONY: _unittest_glue +_unittest_glue: + pytest -v pulp-glue-maven/tests -m "not live" .PHONY: unittest_glue unittest_glue: - python3 -m pytest -v pulp-glue-maven/tests -m "not live" + uv run $(MAKE) _unittest_glue diff --git a/lint_requirements.txt b/lint_requirements.txt deleted file mode 100644 index 4a5e7ce..0000000 --- a/lint_requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -# Lint requirements -ruff~=0.15.1 -mypy~=1.20.0 -shellcheck-py~=0.11.0.1 - -# Type annotation stubs -types-pygments -types-PyYAML -types-requests -types-setuptools -types-toml - -# Install the actual bits for mypy --r test_requirements.txt diff --git a/pulp-glue-maven/pyproject.toml b/pulp-glue-maven/pyproject.toml index 6c73fa1..93f2084 100644 --- a/pulp-glue-maven/pyproject.toml +++ b/pulp-glue-maven/pyproject.toml @@ -64,5 +64,5 @@ line-length = 100 [tool.ruff.lint] # This section is managed by the cookiecutter templates. -extend-select = ["I"] +extend-select = ["I", "INT", "PTH"] diff --git a/pyproject.toml b/pyproject.toml index f94cb59..ced9e63 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -122,7 +122,7 @@ markers = [ strict = true warn_unused_ignores = false show_error_codes = true -files = "src/**/*.py, tests/*.py" +files = "src/**/*.py, tests/**/*.py" mypy_path = ["src", "pulp-glue-maven/src"] namespace_packages = true explicit_package_bases = true @@ -190,14 +190,55 @@ replace = "\"pulp-glue-maven=={new_version}\"" [tool.ruff] # This section is managed by the cookiecutter templates. line-length = 100 -extend-exclude = ["cookiecutter"] [tool.ruff.lint] # This section is managed by the cookiecutter templates. -extend-select = ["I"] +extend-select = ["I", "INT", "PTH"] [tool.ruff.lint.isort] # This section is managed by the cookiecutter templates. sections = { second-party = ["pulp_glue"] } section-order = ["future", "standard-library", "third-party", "second-party", "first-party", "local-folder"] + + +[tool.uv.sources] +# This section is managed by the cookiecutter templates. +pulp-glue-maven = { workspace = true } + +[tool.uv.workspace] +# This section is managed by the cookiecutter templates. +members = ["pulp-glue-maven"] + +[tool.uv.build-backend] +# This section is managed by the cookiecutter templates. +module-name = ["pulpcore.cli"] +namespace = true +source-exclude = ["*.pot", "*.po", "**/*\\~"] + + +[dependency-groups] +dev = [ + {include-group = "lint"}, + "pylsp-mypy>=0.7.0", + "pylsp-rope>=0.1.17,<0.1.18", +] +lint = [ + {include-group = "test"}, + "mypy~=1.20.0", + "ruff~=0.15.1", + "shellcheck-py~=0.11.0.1", + "types-pygments", + "types-pyyaml", + "types-requests", + "types-setuptools", + "types-toml", +] +test = [ + "pygments>=2.19.2", + "pytest>=7.0.0,<9.2", + "pytest-xdist>=3.8.0,<3.9", + "python-gnupg>=0.5.0,<0.6", + "secretstorage>=3.5.0", + "trustme>=1.1.0,<1.3", +] diff --git a/test_requirements.txt b/test_requirements.txt deleted file mode 100644 index 5c7cacb..0000000 --- a/test_requirements.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Test requirements -pytest>=7.0.0,<=8.4.2 -pytest-subtests>=0.12.0,<=0.14.2 -python-gnupg==0.5.5 - -# No pinning here, because we only switch on optional dependencies here. -pygments