From 26a3be6caa286ca0f29d266dfe194286d5cd56bf Mon Sep 17 00:00:00 2001 From: sbilge Date: Thu, 2 May 2024 12:36:33 +0000 Subject: [PATCH] template update --- .devcontainer/Dockerfile | 2 +- .devcontainer/devcontainer.json | 6 +- .github/workflows/check_config_docs.yaml | 4 +- .github/workflows/check_openapi_spec.yaml | 4 +- .github/workflows/check_pyproject.yaml | 4 +- .github/workflows/check_readme.yaml | 4 +- .github/workflows/static_code_analysis.yaml | 4 +- .github/workflows/tests.yaml | 2 +- .pre-commit-config.yaml | 18 +- .pyproject_generation/pyproject_template.toml | 15 +- .template/deprecated_files.txt | 1 + .template/static_files.txt | 4 +- Dockerfile | 4 +- lock/requirements-dev-template.in | 11 +- lock/requirements-dev.txt | 155 ++++++++---------- pyproject.toml | 9 +- .../{license_checker.py => check_license.py} | 71 ++++---- scripts/list_outdated_dependencies.py | 6 +- scripts/script_utils/cli.py | 7 + scripts/script_utils/deps.py | 17 +- scripts/script_utils/lock_deps.py | 6 +- scripts/update_pyproject.py | 32 ++-- scripts/update_readme.py | 4 +- 23 files changed, 182 insertions(+), 208 deletions(-) rename scripts/{license_checker.py => check_license.py} (97%) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index a3be419..50f7f65 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/vscode/devcontainers/python:3.9-bullseye +FROM mcr.microsoft.com/devcontainers/python:1-3.12-bullseye ENV PYTHONUNBUFFERED 1 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index ca1f921..b9b990e 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,5 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: // https://github.com/microsoft/vscode-dev-containers/tree/v0.177.0/containers/python-3-postgres -// Update the VARIANT arg in docker-compose.yml to pick a Python version: 3, 3.12, 3.11, 3.10, 3.9 { "name": "${localWorkspaceFolderBasename}", "dockerComposeFile": "docker-compose.yml", @@ -20,13 +19,10 @@ "python.languageServer": "Pylance", "python.analysis.typeCheckingMode": "basic", "python.testing.pytestPath": "/usr/local/py-utils/bin/pytest", - "python.testing.pytestArgs": [ - "--profile" - ], "python.testing.unittestEnabled": false, "python.testing.pytestEnabled": true, "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "explicit" }, "editor.formatOnSave": true, "editor.renderWhitespace": "all", diff --git a/.github/workflows/check_config_docs.yaml b/.github/workflows/check_config_docs.yaml index 1bffe59..b2d08c8 100644 --- a/.github/workflows/check_config_docs.yaml +++ b/.github/workflows/check_config_docs.yaml @@ -15,9 +15,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 - with: - python-version: '3.12' + uses: ghga-de/gh-action-common@v6 - name: Check config docs id: check-config-docs diff --git a/.github/workflows/check_openapi_spec.yaml b/.github/workflows/check_openapi_spec.yaml index 252b84d..ba4b8e0 100644 --- a/.github/workflows/check_openapi_spec.yaml +++ b/.github/workflows/check_openapi_spec.yaml @@ -16,9 +16,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 - with: - python-version: '3.12' + uses: ghga-de/gh-action-common@v6 - name: Check openapi.yaml id: check-openapi-docs diff --git a/.github/workflows/check_pyproject.yaml b/.github/workflows/check_pyproject.yaml index 4600d0a..0c7abdc 100644 --- a/.github/workflows/check_pyproject.yaml +++ b/.github/workflows/check_pyproject.yaml @@ -15,9 +15,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 - with: - python-version: '3.12' + uses: ghga-de/gh-action-common@v6 - name: Check pyproject.toml id: check-pyproject diff --git a/.github/workflows/check_readme.yaml b/.github/workflows/check_readme.yaml index c24bb1d..5d06e3f 100644 --- a/.github/workflows/check_readme.yaml +++ b/.github/workflows/check_readme.yaml @@ -15,9 +15,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 - with: - python-version: '3.12' + uses: ghga-de/gh-action-common@v6 - name: Check README id: check-readme diff --git a/.github/workflows/static_code_analysis.yaml b/.github/workflows/static_code_analysis.yaml index 12134ed..052dfdc 100644 --- a/.github/workflows/static_code_analysis.yaml +++ b/.github/workflows/static_code_analysis.yaml @@ -15,7 +15,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 + uses: ghga-de/gh-action-common@v6 - name: Run pre-commit uses: pre-commit/action@v3.0.1 @@ -36,4 +36,4 @@ jobs: - name: Check license header and file id: license-checker run: | - ./scripts/license_checker.py + ./scripts/check_license.py diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 33ce3d0..56a9c19 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -15,7 +15,7 @@ jobs: - name: Common steps id: common - uses: ghga-de/gh-action-common@v5 + uses: ghga-de/gh-action-common@v6 - name: Run tests id: pytest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index ee3b65f..4ac77e2 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,10 +1,7 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks -default_language_version: - python: python3.9 - -minimum_pre_commit_version: 3.0.0 +minimum_pre_commit_version: 3.7.0 repos: - repo: local @@ -28,7 +25,6 @@ repos: - id: end-of-file-fixer exclude: '.*\.json|example_config.yaml' - id: check-yaml - args: [--unsafe] - id: check-added-large-files - id: check-ast - id: check-json @@ -48,20 +44,14 @@ repos: args: [--fix=lf] - id: no-commit-to-branch args: [--branch, dev, --branch, int, --branch, main] - - id: debug-statements - - id: debug-statements - - id: debug-statements - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.3.7 + rev: v0.4.2 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - - repo: https://github.com/psf/black - rev: 23.11.0 - hooks: - - id: black + - id: ruff-format - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.9.0 + rev: v1.10.0 hooks: - id: mypy args: [--no-warn-unused-ignores] diff --git a/.pyproject_generation/pyproject_template.toml b/.pyproject_generation/pyproject_template.toml index e2d5958..07a11ff 100644 --- a/.pyproject_generation/pyproject_template.toml +++ b/.pyproject_generation/pyproject_template.toml @@ -7,14 +7,12 @@ readme = "README.md" authors = [ { name = "German Human Genome Phenome Archive (GHGA)", email = "contact@ghga.de" }, ] -requires-python = ">=3.9" +requires-python = ">=3.12" license = { text = "Apache 2.0" } classifiers = [ "Development Status :: 1 - Planning", "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "License :: OSI Approved :: Apache Software License", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", @@ -35,7 +33,7 @@ exclude = [ ] line-length = 88 src = ["src", "tests", "examples", "scripts"] -target-version = "py39" +target-version = "py312" [tool.ruff.lint] fixable = [ @@ -60,6 +58,7 @@ ignore = [ "D107", # missing docstring in __init__ "D206", # indent-with-spaces (for formatter) "D300", # triple-single-quotes (for formatter) + "UP040", # type statement (not yet supported by mypy) ] select = [ "C90", # McCabe Complexity @@ -105,7 +104,7 @@ asyncio_mode = "strict" [tool.coverage.paths] source = [ - "src", - "/workspace/src", - "**/lib/python*/site-packages", + "src", + "/workspace/src", + "**/lib/python*/site-packages", ] diff --git a/.template/deprecated_files.txt b/.template/deprecated_files.txt index df962ef..152ea26 100644 --- a/.template/deprecated_files.txt +++ b/.template/deprecated_files.txt @@ -13,6 +13,7 @@ .github/workflows/cd.yaml scripts/check_mandatory_and_static_files.py +scripts/license_checker.py scripts/update_static_files.py docs diff --git a/.template/static_files.txt b/.template/static_files.txt index 46e46bf..1cf9790 100644 --- a/.template/static_files.txt +++ b/.template/static_files.txt @@ -15,10 +15,12 @@ scripts/script_utils/__init__.py scripts/script_utils/cli.py +scripts/script_utils/deps.py +scripts/script_utils/lock_deps.py scripts/__init__.py scripts/update_all.py -scripts/license_checker.py +scripts/check_license.py scripts/get_package_name.py scripts/update_config_docs.py scripts/update_template_files.py diff --git a/Dockerfile b/Dockerfile index 8c0e7f4..10d62de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. ## creating building container -FROM python:3.10.9-slim-bullseye AS builder +FROM python:3.12-slim-bookworm AS builder # update and install dependencies RUN apt update RUN apt upgrade -y @@ -26,7 +26,7 @@ WORKDIR /service RUN python -m build # creating running container -FROM python:3.10.9-slim-bullseye +FROM python:3.12-slim-bookworm # update and install dependencies RUN apt update RUN apt upgrade -y diff --git a/lock/requirements-dev-template.in b/lock/requirements-dev-template.in index 36459d7..da84663 100644 --- a/lock/requirements-dev-template.in +++ b/lock/requirements-dev-template.in @@ -1,17 +1,17 @@ # common requirements for development and testing of services -pytest>=8.1 -pytest-asyncio>=0.23 +pytest>=8.2 +pytest-asyncio>=0.23.6 pytest-cov>=5 snakeviz>=2.2 logot>=1.3 pre-commit>=3.7 -mypy>=1.9 +mypy>=1.10 mypy-extensions>=1.0 -ruff>=0.3 +ruff>=0.4 click>=8.1 typer>=0.12 @@ -27,7 +27,6 @@ jsonschema2md>=1.1 setuptools>=69.5 # required since switch to pyproject.toml and pip-tools -tomli>=2.0.1 tomli_w>=1.0 -uv>=0.1.31 +uv>=0.1.39 diff --git a/lock/requirements-dev.txt b/lock/requirements-dev.txt index 9aa20c8..a3de336 100644 --- a/lock/requirements-dev.txt +++ b/lock/requirements-dev.txt @@ -182,12 +182,6 @@ et-xmlfile==1.1.0 \ --hash=sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c \ --hash=sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada # via openpyxl -exceptiongroup==1.2.0 \ - --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ - --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 - # via - # anyio - # pytest filelock==3.13.4 \ --hash=sha256:404e5e9253aa60ad457cae1be07c0f0ca90a63931200a47d9b6a6af84fd7b45f \ --hash=sha256:d13f466618bfde72bd2c18255e269f72542c6e70e7bac83a0232d6b1cc5c8cf4 @@ -233,34 +227,34 @@ mdurl==0.1.2 \ --hash=sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8 \ --hash=sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba # via markdown-it-py -mypy==1.9.0 \ - --hash=sha256:0235391f1c6f6ce487b23b9dbd1327b4ec33bb93934aa986efe8a9563d9349e6 \ - --hash=sha256:190da1ee69b427d7efa8aa0d5e5ccd67a4fb04038c380237a0d96829cb157913 \ - --hash=sha256:2418488264eb41f69cc64a69a745fad4a8f86649af4b1041a4c64ee61fc61129 \ - --hash=sha256:3a3c007ff3ee90f69cf0a15cbcdf0995749569b86b6d2f327af01fd1b8aee9dc \ - --hash=sha256:3cc5da0127e6a478cddd906068496a97a7618a21ce9b54bde5bf7e539c7af974 \ - --hash=sha256:48533cdd345c3c2e5ef48ba3b0d3880b257b423e7995dada04248725c6f77374 \ - --hash=sha256:49c87c15aed320de9b438ae7b00c1ac91cd393c1b854c2ce538e2a72d55df150 \ - --hash=sha256:4d3dbd346cfec7cb98e6cbb6e0f3c23618af826316188d587d1c1bc34f0ede03 \ - --hash=sha256:571741dc4194b4f82d344b15e8837e8c5fcc462d66d076748142327626a1b6e9 \ - --hash=sha256:587ce887f75dd9700252a3abbc9c97bbe165a4a630597845c61279cf32dfbf02 \ - --hash=sha256:5d741d3fc7c4da608764073089e5f58ef6352bedc223ff58f2f038c2c4698a89 \ - --hash=sha256:5e6061f44f2313b94f920e91b204ec600982961e07a17e0f6cd83371cb23f5c2 \ - --hash=sha256:61758fabd58ce4b0720ae1e2fea5cfd4431591d6d590b197775329264f86311d \ - --hash=sha256:653265f9a2784db65bfca694d1edd23093ce49740b2244cde583aeb134c008f3 \ - --hash=sha256:68edad3dc7d70f2f17ae4c6c1b9471a56138ca22722487eebacfd1eb5321d612 \ - --hash=sha256:81a10926e5473c5fc3da8abb04119a1f5811a236dc3a38d92015cb1e6ba4cb9e \ - --hash=sha256:85ca5fcc24f0b4aeedc1d02f93707bccc04733f21d41c88334c5482219b1ccb3 \ - --hash=sha256:a260627a570559181a9ea5de61ac6297aa5af202f06fd7ab093ce74e7181e43e \ - --hash=sha256:aceb1db093b04db5cd390821464504111b8ec3e351eb85afd1433490163d60cd \ - --hash=sha256:b685154e22e4e9199fc95f298661deea28aaede5ae16ccc8cbb1045e716b3e04 \ - --hash=sha256:d357423fa57a489e8c47b7c85dfb96698caba13d66e086b412298a1a0ea3b0ed \ - --hash=sha256:d4d5ddc13421ba3e2e082a6c2d74c2ddb3979c39b582dacd53dd5d9431237185 \ - --hash=sha256:e49499be624dead83927e70c756970a0bc8240e9f769389cdf5714b0784ca6bf \ - --hash=sha256:e54396d70be04b34f31d2edf3362c1edd023246c82f1730bbf8768c28db5361b \ - --hash=sha256:f88566144752999351725ac623471661c9d1cd8caa0134ff98cceeea181789f4 \ - --hash=sha256:f8a67616990062232ee4c3952f41c779afac41405806042a8126fe96e098419f \ - --hash=sha256:fe28657de3bfec596bbeef01cb219833ad9d38dd5393fc649f4b366840baefe6 +mypy==1.10.0 \ + --hash=sha256:075cbf81f3e134eadaf247de187bd604748171d6b79736fa9b6c9685b4083061 \ + --hash=sha256:12b6bfc1b1a66095ab413160a6e520e1dc076a28f3e22f7fb25ba3b000b4ef99 \ + --hash=sha256:1ec404a7cbe9fc0e92cb0e67f55ce0c025014e26d33e54d9e506a0f2d07fe5de \ + --hash=sha256:28d0e038361b45f099cc086d9dd99c15ff14d0188f44ac883010e172ce86c38a \ + --hash=sha256:2b0695d605ddcd3eb2f736cd8b4e388288c21e7de85001e9f85df9187f2b50f9 \ + --hash=sha256:3236a4c8f535a0631f85f5fcdffba71c7feeef76a6002fcba7c1a8e57c8be1ec \ + --hash=sha256:3be66771aa5c97602f382230165b856c231d1277c511c9a8dd058be4784472e1 \ + --hash=sha256:3d087fcbec056c4ee34974da493a826ce316947485cef3901f511848e687c131 \ + --hash=sha256:3f298531bca95ff615b6e9f2fc0333aae27fa48052903a0ac90215021cdcfa4f \ + --hash=sha256:4a2b5cdbb5dd35aa08ea9114436e0d79aceb2f38e32c21684dcf8e24e1e92821 \ + --hash=sha256:4cf18f9d0efa1b16478c4c129eabec36148032575391095f73cae2e722fcf9d5 \ + --hash=sha256:8b2cbaca148d0754a54d44121b5825ae71868c7592a53b7292eeb0f3fdae95ee \ + --hash=sha256:8f55583b12156c399dce2df7d16f8a5095291354f1e839c252ec6c0611e86e2e \ + --hash=sha256:92f93b21c0fe73dc00abf91022234c79d793318b8a96faac147cd579c1671746 \ + --hash=sha256:9e36fb078cce9904c7989b9693e41cb9711e0600139ce3970c6ef814b6ebc2b2 \ + --hash=sha256:9fd50226364cd2737351c79807775136b0abe084433b55b2e29181a4c3c878c0 \ + --hash=sha256:a781f6ad4bab20eef8b65174a57e5203f4be627b46291f4589879bf4e257b97b \ + --hash=sha256:a87dbfa85971e8d59c9cc1fcf534efe664d8949e4c0b6b44e8ca548e746a8d53 \ + --hash=sha256:b808e12113505b97d9023b0b5e0c0705a90571c6feefc6f215c1df9381256e30 \ + --hash=sha256:bc6ac273b23c6b82da3bb25f4136c4fd42665f17f2cd850771cb600bdd2ebeda \ + --hash=sha256:cd777b780312ddb135bceb9bc8722a73ec95e042f911cc279e2ec3c667076051 \ + --hash=sha256:da1cbf08fb3b851ab3b9523a884c232774008267b1f83371ace57f412fe308c2 \ + --hash=sha256:e22e1527dc3d4aa94311d246b59e47f6455b8729f4968765ac1eacf9a4760bc7 \ + --hash=sha256:f8c083976eb530019175aabadb60921e73b4f45736760826aa1689dda8208aee \ + --hash=sha256:f90cff89eea89273727d8783fef5d4a934be2fdca11b47def50cf5d311aff727 \ + --hash=sha256:fa7ef5244615a2523b56c034becde4e9e3f9b034854c93639adb667ec9ec2976 \ + --hash=sha256:fcfc70599efde5c67862a07a1aaf50e55bce629ace26bb19dc17cece5dd31ca4 mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 @@ -282,9 +276,9 @@ platformdirs==4.2.0 \ --hash=sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068 \ --hash=sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768 # via virtualenv -pluggy==1.4.0 \ - --hash=sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981 \ - --hash=sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be +pluggy==1.5.0 \ + --hash=sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1 \ + --hash=sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 # via pytest pre-commit==3.7.0 \ --hash=sha256:5eae9e10c2b5ac51577c3452ec0a490455c45a0533f7960f993a0d01e59decab \ @@ -377,9 +371,9 @@ pygments==2.17.2 \ --hash=sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c \ --hash=sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367 # via rich -pytest==8.1.1 \ - --hash=sha256:2a8386cfc11fa9d2c50ee7b2a57e7d898ef90470a7a34c4b949ff59662bb78b7 \ - --hash=sha256:ac978141a75948948817d360297b7aae0fcb9d6ff6bc9ec6d514b85d5a65c044 +pytest==8.2.0 \ + --hash=sha256:1733f0620f6cda4095bbf0d9ff8022486e91892245bb9e7d5542c018f612f233 \ + --hash=sha256:d507d4482197eac0ba2bae2e9babf0672eb333017bcedaa5fb1a3d42c1174b3f # via # pytest-asyncio # pytest-cov @@ -456,24 +450,24 @@ rich==13.7.1 \ --hash=sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222 \ --hash=sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432 # via typer -ruff==0.3.7 \ - --hash=sha256:0e8377cccb2f07abd25e84fc5b2cbe48eeb0fea9f1719cad7caedb061d70e5ce \ - --hash=sha256:15a4d1cc1e64e556fa0d67bfd388fed416b7f3b26d5d1c3e7d192c897e39ba4b \ - --hash=sha256:3050ec0af72b709a62ecc2aca941b9cd479a7bf2b36cc4562f0033d688e44fa1 \ - --hash=sha256:379b67d4f49774ba679593b232dcd90d9e10f04d96e3c8ce4a28037ae473f7bb \ - --hash=sha256:5b15cc59c19edca917f51b1956637db47e200b0fc5e6e1878233d3a938384b0b \ - --hash=sha256:5ef0e501e1e39f35e03c2acb1d1238c595b8bb36cf7a170e7c1df1b73da00e74 \ - --hash=sha256:6c44e0149f1d8b48c4d5c33d88c677a4aa22fd09b1683d6a7ff55b816b5d074f \ - --hash=sha256:789e144f6dc7019d1f92a812891c645274ed08af6037d11fc65fcbc183b7d59f \ - --hash=sha256:a29cc38e4c1ab00da18a3f6777f8b50099d73326981bb7d182e54a9a21bb4ff7 \ - --hash=sha256:bc931de87593d64fad3a22e201e55ad76271f1d5bfc44e1a1887edd0903c7d9f \ - --hash=sha256:c060aea8ad5ef21cdfbbe05475ab5104ce7827b639a78dd55383a6e9895b7c51 \ - --hash=sha256:d28bdf3d7dc71dd46929fafeec98ba89b7c3550c3f0978e36389b5631b793663 \ - --hash=sha256:d48098bd8f5c38897b03604f5428901b65e3c97d40b3952e38637b5404b739a2 \ - --hash=sha256:d5c1aebee5162c2226784800ae031f660c350e7a3402c4d1f8ea4e97e232e3ba \ - --hash=sha256:da8a4fda219bf9024692b1bc68c9cff4b80507879ada8769dc7e985755d662ea \ - --hash=sha256:e491045781b1e38b72c91247cf4634f040f8d0cb3e6d3d64d38dcf43616650b4 \ - --hash=sha256:ebf8f615dde968272d70502c083ebf963b6781aacd3079081e03b32adfe4d58a +ruff==0.4.2 \ + --hash=sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b \ + --hash=sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68 \ + --hash=sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac \ + --hash=sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483 \ + --hash=sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc \ + --hash=sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5 \ + --hash=sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798 \ + --hash=sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd \ + --hash=sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22 \ + --hash=sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376 \ + --hash=sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe \ + --hash=sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480 \ + --hash=sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e \ + --hash=sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa \ + --hash=sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5 \ + --hash=sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf \ + --hash=sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069 semver==3.0.2 \ --hash=sha256:6253adb39c70f6e51afed2fa7152bcd414c411286088fb4b9effb133885ab4cc \ --hash=sha256:b1ea4686fe70b981f85359eda33199d60c53964284e0cfb4977d243e37cf4bf4 @@ -499,13 +493,6 @@ stringcase==1.2.0 \ testcontainers==4.3.3 \ --hash=sha256:48d5cc314be39ad8e678057347c49aef5f2786227470a2fcf43584fc79a8e4a0 \ --hash=sha256:e9309c53529e842485e4b326a754bb87b0ddaa78da6422275b52796c0cb7eb8b -tomli==2.0.1 \ - --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ - --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f - # via - # coverage - # mypy - # pytest tomli-w==1.0.0 \ --hash=sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463 \ --hash=sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9 @@ -529,8 +516,6 @@ typing-extensions==4.11.0 \ --hash=sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0 \ --hash=sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a # via - # anyio - # logot # mypy # pydantic # pydantic-core @@ -543,24 +528,24 @@ urllib3==1.26.18 \ # docker # requests # testcontainers -uv==0.1.32 \ - --hash=sha256:0c9ca49cc73bf61eaf88d005bc16193a2f211a736f26c7612fa158a9a44c4efc \ - --hash=sha256:0db70283655a2bee8129562b0d0c33979a9ea0586572402a226ffae370e24d20 \ - --hash=sha256:11f1df69d5adad54871e12ed7d7c9250deda9da4800b3dadfa84a65625e945f5 \ - --hash=sha256:2d1c85698040efe36b2ddf8b9072c8f01c14a9fa164b5d0a2e6b0dbb11443439 \ - --hash=sha256:339a275711f2c1faab155f47c2e06e272292401ab054ede37d92ef7ebbffad9b \ - --hash=sha256:47ff7ab9cdadf01033663b74d65a57648f41b81d07f047370b7eefff934680ec \ - --hash=sha256:5af112155bbd9b0abe7748d6b31186c3c0c8cf7931dc99762cc45ad9f44732f7 \ - --hash=sha256:907ff64b74da60e2280b4536f7ae64539219254286c81b857f709ab2e91487ff \ - --hash=sha256:9365a51e1dd711b8cab661a481b1222dba721497b8a7604bb1fe8e63db900476 \ - --hash=sha256:a7547b19596bec70a041d4c74af1cdd5c3f426c9dd0edb5b6c98a159cc65f43f \ - --hash=sha256:ac453ebbc52da083501a56e0378a71be637920c4cbf60b6dca64292464a00c23 \ - --hash=sha256:c3b9bb6194e3e2ea41174fc49d66d09eeb5566a5b3c6a6476f30ea2342e547f5 \ - --hash=sha256:dac71a5abac7c45914acbdc5760be1c7c14c8ce4da7447dfa4f661a57d3d0afe \ - --hash=sha256:e10e3a44c73934a78eaac199952585aed1f8b0c742b8b034570b3816cb9071af \ - --hash=sha256:ed6a41164aac4538a5bbb850ab52a6c2a679e9aa642f32f001799fd5a3ccf00c \ - --hash=sha256:f61de511a3296aa9519ac9cc1d30987aea00a94cd964c8227088a14f0b3f3ab3 \ - --hash=sha256:faf8bba1feb328b93376c2ff26a436a4a41ac45e12c3e46a850edb289e7653fd +uv==0.1.39 \ + --hash=sha256:2333dd52e6734e0da6722bdd7b7257d0f8beeac89623c5cfc3888b4c56bc812e \ + --hash=sha256:2ae930189742536f8178617c4ec05cb10271cb3886f6039abd36ee6ab511b160 \ + --hash=sha256:2bda6686a9bb1370d7f53436d34f8ede0fa1b9877b5e152aedd9b22fc3cb33a9 \ + --hash=sha256:3330bd7ab8a6160d815fdc36f48479edf6db8b58d39d20959555095ea7eb63c5 \ + --hash=sha256:3365e0631a738a482d2379e565a230b135f7c5665394313829ccabf7c76c1362 \ + --hash=sha256:388018659e5d73fdeb8ce13c1d812391ec981bf446ab86fb9c0e3d227f727da2 \ + --hash=sha256:4c6ee1148f23aa5d6edf1a1106cc33c4aa57bdbfe8d4c5068c672105415d3b99 \ + --hash=sha256:6b2acc907f7a1735dd9ffeb20d8c7aeeb86b1e5ba0a999e09433ad7f2789dc78 \ + --hash=sha256:7848d703201e6867ae2c70d611e6ffd53d5e5adfc2c9abe89b6d021975e43e81 \ + --hash=sha256:7ee426e0c5fa048cc44f3ac78e476121ef4365bb8bc9199d3cbffc372a80e55d \ + --hash=sha256:88f5601ee957f9be2efc7a24d186f9d2641053806e107e0e42c5e522882c89e0 \ + --hash=sha256:93217578e68a431df235173e390ad7df090499367cd7f5c811520fd4ea3d5047 \ + --hash=sha256:c131dba5fe5079d9c5f06846649e35662901a9afd9b31de17714c63e042d91d2 \ + --hash=sha256:c20b9023dac12ee518de79c91df313be7abb052440cb78f8ffb20dea81d3289e \ + --hash=sha256:cd6d9629ab0e22ab2336b8d6363573ea5a7060ef82ff5d3e6da4b1b30522ef13 \ + --hash=sha256:ce911087f56edc97a5792c17f682ed7611fedead0ea117f56bb6f3942eb3e7b3 \ + --hash=sha256:fba96b3049aea5c1394cd360e5900e4af39829df48ed6fc55eba115c00c8195a virtualenv==20.25.1 \ --hash=sha256:961c026ac520bac5f69acb8ea063e8a4f071bcc9457b9c1f28f6b085c511583a \ --hash=sha256:e08e13ecdca7a0bd53798f356d5831434afa5b07b93f0abdf0797b7a06ffe197 diff --git a/pyproject.toml b/pyproject.toml index 3a624b2..151999d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,13 +9,11 @@ readme = "README.md" authors = [ { name = "German Human Genome Phenome Archive (GHGA)", email = "contact@ghga.de" }, ] -requires-python = ">=3.9" +requires-python = ">=3.12" classifiers = [ "Development Status :: 1 - Planning", "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "License :: OSI Approved :: Apache Software License", "Topic :: Internet :: WWW/HTTP :: HTTP Servers", @@ -62,7 +60,7 @@ src = [ "examples", "scripts", ] -target-version = "py39" +target-version = "py312" [tool.ruff.lint] fixable = [ @@ -87,6 +85,7 @@ ignore = [ "D107", "D206", "D300", + "UP040", ] select = [ "C90", diff --git a/scripts/license_checker.py b/scripts/check_license.py similarity index 97% rename from scripts/license_checker.py rename to scripts/check_license.py index 9d484db..96a2c83 100755 --- a/scripts/license_checker.py +++ b/scripts/check_license.py @@ -24,7 +24,6 @@ import sys from datetime import date from pathlib import Path -from typing import Optional, Union # root directory of the package: ROOT_DIR = Path(__file__).parent.parent.resolve() @@ -34,45 +33,45 @@ # exclude files and dirs from license header check: EXCLUDE = [ + ".coveragerc", ".devcontainer", - "eggs", + ".editorconfig", ".eggs", - "build", - "dist", - "develop-eggs", - "lib", - "lib62", - "parts", - "sdist", - "wheels", - "pip-wheel-metadata", - ".coveragerc", ".git", ".github", ".flake8", - ".gitignore", - ".pylintrc", - ".ruff.toml", - ".ruff_cache", - "example_config.yaml", - "config_schema.json", - "LICENSE", # is checked but not for the license header - ".pre-commit-config.yaml", - "docs", - ".vscode", + ".gitignore" ".pre-commit-config.yaml", ".mypy_cache", ".mypy.ini", + ".pylintrc", ".pytest_cache", - ".editorconfig", - ".tox", - "venv", - ".venv", + ".ruff.toml", + ".ruff_cache", ".template/.static_files.txt", ".template/.static_files_ignore.txt", ".template/.mandatory_files.txt", ".template/.mandatory_files_ignore.txt", ".template/.deprecated_files.txt", ".template/.deprecated_files_ignore.txt", + ".tox", + ".venv", + ".vscode", + "eggs", + "build", + "config_schema.json", + "dist", + "docs", + "develop-eggs", + "example_config.yaml", + "htmlcov", + "lib", + "lib62", + "parts", + "pip-wheel-metadata", + "sdist", + "venv", + "wheels", + "LICENSE", # is checked but not for the license header ] # exclude file by file ending from license header check: @@ -140,11 +139,11 @@ class GlobalCopyrightNotice: """ def __init__(self): - self._text: Optional[str] = None - self._n_lines: Optional[int] = None + self._text: str | None = None + self._n_lines: int | None = None @property - def text(self) -> Optional[str]: + def text(self) -> str | None: return self._text @text.setter @@ -167,7 +166,7 @@ def n_lines(self) -> int: class UnexpectedBinaryFileError(RuntimeError): """Thrown when trying to read a binary file.""" - def __init__(self, file_path: Union[str, Path]): + def __init__(self, file_path: str | Path): message = f"The file could not be read because it is binary: {str(file_path)}" super().__init__(message) @@ -181,13 +180,13 @@ def get_target_files( """Get target files that are not match the exclude conditions. Args: target_dir (pathlib.Path): The target dir to search. - exclude (List[str], optional): + exclude (list[str], optional): Overwrite default list of file/dir paths relative to the target dir that shall be excluded. - exclude_endings (List[str], optional): + exclude_endings (list[str], optional): Overwrite default list of file endings that shall be excluded. - exclude_pattern (List[str], optional): + exclude_pattern (list[str], optional): Overwrite default list of regex patterns match file path for exclusion. """ @@ -407,13 +406,13 @@ def check_file_headers( The author that shall be included in the license header. It will replace any appearance of "{author}" in the license header. This defaults to an author info for GHGA. - exclude (List[str], optional): + exclude (list[str], optional): Overwrite default list of file/dir paths relative to the target dir that shall be excluded. - exclude_endings (List[str], optional): + exclude_endings (list[str], optional): Overwrite default list of file endings that shall be excluded. - exclude_pattern (List[str], optional): + exclude_pattern (list[str], optional): Overwrite default list of regex patterns match file path for exclusion. """ diff --git a/scripts/list_outdated_dependencies.py b/scripts/list_outdated_dependencies.py index cbdcb3a..894818c 100755 --- a/scripts/list_outdated_dependencies.py +++ b/scripts/list_outdated_dependencies.py @@ -139,12 +139,14 @@ def print_table( header_lengths = [len(header) for header in headers] # Find the maximum length of each column - col_widths = [max(len(str(cell)) for cell in col) for col in zip(*rows)] + col_widths = [ + max(len(str(cell)) for cell in col) for col in zip(*rows, strict=True) + ] # Create a row format based on the maximum column widths row_format = delimiter.join( f"{{:<{max(width, header_len)}}}" - for width, header_len in zip(col_widths, header_lengths) + for width, header_len in zip(col_widths, header_lengths, strict=True) ) print(" " + row_format.format(*headers)) diff --git a/scripts/script_utils/cli.py b/scripts/script_utils/cli.py index 0d77ce2..c7d6af4 100644 --- a/scripts/script_utils/cli.py +++ b/scripts/script_utils/cli.py @@ -26,6 +26,13 @@ def echo_success(message: str): typer.echo(styled_message) +def echo_warning(message: str): + """Print a warning message.""" + + styled_message = typer.style(text=message, fg=typer.colors.YELLOW) + typer.echo(styled_message) + + def echo_failure(message: str): """Print a failure message.""" diff --git a/scripts/script_utils/deps.py b/scripts/script_utils/deps.py index 5d65cf7..4e2f8e7 100644 --- a/scripts/script_utils/deps.py +++ b/scripts/script_utils/deps.py @@ -1,4 +1,4 @@ -# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln # for the German Human Genome-Phenome Archive (GHGA) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,12 +14,13 @@ # limitations under the License. # """Contains utils for working with dependencies, lock files, etc.""" + +import tomllib from copy import deepcopy from pathlib import Path from typing import Any import stringcase -import tomli def exclude_from_dependency_list(*, package_name: str, dependencies: list) -> list: @@ -55,11 +56,11 @@ def remove_self_dependencies(pyproject: dict) -> dict: if "optional-dependencies" in project_metadata: for group in project_metadata["optional-dependencies"]: - project_metadata["optional-dependencies"][ - group - ] = exclude_from_dependency_list( - package_name=package_name, - dependencies=project_metadata["optional-dependencies"][group], + project_metadata["optional-dependencies"][group] = ( + exclude_from_dependency_list( + package_name=package_name, + dependencies=project_metadata["optional-dependencies"][group], + ) ) return modified_pyproject @@ -68,7 +69,7 @@ def remove_self_dependencies(pyproject: dict) -> dict: def get_modified_pyproject(pyproject_toml_path: Path) -> dict[str, Any]: """Get a copy of pyproject.toml with any self-referencing dependencies removed.""" with open(pyproject_toml_path, "rb") as pyproject_toml: - pyproject = tomli.load(pyproject_toml) + pyproject = tomllib.load(pyproject_toml) modified_pyproject = remove_self_dependencies(pyproject) return modified_pyproject diff --git a/scripts/script_utils/lock_deps.py b/scripts/script_utils/lock_deps.py index 60d857e..f800d14 100644 --- a/scripts/script_utils/lock_deps.py +++ b/scripts/script_utils/lock_deps.py @@ -1,4 +1,4 @@ -# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# Copyright 2021 - 2024 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln # for the German Human Genome-Phenome Archive (GHGA) # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,16 +14,16 @@ # limitations under the License. # """Provides a function to get all dependencies from the lock file""" + import re from pathlib import Path -from typing import Optional from packaging.requirements import Requirement def get_lock_file_deps( lock_file_path: Path, - exclude: Optional[set[str]] = None, + exclude: set[str] | None = None, ) -> list[Requirement]: """Inspect the lock file to get the dependencies. diff --git a/scripts/update_pyproject.py b/scripts/update_pyproject.py index 6f63cd3..a09c6f0 100755 --- a/scripts/update_pyproject.py +++ b/scripts/update_pyproject.py @@ -19,9 +19,9 @@ """A script to update the pyproject.toml.""" import sys +import tomllib from pathlib import Path -import tomli import tomli_w from script_utils import cli @@ -37,33 +37,33 @@ def read_template_pyproject() -> dict[str, object]: """Read the pyproject_template.toml.""" with open(PYPROJECT_TEMPLATE_PATH, "rb") as file: - return tomli.load(file) + return tomllib.load(file) def read_custom_pyproject() -> dict[str, object]: """Read the pyproject_custom.toml.""" with open(PYPROJECT_CUSTOM_PATH, "rb") as file: - return tomli.load(file) + return tomllib.load(file) def read_current_pyproject() -> dict[str, object]: """Read the current pyproject.toml.""" with open(PYPROJECT_TOML, "rb") as file: - return tomli.load(file) + return tomllib.load(file) def write_pyproject(pyproject: dict[str, object]) -> None: """Write the given pyproject dict into the pyproject.toml.""" with open(PYPROJECT_TOML, "wb") as file: - tomli_w.dump(pyproject, file) + tomli_w.dump(pyproject, file, multiline_strings=True) def merge_fields(*, source: dict[str, object], dest: dict[str, object]): """Merge fields existing in both custom and template pyproject definitions. If a given field is a dictionary, merge or assign depending on if it's found in dest. - If the field is anything else either assign the value or exit with a message if a - conflict exists. + If the field is anything else either assign the value or exit with an error message + if the values have different types. """ for field, value in source.items(): if isinstance(value, dict): @@ -72,11 +72,13 @@ def merge_fields(*, source: dict[str, object], dest: dict[str, object]): else: dest[field] = value else: - if field in dest and value != dest[field]: - cli.echo_failure(f"Conflicting values for '{field}'") - exit(1) - elif field not in dest: - dest[field] = value + if field in dest: + if type(value) == type(dest[field]): + cli.echo_warning(f"Overriding value for '{field}'...") + else: + cli.echo_failure(f"Conflicting types for '{field}'...") + sys.exit(1) + dest[field] = value def merge_pyprojects(inputs: list[dict[str, object]]) -> dict[str, object]: @@ -85,10 +87,10 @@ def merge_pyprojects(inputs: list[dict[str, object]]) -> dict[str, object]: for input in inputs[1:]: for field, value in input.items(): - if field not in pyproject: - pyproject[field] = value - else: + if field in pyproject: merge_fields(source=value, dest=pyproject[field]) # type: ignore + else: + pyproject[field] = value return pyproject diff --git a/scripts/update_readme.py b/scripts/update_readme.py index cf705b6..41052d2 100755 --- a/scripts/update_readme.py +++ b/scripts/update_readme.py @@ -20,11 +20,11 @@ import json import subprocess # nosec import sys +import tomllib from pathlib import Path from string import Template import jsonschema2md -import tomli from pydantic import BaseModel, Field from stringcase import spinalcase, titlecase @@ -97,7 +97,7 @@ def read_toml_package_header() -> PackageHeader: """Read basic information about the package from the pyproject.toml""" with open(PYPROJECT_TOML_PATH, "rb") as pyproject_toml: - pyproject = tomli.load(pyproject_toml) + pyproject = tomllib.load(pyproject_toml) pyproject_project = pyproject["project"] return PackageHeader( shortname=pyproject_project["name"],