From 08a1d847c40312e86a907a39585d1c8e91ac8bf4 Mon Sep 17 00:00:00 2001 From: Siddhesh Mhadnak Date: Wed, 23 Oct 2024 01:46:22 +0530 Subject: [PATCH] refactor: migrate to PDM --- .github/dependabot.yaml | 27 +- .github/workflows/image-build-push.yaml | 22 +- .github/workflows/lint-test.yaml | 35 ++ .github/workflows/python-ci.yaml | 27 -- .markdownlint.yaml | 5 + .pre-commit-config.yaml | 102 +++++- .taplo.toml | 4 + .yamlfix.toml | 4 + .yamllint.yaml | 15 + Dockerfile | 16 +- README.md | 4 +- pdm.lock | 452 ++++++++++++++++++++++++ pyproject.toml | 95 +++-- requirements/requirements.in | 5 - requirements/requirements.txt | 44 --- 15 files changed, 711 insertions(+), 146 deletions(-) create mode 100644 .github/workflows/lint-test.yaml delete mode 100644 .github/workflows/python-ci.yaml create mode 100644 .markdownlint.yaml create mode 100644 .taplo.toml create mode 100644 .yamlfix.toml create mode 100644 .yamllint.yaml create mode 100644 pdm.lock delete mode 100644 requirements/requirements.in delete mode 100644 requirements/requirements.txt diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index c912694..fc62844 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -1,19 +1,30 @@ +--- version: 2 + updates: - - package-ecosystem: "github-actions" - directory: "/" + - package-ecosystem: github-actions + directory: / schedule: - interval: "monthly" + interval: monthly groups: ci-dependencies: patterns: - - "*" + - '*' - - package-ecosystem: "pip" - directory: "/" + - package-ecosystem: pip + directory: / schedule: - interval: "monthly" + interval: monthly groups: python-dependencies: patterns: - - "*" + - '*' + + - package-ecosystem: docker + directory: / + schedule: + interval: monthly + groups: + docker-dependencies: + patterns: + - '*' diff --git a/.github/workflows/image-build-push.yaml b/.github/workflows/image-build-push.yaml index ab2ebed..9b11f65 100644 --- a/.github/workflows/image-build-push.yaml +++ b/.github/workflows/image-build-push.yaml @@ -35,19 +35,19 @@ jobs: runs-on: ubuntu-24.04 steps: - - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 - name: Install cosign - uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 + uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da # v3.7.0 - name: Set up Docker Buildx id: buildx - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 with: platforms: ${{ matrix.platform }} - name: Log in to container registry (${{ env.REGISTRY }}) - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -55,7 +55,7 @@ jobs: - name: Extract Docker metadata id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | @@ -67,7 +67,7 @@ jobs: - name: Build and push Docker image id: docker_build_push - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 + uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6.9.0 with: builder: ${{ steps.buildx.outputs.name }} build-args: | @@ -98,7 +98,7 @@ jobs: - name: Upload digest if: ${{ github.ref == 'refs/heads/main' || startswith(github.event.ref, 'refs/tags/v') }} - uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 + uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3 with: if-no-files-found: error name: digests @@ -113,16 +113,16 @@ jobs: runs-on: ubuntu-24.04 steps: - name: Download digests - uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: name: digests path: /tmp/digests - name: Set up Docker Buildx - uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 + uses: docker/setup-buildx-action@c47758b77c9736f4b2ef4073d4d51994fabfe349 # v3.7.1 - name: Log in to container registry (${{ env.REGISTRY }}) - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ${{ env.REGISTRY }} username: ${{ github.actor }} @@ -130,7 +130,7 @@ jobs: - name: Extract Docker metadata id: docker_meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 + uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1 with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} tags: | diff --git a/.github/workflows/lint-test.yaml b/.github/workflows/lint-test.yaml new file mode 100644 index 0000000..c31a95c --- /dev/null +++ b/.github/workflows/lint-test.yaml @@ -0,0 +1,35 @@ +--- +name: Lint & Test + +on: + push: + branches: + - main + tags: + - v* + pull_request: + +defaults: + run: + shell: bash + +jobs: + lint_test: + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@eef61447b9ff4aafe5dcd4e0bbf5d482be7e7871 # v4.2.1 + + - name: Setup PDM + uses: pdm-project/setup-pdm@568ddd69406b30de1774ec0044b73ae06e716aa4 # v4.1 + with: + python-version: '3.11' + cache: true + + - name: Install dependencies + run: pdm install --no-self + + - name: Run pre-commit + run: pdm pre-commit + + - name: Run tests + run: pdm test diff --git a/.github/workflows/python-ci.yaml b/.github/workflows/python-ci.yaml deleted file mode 100644 index d0b503c..0000000 --- a/.github/workflows/python-ci.yaml +++ /dev/null @@ -1,27 +0,0 @@ -name: "Python CI" - -on: - push: - branches: - - main - pull_request: - -jobs: - pre-commit: - uses: darbiadev/.github/.github/workflows/generic-precommit.yaml@ea97d99e1520c46080c4c9032a69552e491474ac # v13.0.0 - - lint: - needs: pre-commit - uses: darbiadev/.github/.github/workflows/python-lint.yaml@ea97d99e1520c46080c4c9032a69552e491474ac # v13.0.0 - - test: - needs: lint - strategy: - matrix: - os: [ "ubuntu-latest" ] - python-version: [ "3.11" ] - - uses: darbiadev/.github/.github/workflows/python-test.yaml@ea97d99e1520c46080c4c9032a69552e491474ac # v13.0.0 - with: - os: ${{ matrix.os }} - python-version: ${{ matrix.python-version }} diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..83b6592 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,5 @@ +--- +MD013: + line_length: 120 + +MD024: false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6189179..f8f2e19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,18 +1,98 @@ +--- +default_language_version: + python: python3 + node: system + repos: + - repo: meta + hooks: + - id: check-hooks-apply + - id: check-useless-excludes + - repo: https://github.com/pre-commit/pre-commit-hooks rev: cef0300fd0fc4d2a87a85fa2093c6b283ea36f4b # frozen: v5.0.0 hooks: - - id: check-case-conflict + - id: check-added-large-files - id: check-merge-conflict - - id: check-toml - - id: check-yaml - - id: check-json - - id: trailing-whitespace - args: [ --markdown-linebreak-ext=md ] - - id: mixed-line-ending - args: [ --fix=lf ] - id: end-of-file-fixer - - repo: https://github.com/astral-sh/ruff-pre-commit - rev: "8983acb92ee4b01924893632cf90af926fa608f0" # frozen: v0.7.0 + - id: name-tests-test + args: + - --pytest-test-first + - id: trailing-whitespace + args: + - --markdown-linebreak-ext=md + exclude: \.gitignore + + - repo: local + hooks: + - id: ruff-format + name: Ruff (Format) + description: Format Python files + language: system + entry: pdm run format + types_or: + - python + - pyi + + - id: ruff-lint + name: Ruff (Lint) + description: Lint Python files + language: system + entry: pdm run lint + args: + - --exit-non-zero-on-fix + types_or: + - python + - pyi + + - id: pyright + name: Pyright + description: Type-check Python files + language: system + entry: pdm run type-check + types_or: + - python + - pyi + pass_filenames: false + + - repo: https://github.com/python-jsonschema/check-jsonschema + rev: 37cd56d9d154dfb0648eaee8efc1040512700c47 # frozen: 0.29.4 + hooks: + - id: check-github-workflows + + - repo: https://github.com/lyz-code/yamlfix + rev: 8072181c0f2eab9f2dd8db2eb3b9556d7cd0bd74 # frozen: 1.17.0 + hooks: + - id: yamlfix + args: + - --config-file + - .yamlfix.toml + + - repo: https://github.com/adrienverge/yamllint + rev: 81e9f98ffd059efe8aa9c1b1a42e5cce61b640c6 # frozen: v1.35.1 + hooks: + - id: yamllint + args: + - --strict + + - repo: https://github.com/igorshubovych/markdownlint-cli + rev: aa975a18c9a869648007d33864034dbc7481fe5e # frozen: v0.42.0 + hooks: + - id: markdownlint-fix + + - repo: https://github.com/ComPWA/taplo-pre-commit + rev: 23eab0f0eedcbedebff420f5fdfb284744adc7b3 # frozen: v0.9.3 + hooks: + - id: taplo-format + - id: taplo-lint + + - repo: https://github.com/sirwart/ripsecrets + rev: 033ec5192b738b6712701be920cba545c2775050 # frozen: v0.1.8 + hooks: + - id: ripsecrets + + - repo: https://github.com/crate-ci/typos + rev: 515e0fc2601a0905af8ad0800975c861be1074f1 # frozen: v1.26.0 hooks: - - id: ruff + - id: typos + args: [] diff --git a/.taplo.toml b/.taplo.toml new file mode 100644 index 0000000..508e9a2 --- /dev/null +++ b/.taplo.toml @@ -0,0 +1,4 @@ +[formatting] +column_width = 120 +compact_inline_tables = true +indent_tables = true diff --git a/.yamlfix.toml b/.yamlfix.toml new file mode 100644 index 0000000..b252c1a --- /dev/null +++ b/.yamlfix.toml @@ -0,0 +1,4 @@ +line_length = 120 +section_whitelines = 1 +sequence_style = 'block_style' +whitelines = 1 diff --git a/.yamllint.yaml b/.yamllint.yaml new file mode 100644 index 0000000..8eda018 --- /dev/null +++ b/.yamllint.yaml @@ -0,0 +1,15 @@ +--- +extends: default + +ignore-from-file: + - .git/info/exclude + - .gitignore + +rules: + line-length: + max: 120 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + + truthy: + check-keys: false diff --git a/Dockerfile b/Dockerfile index 13425f7..5b2a54b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,21 @@ -FROM python:3.12-slim@sha256:babc0d450bf9ed2b369814bc2f466e53a6ea43f1201f6df4e7988751f755c52c +FROM python:3.12-slim@sha256:032c52613401895aa3d418a4c563d2d05f993bc3ecc065c8f4e2280978acd249 # Define Git SHA build argument for Sentry ARG git_sha="development" ENV GIT_SHA=$git_sha -COPY requirements/requirements.txt . -RUN python -m pip install --requirement requirements.txt +WORKDIR /app + +RUN python -m pip install --no-cache-dir -U pip setuptools wheel +RUN python -m pip install --no-cache-dir pdm + +COPY pyproject.toml pdm.lock ./ +RUN pdm export --prod -o requirements.txt && python -m pip install --no-cache-dir -r requirements.txt -COPY pyproject.toml pyproject.toml COPY src/ src/ -RUN python -m pip install . +RUN python -m pip install --no-cache-dir . -RUN adduser --disabled-password loader +RUN useradd --no-create-home --shell=/bin/bash loader USER loader CMD [ "python", "-m", "loader" ] diff --git a/README.md b/README.md index 410d38d..1e9b975 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# dragonfly-loader +# Dragonfly Loader -Automated job for loading new releases into the Mainframe +An automated job to load new releases from the PyPI RSS feed into the [Dragonfly Mainframe](https://github.com/vipyrsec/dragonfly-mainframe). diff --git a/pdm.lock b/pdm.lock new file mode 100644 index 0000000..d854bfe --- /dev/null +++ b/pdm.lock @@ -0,0 +1,452 @@ +# This file is @generated by PDM. +# It is not intended for manual editing. + +[metadata] +groups = ["default", "dev", "test"] +strategy = ["inherit_metadata"] +lock_version = "4.5.0" +content_hash = "sha256:9d6072c4b4082ce6fba3083e3b16dcecfc8b8c88b174cc492c66bcbd613d1f02" + +[[metadata.targets]] +requires_python = ">=3.12,<3.13.dev0" + +[[package]] +name = "annotated-types" +version = "0.7.0" +requires_python = ">=3.8" +summary = "Reusable constraint types to use with typing.Annotated" +groups = ["default"] +dependencies = [ + "typing-extensions>=4.0.0; python_version < \"3.9\"", +] +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + +[[package]] +name = "anyio" +version = "4.6.2.post1" +requires_python = ">=3.9" +summary = "High level compatibility layer for multiple asynchronous event loop implementations" +groups = ["default"] +dependencies = [ + "exceptiongroup>=1.0.2; python_version < \"3.11\"", + "idna>=2.8", + "sniffio>=1.1", + "typing-extensions>=4.1; python_version < \"3.11\"", +] +files = [ + {file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"}, + {file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"}, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +requires_python = ">=3.6" +summary = "Python package for providing Mozilla's CA Bundle." +groups = ["default"] +files = [ + {file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"}, + {file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"}, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +requires_python = ">=3.8" +summary = "Validate configuration and produce human readable error messages." +groups = ["dev"] +files = [ + {file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"}, + {file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Cross-platform colored terminal text." +groups = ["test"] +marker = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "distlib" +version = "0.3.9" +summary = "Distribution utilities" +groups = ["dev"] +files = [ + {file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"}, + {file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"}, +] + +[[package]] +name = "filelock" +version = "3.16.1" +requires_python = ">=3.8" +summary = "A platform independent file lock." +groups = ["dev"] +files = [ + {file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"}, + {file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"}, +] + +[[package]] +name = "h11" +version = "0.14.0" +requires_python = ">=3.7" +summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.8\"", +] +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.6" +requires_python = ">=3.8" +summary = "A minimal low-level HTTP client." +groups = ["default"] +dependencies = [ + "certifi", + "h11<0.15,>=0.13", +] +files = [ + {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"}, + {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"}, +] + +[[package]] +name = "httpx" +version = "0.27.2" +requires_python = ">=3.8" +summary = "The next generation HTTP client." +groups = ["default"] +dependencies = [ + "anyio", + "certifi", + "httpcore==1.*", + "idna", + "sniffio", +] +files = [ + {file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"}, + {file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"}, +] + +[[package]] +name = "identify" +version = "2.6.1" +requires_python = ">=3.8" +summary = "File identification library for Python" +groups = ["dev"] +files = [ + {file = "identify-2.6.1-py2.py3-none-any.whl", hash = "sha256:53863bcac7caf8d2ed85bd20312ea5dcfc22226800f6d6881f232d861db5a8f0"}, + {file = "identify-2.6.1.tar.gz", hash = "sha256:91478c5fb7c3aac5ff7bf9b4344f803843dc586832d5f110d672b19aa1984c98"}, +] + +[[package]] +name = "idna" +version = "3.10" +requires_python = ">=3.6" +summary = "Internationalized Domain Names in Applications (IDNA)" +groups = ["default"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" +groups = ["test"] +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "letsbuilda-pypi" +version = "5.1.0" +requires_python = ">=3.11" +summary = "A wrapper for PyPI's API and RSS feed" +groups = ["default"] +dependencies = [ + "httpx", + "xmltodict", +] +files = [ + {file = "letsbuilda-pypi-5.1.0.tar.gz", hash = "sha256:e5d9f14803ea74d6112b33256aef6f829163c5b8407142f5e2250b5093b8ef5a"}, + {file = "letsbuilda_pypi-5.1.0-py3-none-any.whl", hash = "sha256:5a0dff883e0d2307a558b8bfe1ce70beb120d2c036fbeab03a5b860d0718a968"}, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +summary = "Node.js virtual environment builder" +groups = ["dev"] +files = [ + {file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"}, + {file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"}, +] + +[[package]] +name = "packaging" +version = "24.1" +requires_python = ">=3.8" +summary = "Core utilities for Python packages" +groups = ["test"] +files = [ + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +requires_python = ">=3.8" +summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." +groups = ["dev"] +files = [ + {file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"}, + {file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"}, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +requires_python = ">=3.8" +summary = "plugin and hook calling mechanisms for python" +groups = ["test"] +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[[package]] +name = "pre-commit" +version = "4.0.1" +requires_python = ">=3.9" +summary = "A framework for managing and maintaining multi-language pre-commit hooks." +groups = ["dev"] +dependencies = [ + "cfgv>=2.0.0", + "identify>=1.0.0", + "nodeenv>=0.11.1", + "pyyaml>=5.1", + "virtualenv>=20.10.0", +] +files = [ + {file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"}, + {file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"}, +] + +[[package]] +name = "pydantic" +version = "2.9.2" +requires_python = ">=3.8" +summary = "Data validation using Python type hints" +groups = ["default"] +dependencies = [ + "annotated-types>=0.6.0", + "pydantic-core==2.23.4", + "typing-extensions>=4.12.2; python_version >= \"3.13\"", + "typing-extensions>=4.6.1; python_version < \"3.13\"", +] +files = [ + {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"}, + {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"}, +] + +[[package]] +name = "pydantic-core" +version = "2.23.4" +requires_python = ">=3.8" +summary = "Core functionality for Pydantic validation and serialization" +groups = ["default"] +dependencies = [ + "typing-extensions!=4.7.0,>=4.6.0", +] +files = [ + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231"}, + {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"}, + {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e"}, + {file = "pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24"}, + {file = "pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84"}, + {file = "pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9"}, + {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"}, +] + +[[package]] +name = "pydantic-settings" +version = "2.2.1" +requires_python = ">=3.8" +summary = "Settings management using Pydantic" +groups = ["default"] +dependencies = [ + "pydantic>=2.3.0", + "python-dotenv>=0.21.0", +] +files = [ + {file = "pydantic_settings-2.2.1-py3-none-any.whl", hash = "sha256:0235391d26db4d2190cb9b31051c4b46882d28a51533f97440867f012d4da091"}, + {file = "pydantic_settings-2.2.1.tar.gz", hash = "sha256:00b9f6a5e95553590434c0fa01ead0b216c3e10bc54ae02e37f359948643c5ed"}, +] + +[[package]] +name = "pyright" +version = "1.1.385" +requires_python = ">=3.7" +summary = "Command line wrapper for pyright" +groups = ["dev"] +dependencies = [ + "nodeenv>=1.6.0", + "typing-extensions>=4.1", +] +files = [ + {file = "pyright-1.1.385-py3-none-any.whl", hash = "sha256:e5b9a1b8d492e13004d822af94d07d235f2c7c158457293b51ab2214c8c5b375"}, + {file = "pyright-1.1.385.tar.gz", hash = "sha256:1bf042b8f080441534aa02101dea30f8fc2efa8f7b6f1ab05197c21317f5bfa7"}, +] + +[[package]] +name = "pytest" +version = "8.3.3" +requires_python = ">=3.8" +summary = "pytest: simple powerful testing with Python" +groups = ["test"] +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2,>=1.5", + "tomli>=1; python_version < \"3.11\"", +] +files = [ + {file = "pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2"}, + {file = "pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181"}, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +requires_python = ">=3.8" +summary = "Read key-value pairs from a .env file and set them as environment variables" +groups = ["default"] +files = [ + {file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"}, + {file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +requires_python = ">=3.8" +summary = "YAML parser and emitter for Python" +groups = ["dev"] +files = [ + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + +[[package]] +name = "ruff" +version = "0.7.0" +requires_python = ">=3.7" +summary = "An extremely fast Python linter and code formatter, written in Rust." +groups = ["dev"] +files = [ + {file = "ruff-0.7.0-py3-none-linux_armv6l.whl", hash = "sha256:0cdf20c2b6ff98e37df47b2b0bd3a34aaa155f59a11182c1303cce79be715628"}, + {file = "ruff-0.7.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:496494d350c7fdeb36ca4ef1c9f21d80d182423718782222c29b3e72b3512737"}, + {file = "ruff-0.7.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:214b88498684e20b6b2b8852c01d50f0651f3cc6118dfa113b4def9f14faaf06"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:630fce3fefe9844e91ea5bbf7ceadab4f9981f42b704fae011bb8efcaf5d84be"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:211d877674e9373d4bb0f1c80f97a0201c61bcd1e9d045b6e9726adc42c156aa"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194d6c46c98c73949a106425ed40a576f52291c12bc21399eb8f13a0f7073495"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:82c2579b82b9973a110fab281860403b397c08c403de92de19568f32f7178598"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9af971fe85dcd5eaed8f585ddbc6bdbe8c217fb8fcf510ea6bca5bdfff56040e"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b641c7f16939b7d24b7bfc0be4102c56562a18281f84f635604e8a6989948914"}, + {file = "ruff-0.7.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71672336e46b34e0c90a790afeac8a31954fd42872c1f6adaea1dff76fd44f9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ab7d98c7eed355166f367597e513a6c82408df4181a937628dbec79abb2a1fe4"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1eb54986f770f49edb14f71d33312d79e00e629a57387382200b1ef12d6a4ef9"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:dc452ba6f2bb9cf8726a84aa877061a2462afe9ae0ea1d411c53d226661c601d"}, + {file = "ruff-0.7.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:4b406c2dce5be9bad59f2de26139a86017a517e6bcd2688da515481c05a2cb11"}, + {file = "ruff-0.7.0-py3-none-win32.whl", hash = "sha256:f6c968509f767776f524a8430426539587d5ec5c662f6addb6aa25bc2e8195ec"}, + {file = "ruff-0.7.0-py3-none-win_amd64.whl", hash = "sha256:ff4aabfbaaba880e85d394603b9e75d32b0693152e16fa659a3064a85df7fce2"}, + {file = "ruff-0.7.0-py3-none-win_arm64.whl", hash = "sha256:10842f69c245e78d6adec7e1db0a7d9ddc2fff0621d730e61657b64fa36f207e"}, + {file = "ruff-0.7.0.tar.gz", hash = "sha256:47a86360cf62d9cd53ebfb0b5eb0e882193fc191c6d717e8bef4462bc3b9ea2b"}, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +requires_python = ">=3.7" +summary = "Sniff out which async library your code is running under" +groups = ["default"] +files = [ + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +requires_python = ">=3.8" +summary = "Backported and Experimental Type Hints for Python 3.8+" +groups = ["default", "dev"] +files = [ + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, +] + +[[package]] +name = "virtualenv" +version = "20.27.0" +requires_python = ">=3.8" +summary = "Virtual Python Environment builder" +groups = ["dev"] +dependencies = [ + "distlib<1,>=0.3.7", + "filelock<4,>=3.12.2", + "importlib-metadata>=6.6; python_version < \"3.8\"", + "platformdirs<5,>=3.9.1", +] +files = [ + {file = "virtualenv-20.27.0-py3-none-any.whl", hash = "sha256:44a72c29cceb0ee08f300b314848c86e57bf8d1f13107a5e671fb9274138d655"}, + {file = "virtualenv-20.27.0.tar.gz", hash = "sha256:2ca56a68ed615b8fe4326d11a0dca5dfbe8fd68510fb6c6349163bed3c15f2b2"}, +] + +[[package]] +name = "xmltodict" +version = "0.14.2" +requires_python = ">=3.6" +summary = "Makes working with XML feel like you are working with JSON" +groups = ["default"] +files = [ + {file = "xmltodict-0.14.2-py2.py3-none-any.whl", hash = "sha256:20cc7d723ed729276e808f26fb6b3599f786cbc37e06c65e192ba77c40f20aac"}, + {file = "xmltodict-0.14.2.tar.gz", hash = "sha256:201e7c28bb210e374999d1dde6382923ab0ed1a8a5faeece48ab525b7810a553"}, +] diff --git a/pyproject.toml b/pyproject.toml index 2b4d161..fcbcf21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,47 +1,78 @@ [project] name = "dragonfly-loader" version = "1.0.1" -description = "Loads all the packages from the PyPI RSS feed into the Dragonfly API" -dynamic = ["dependencies"] - -[project.urls] -repository = "https://github.com/vipyrsec/dragonfly-loader/" +description = "Loads releases from the PyPI RSS feed into the Dragonfly Mainframe" +license = {text = "MIT"} +requires-python = ">=3.12,<3.13.dev0" +dependencies = [ + # Core + "pydantic-settings==2.2.1", + # PyPI integration + "letsbuilda-pypi==5.1.0", +] -[project.optional-dependencies] -dev = ["pip-tools", "pre-commit", "ruff", "mypy"] -tests = ["pytest"] + [project.optional-dependencies] + dev = ["pre-commit==4.0.1", "pyright==1.1.385", "ruff==0.7.0"] + test = ["pytest==8.3.3"] [build-system] -requires = ["setuptools", "wheel"] -build-backend = "setuptools.build_meta" +requires = ["pdm-backend"] +build-backend = "pdm.backend" + +[tool.pdm.scripts] +format = "ruff format" +lint = "ruff check --fix" +type-check = "pyright" +pre-commit = "pre-commit run --all-files" +test = "pytest" +all = {composite = ["format", "lint", "type-check", "test"]} + +[tool.pyright] +include = ["src/**/*.py"] -[tool.setuptools.dynamic.dependencies] -file = ["requirements/requirements.txt"] +venvPath = "." +venv = ".venv" [tool.ruff] -preview = true +preview = false unsafe-fixes = true target-version = "py311" line-length = 120 -[tool.ruff.lint] -select = ["ALL"] -ignore = [ - "CPY001", # (Missing copyright notice at top of file) - "DOC201", # `return` is not documented in docstring - "DOC402", # `yield` is not documented in docstring - "DOC501", # Raised exception `{id}` missing from docstring -] + [tool.ruff.lint] + select = ["ALL"] + ignore = [ + "DOC201", # `return` is not documented in docstring + "DOC402", # `yield` is not documented in docstring + "DOC501", # Raised exception `{id}` missing from docstring -[tool.ruff.lint.extend-per-file-ignores] -"tests/*" = [ - "INP001", # (File `tests/*.py` is part of an implicit namespace package. Add an `__init__.py`.) - Tests are not modules - "S101", # (Use of `assert` detected) - Yes, that's the point - "PT004", # (Fixture `*` does not return anything, add leading underscore) - Used for pytest fixtures - "ARG001", # (Unused function argument: `*`) - Used for pytest fixtures - "S105", # (Possible hardcoded password in variable) - Used to mock access tokens - "S106", # (Possible hardcoded password in argument) - Used to mock access tokens -] + # Conflicting rules with format (https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules) + 'COM812', + 'COM819', + 'D206', + 'D300', + 'E111', + 'E114', + 'E117', + 'ISC001', + 'ISC002', + 'Q000', + 'Q001', + 'Q002', + 'Q003', + 'W191', + ] + + [tool.ruff.lint.extend-per-file-ignores] + "docs/*" = [ + "INP001", # (File `docs/*.py` is part of an implicit namespace package. Add an `__init__.py`.) - Docs are not modules + ] + "tests/*" = [ + "INP001", # (File `tests/*.py` is part of an implicit namespace package. Add an `__init__.py`.) - Tests are not modules + "S101", # (Use of `assert` detected) - Yes, that's the point + "S105", # Possible hardcoded password -- Mock access tokens are used in tests. + "S106", # Possible hardcoded password -- Mock access tokens are used in tests. + ] -[tool.ruff.lint.pydocstyle] -convention = "numpy" + [tool.ruff.lint.pydocstyle] + convention = "numpy" diff --git a/requirements/requirements.in b/requirements/requirements.in deleted file mode 100644 index ee80efb..0000000 --- a/requirements/requirements.in +++ /dev/null @@ -1,5 +0,0 @@ -# Core -pydantic-settings - -# PyPI integration -letsbuilda-pypi>=5.0.0b3 diff --git a/requirements/requirements.txt b/requirements/requirements.txt deleted file mode 100644 index d876163..0000000 --- a/requirements/requirements.txt +++ /dev/null @@ -1,44 +0,0 @@ -# -# This file is autogenerated by pip-compile with Python 3.11 -# by the following command: -# -# pip-compile requirements/requirements.in -# -annotated-types==0.6.0 - # via pydantic -anyio==4.2.0 - # via httpx -certifi==2024.2.2 - # via - # httpcore - # httpx -h11==0.14.0 - # via httpcore -httpcore==1.0.3 - # via httpx -httpx==0.26.0 - # via letsbuilda-pypi -idna==3.6 - # via - # anyio - # httpx -letsbuilda-pypi==5.1.0 - # via -r requirements/requirements.in -pydantic==2.6.1 - # via pydantic-settings -pydantic-core==2.16.2 - # via pydantic -pydantic-settings==2.2.1 - # via -r requirements/requirements.in -python-dotenv==1.0.1 - # via pydantic-settings -sniffio==1.3.0 - # via - # anyio - # httpx -typing-extensions==4.9.0 - # via - # pydantic - # pydantic-core -xmltodict==0.13.0 - # via letsbuilda-pypi