From 68a463acb8d5a2ad4db4dcefb95f13ca547ed516 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 12:58:33 +0000 Subject: [PATCH 01/16] Migrate to uv --- .github/assets/.copier-answers.yml | 8 +- README.md | 39 ++--- copier.yml | 24 ++- project/.devcontainer/Dockerfile.jinja | 11 +- project/.devcontainer/devcontainer.json.jinja | 11 +- project/.github/dependabot.yml.jinja | 13 +- project/.github/workflows/build.yaml.jinja | 22 ++- project/.github/workflows/release.yaml.jinja | 25 ++- ...copier-delete-branch.yaml{% endif %}.jinja | 2 +- ...auto_update %}copier.yaml{% endif %}.jinja | 32 +++- ... include_docs %}docs.yaml{% endif %}.jinja | 41 ++++- project/README.md.jinja | 29 ++-- project/pyproject.toml.jinja | 157 +++++++++++------- .../{docs => }/index.md | 0 .../{docs => }/styles/extra.css | 0 .../index.md | 0 .../intro_notebook.ipynb | 0 ...nclude_docs %}mkdocs.yml{% endif %}.jinja} | 0 ...%}.pre-commit-config.yaml{% endif %}.jinja | 16 +- 19 files changed, 307 insertions(+), 123 deletions(-) rename project/{% if include_docs %}docs{% endif %}/{docs => }/index.md (100%) rename project/{% if include_docs %}docs{% endif %}/{docs => }/styles/extra.css (100%) rename project/{% if include_docs %}docs{% endif %}/{docs => }/{% if include_notebooks %}notebooks{% endif %}/index.md (100%) rename project/{% if include_docs %}docs{% endif %}/{docs => }/{% if include_notebooks %}notebooks{% endif %}/intro_notebook.ipynb (100%) rename project/{{% if include_docs %}docs{% endif %}/mkdocs.yml.jinja => {% if include_docs %}mkdocs.yml{% endif %}.jinja} (100%) diff --git a/.github/assets/.copier-answers.yml b/.github/assets/.copier-answers.yml index e182ae7..47b22c3 100644 --- a/.github/assets/.copier-answers.yml +++ b/.github/assets/.copier-answers.yml @@ -2,6 +2,7 @@ _src_path: ./ author_email: 45483159+twsl@users.noreply.github.com author_username: twsl +copier_auto_update: true copyright_holder: twsl copyright_holder_email: 45483159+twsl@users.noreply.github.com copyright_license: MIT @@ -9,6 +10,7 @@ copyright_year: 2025 custom_install: true github_runner: - ubuntu-latest +github_runner_clean: false github_runner_python_version: - "3.11" include_databricks: false @@ -16,6 +18,8 @@ include_docs: true include_notebooks: true include_sample_code: false line_ending: lf +package_manager: uv +precommit_tool: prek primary_branch: main project_description: "The python description" project_name: example-project @@ -27,7 +31,5 @@ repository_name: example-project repository_namespace: twsl repository_provider: test.ghe.com self_signed: false +type_checker: ty use_precommit: true -precommit_tool: prek -copier_auto_update: true -github_runner_clean: false diff --git a/README.md b/README.md index 164f906..b85d0b3 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,17 @@ # Python Project Template [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-border.json)](https://github.com/copier-org/copier) -[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/) [![linting: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) -[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](.pre-commit-config.yaml) -[![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/) [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit) [![Semantic Versions](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--versions-e10079.svg)](https://github.com/twsl/python-project-template/releases) [![License](https://img.shields.io/badge/license-MIT-blue)](LICENSE) A generic python project template based on [`copier`](https://copier.readthedocs.io/en/stable/) for my data science focused projects. +- Package Manager: [![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv) or [![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/) +- pre-commit: [![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek) or [![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit) +- Type checker: [![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty) or [![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/) + ## TL;DR ```bash @@ -22,14 +23,16 @@ copier copy --trust --vcs-ref=HEAD git+https://github.com/twsl/python-project-te ### Development features - Supports `Python 3.10` and [higher](https://devguide.python.org/versions/). -- [`Poetry`](https://python-poetry.org/) as a dependencies manager. See configuration in `pyproject.toml`. +- [`uv`](https://github.com/astral-sh/uv) or [`Poetry`](https://python-poetry.org/) as a dependencies manager. See configuration in `pyproject.toml`. - Automatic codestyle with [`ruff`](https://github.com/astral-sh/ruff). -- Ready-to-use [`pre-commit`](https://pre-commit.com/) hooks with code-formatting. -- Type checks with [`pyright`](https://github.com/microsoft/pyright). +- Ready-to-use [`pre-commit`](https://pre-commit.com/) hooks with code-formatting. Execute with [`prek`](https://github.com/j178/prek) or [`pre-commit`](https://github.com/pre-commit/pre-commit) +- Type checks with [`ty`](https://github.com/astral-sh/ty) or [`pyright`](https://github.com/microsoft/pyright). - Security checks with [`bandit`](https://github.com/PyCQA/bandit). - Testing with [`pytest`](https://docs.pytest.org/en/latest/). - Ready-to-use `.editorconfig` and `.gitignore`. - Ready-to-use [`Devcontainer`](https://containers.dev/). +- Find dead code with [`vulture`](https://github.com/jendrikseipp/vulture). +- Avoid credential leaks with [`gitleaks`](https://github.com/gitleaks/gitleaks). ### Deployment features @@ -88,6 +91,9 @@ The template uses the following variables to customize the project: | `custom_install` | `customized` | | `project_name` | `example_project` | | `project_description` | `` | +| `repository_provider` | `github.com` | +| `ghec` | `false` | +| `ghes` | `false` | | `primary_branch` | `main` | | `author_username` | `` | | `author_email` | `{{ author_username }}@users.noreply.github.com` | @@ -96,32 +102,27 @@ The template uses the following variables to customize the project: | `repository_name` | `{{ project_name }}` | | `copyright_holder` | `{{ author_username }}` | | `copyright_holder_email` | `{{ author_email }}` | -| `copyright_year` | `2025` | +| `copyright_year` | `2026` | | `copyright_license` | `MIT` | -| `python_version` | `3.11` | +| `python_version` | `3.12` | | `python_package_distribution_name` | `{{ project_name }}` | | `python_package_import_name` | `{{ project_name }}` | | `python_package_command_line_name` | `{{ project_name }}` | | `line_ending` | `lf` | +| `package_manager` | `uv` | +| `type_checker` | `ty` | | `use_precommit` | `true` | | `precommit_tool` | `prek` | | `include_docs` | `true` | | `include_notebooks` | `true` | -| `include_databricks` | `true` | -| `github_runner_python_version` | `3.11` | +| `include_databricks` | `false` | +| `github_runner_python_version` | `[3.12]` | | `github_runner` | `ubuntu-latest` | | `github_runner_ghec` | `ubuntu-2core-amd64` | +| `github_runner_clean` | `true` | | `github_rate_limit` | `false` | | `include_sample_code` | `false` | | `self_signed` | `false` | +| `copier_auto_update` | `false` | All input values will be saved in the `.copier-answers.yml` - -## Credits - -I just combined multiple templates to create this one, therefore all credits belong to the following projects: - -- [poetry-copier](https://github.com/lukin0110/poetry-copier) -- [python-project-template](https://github.com/lincc-frameworks/python-project-template) -- [copier-poetry](https://github.com/pawamoy/copier-poetry) -- [python-package-template](https://github.com/TezRomacH/python-package-template) diff --git a/copier.yml b/copier.yml index 8da3dd0..1d7d4dd 100644 --- a/copier.yml +++ b/copier.yml @@ -113,7 +113,7 @@ copyright_holder_email: copyright_year: type: int help: The copyright year? - default: 2025 + default: 2026 when: "{{ custom_install }}" copyright_license: @@ -129,8 +129,8 @@ copyright_license: # https://devguide.python.org/versions/ python_version: type: str - help: What version of python are you targeting? - default: "3.11" + help: What version of python are you targeting? See https://devguide.python.org/versions/ + default: "3.12" choices: - "3.10" - "3.11" @@ -164,6 +164,24 @@ line_ending: LF: lf CLRF: crlf +package_manager: + type: str + help: Which Python package and project manager do you want to use? + default: uv + choices: + uv: uv + poetry: poetry + when: "{{ custom_install }}" + +type_checker: + type: str + help: Which Python type checker do you want to use? + default: ty + choices: + pyright: pyright + ty: ty + when: "{{ custom_install }}" + use_precommit: type: bool default: yes diff --git a/project/.devcontainer/Dockerfile.jinja b/project/.devcontainer/Dockerfile.jinja index 66e212c..41089c0 100644 --- a/project/.devcontainer/Dockerfile.jinja +++ b/project/.devcontainer/Dockerfile.jinja @@ -10,10 +10,17 @@ RUN python3 -m pip install --upgrade setuptools # Install poetry RUN pip install --upgrade pip - +{% if package_manager == 'poetry' %} ENV PATH="/etc/poetry/bin:$PATH" RUN curl -sSL {% if self_signed %}-k{% endif %} https://install.python-poetry.org | POETRY_HOME=/etc/poetry python - \ && poetry completions bash >> ~/.bash_completion \ && poetry config virtualenvs.create false \ - && poetry self add "poetry-dynamic-versioning[plugin]" + && poetry self add "poetry-dynamic-versioning[plugin]"{% elif package_manager == 'uv'%} +ENV PATH="/root/.local/bin/:$PATH" +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ + +# RUN curl -LsSf https://astral.sh/uv/install.sh | sh +RUN echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc \ + && echo 'eval "$(uvx --generate-shell-completion bash)"' >> ~/.bashrc{% endif %} + {% if self_signed %}RUN echo "--insecure" > ~/.curlrc{% endif %} diff --git a/project/.devcontainer/devcontainer.json.jinja b/project/.devcontainer/devcontainer.json.jinja index 3f89d90..b10971c 100644 --- a/project/.devcontainer/devcontainer.json.jinja +++ b/project/.devcontainer/devcontainer.json.jinja @@ -12,7 +12,8 @@ },{% if self_signed %} // https://github.com/microsoft/vscode-remote-release/issues/6092 "remoteEnv": { - "NODE_TLS_REJECT_UNAUTHORIZED": "0" + "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% if package_manager == 'uv'%} + "UV_SYSTEM_PYTHON": "1"{% endif %} },{% endif %} // Features to add to the dev container. More info: https://containers.dev/features. "features": { @@ -28,7 +29,8 @@ // Use 'forwardPorts' to make a list of ports inside the container available locally. // "forwardPorts": [], // Use 'postCreateCommand' to run commands after the container is created. - "postCreateCommand": "poetry install{% if use_precommit %}{% if precommit_tool == 'pre-commit' %} && pre-commit install{% elif precommit_tool == 'prek' %} && prek install{% endif %}{% endif %}", + "postCreateCommand": "{% if package_manager == 'poetry' %}poetry install{% elif package_manager == 'uv'%}uv sync --all-groups --all-extras{% endif %}", + "postStartCommand": "{% if use_precommit %}{% if precommit_tool == 'pre-commit' %}pre-commit install{% elif precommit_tool == 'prek' %}{% if package_manager == 'uv'%}uv tool install prek && {% endif %}prek install{% endif %}{% endif %}", // Configure tool-specific properties. "customizations": { // Configure properties specific to VS Code. @@ -45,7 +47,7 @@ "python.pythonPath": "/usr/local/bin/python", "python.envFile": "${workspaceFolder}/.env", "python.defaultInterpreterPath": "/usr/local/bin/python", - "python.languageServer": "Pylance", + "python.languageServer": {% if type_checker == 'pyright' %}"Pylance"{% elif type_checker == 'ty' %}"None"{% endif %}, "python.autoComplete.addBrackets": true, "python.analysis.autoImportCompletions": true, "python.analysis.completeFunctionParens": true, @@ -95,7 +97,7 @@ // Add the IDs of extensions you want installed when the container is created. "extensions": [ "ms-python.python", - "ms-python.vscode-pylance", + {% if type_checker == 'pyright' %}"ms-python.vscode-pylance"{% elif type_checker == 'ty' %}"astral-sh.ty"{% endif %}, "ms-toolsai.jupyter", "GitHub.copilot", "GitHub.copilot-chat", @@ -114,6 +116,7 @@ "njpwerner.autodocstring", "rodolphebarbanneau.python-docstring-highlighter", "mechatroner.rainbow-csv", + "oderwat.indent-rainbow", "uctakeoff.vscode-counter", "bierner.github-markdown-preview", "yahyabatulu.vscode-markdown-alert", diff --git a/project/.github/dependabot.yml.jinja b/project/.github/dependabot.yml.jinja index e7fc1d0..6a9c867 100644 --- a/project/.github/dependabot.yml.jinja +++ b/project/.github/dependabot.yml.jinja @@ -21,7 +21,7 @@ updates: interval: weekly allow: - dependency-type: all - open-pull-requests-limit: 50 + open-pull-requests-limit: 50{% if package_manager == 'poetry' %} - package-ecosystem: pip directory: / @@ -30,4 +30,13 @@ updates: allow: - dependency-type: production - dependency-type: development - open-pull-requests-limit: 50 + open-pull-requests-limit: 50{% elif package_manager == 'uv'%} + + - package-ecosystem: uv + directory: / + schedule: + interval: weekly + allow: + - dependency-type: production + - dependency-type: development + {% endif %} diff --git a/project/.github/workflows/build.yaml.jinja b/project/.github/workflows/build.yaml.jinja index ce19046..19d4183 100644 --- a/project/.github/workflows/build.yaml.jinja +++ b/project/.github/workflows/build.yaml.jinja @@ -35,13 +35,13 @@ jobs: fetch-depth: 0{% if github_runner_clean %} - name: Free Disk Space - uses: twsl/gha-free-disk-space@main{% endif %} + uses: twsl/gha-free-disk-space@v1{% endif %} {% raw %}- name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: python-version: ${{ matrix.python-version }} -# cache: 'poetry'{% endraw %} +# cache: 'poetry'{% endraw %}{% if package_manager == 'poetry' %} - name: Install Poetry uses: snok/install-poetry@v1 @@ -62,7 +62,16 @@ jobs: restore-keys: venv-${{ runner.os }}-${{ matrix.python-version }}-{% endraw %} - name: Install dependencies - run: poetry install --no-interaction --all-extras{% if use_precommit %}{% if precommit_tool == 'pre-commit' %} + run: poetry install --no-interaction --all-extras{% elif package_manager == 'uv'%} + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "**/uv.lock" + + - name: Install sdl dependencies + run: uv sync --all-groups --all-extras --no-interaction{%endif %}{% if use_precommit %}{% if precommit_tool == 'pre-commit' %} - name: Run pre-commit uses: pre-commit/action@v3.0.1 @@ -74,10 +83,13 @@ jobs: uses: j178/prek-action@v1 continue-on-error: true env: - SKIP: poetry-lock{% endif %}{% endif %} + SKIP: poetry-lock{% endif %}{% endif %}{% if package_manager == 'poetry'%} + + - name: Build dependencies + run: poetry build{% elif package_manager == 'uv'%} - name: Build dependencies - run: poetry build + run: uv build{% endif %} - name: Upload dist uses: actions/upload-artifact@v6 diff --git a/project/.github/workflows/release.yaml.jinja b/project/.github/workflows/release.yaml.jinja index 61aab5b..abe1eb3 100644 --- a/project/.github/workflows/release.yaml.jinja +++ b/project/.github/workflows/release.yaml.jinja @@ -19,12 +19,12 @@ jobs: fetch-depth: 0{% if github_runner_clean %} - name: Free Disk Space - uses: twsl/gha-free-disk-space@main{% endif %} + uses: twsl/gha-free-disk-space@v1{% endif %} {% raw %}- name: Set up Python ${{ env.python-version }} uses: actions/setup-python@v6 with: - python-version: ${{ env.python-version }}{% endraw %} + python-version: ${{ env.python-version }}{% endraw %}{% if package_manager == 'poetry' %} - name: Install Poetry uses: snok/install-poetry@v1 @@ -33,13 +33,16 @@ jobs: virtualenvs-in-project: true virtualenvs-path: .venv + - name: Add poetry to path + run: echo "$(poetry env info --path)/bin" >> $GITHUB_PATH + - name: Set up cache uses: actions/cache@v5 id: cached-poetry-dependencies {% raw %}with: path: .venv - key: venv-${{ runner.os }}-${{ env.python-version }}-${{ hashFiles('poetry.lock') }} - restore-keys: venv-${{ runner.os }}-${{ env.python-version }}-{% endraw %} + key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: venv-${{ runner.os }}-${{ matrix.python-version }}-{% endraw %} - name: Install dependencies run: poetry install --no-interaction --all-extras @@ -56,7 +59,19 @@ jobs: - name: Build run: | - poetry build + poetry build{% elif package_manager == 'uv'%} + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "**/uv.lock" + + - name: Install sdl dependencies + run: uv sync --all-groups --all-extras --no-interaction + + - name: Build dependencies + run: uv build{%endif %} - name: Upload artifacts uses: actions/upload-artifact@v6 diff --git a/project/.github/workflows/{% if copier_auto_update %}copier-delete-branch.yaml{% endif %}.jinja b/project/.github/workflows/{% if copier_auto_update %}copier-delete-branch.yaml{% endif %}.jinja index 1134d6a..7feedf5 100644 --- a/project/.github/workflows/{% if copier_auto_update %}copier-delete-branch.yaml{% endif %}.jinja +++ b/project/.github/workflows/{% if copier_auto_update %}copier-delete-branch.yaml{% endif %}.jinja @@ -1,4 +1,4 @@ -name: Delete Copier PR branch on close +name: Copier PR Clean on: pull_request: diff --git a/project/.github/workflows/{% if copier_auto_update %}copier.yaml{% endif %}.jinja b/project/.github/workflows/{% if copier_auto_update %}copier.yaml{% endif %}.jinja index 53b3adc..8f5266e 100644 --- a/project/.github/workflows/{% if copier_auto_update %}copier.yaml{% endif %}.jinja +++ b/project/.github/workflows/{% if copier_auto_update %}copier.yaml{% endif %}.jinja @@ -33,7 +33,7 @@ jobs: {% raw %}- name: Set up Python ${{ env.python-version }} uses: actions/setup-python@v6 with: - python-version: ${{ env.python-version }}{% endraw %} + python-version: ${{ env.python-version }}{% endraw %}{% if package_manager == 'poetry' %} - name: Install Poetry uses: snok/install-poetry@v1 @@ -50,15 +50,39 @@ jobs: id: cached-poetry-dependencies {% raw %}with: path: .venv - key: venv-${{ runner.os }}-${{ env.python-version }}-${{ hashFiles('poetry.lock') }} - restore-keys: venv-${{ runner.os }}-${{ env.python-version }}-{% endraw %} + key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: venv-${{ runner.os }}-${{ matrix.python-version }}-{% endraw %} - name: Install dependencies run: poetry install --no-interaction --all-extras + - name: Check poetry + run: | + poetry check + + - name: Build + run: | + poetry build + + - name: Run copier update + id: run-update + run: poetry run copier update --trust -A --vcs-ref=HEAD{% elif package_manager == 'uv'%} + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "**/uv.lock" + + - name: Install sdl dependencies + run: uv sync --all-groups --all-extras --no-interaction + + - name: Build dependencies + run: uv build + - name: Run copier update id: run-update - run: poetry run copier update --trust -A --vcs-ref=HEAD + run: uv run copier update --trust -A --vcs-ref=HEAD{%endif %} {% raw %}- name: Resolve conflicts with incoming changes run: | diff --git a/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja b/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja index c033386..069aeef 100644 --- a/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja +++ b/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja @@ -38,7 +38,7 @@ jobs: {% raw %}- name: Set up Python ${{ env.python-version }} uses: actions/setup-python@v6 with: - python-version: ${{ env.python-version }}{% endraw %} + python-version: ${{ env.python-version }}{% endraw %}{% if package_manager == 'poetry' %} - name: Install Poetry uses: snok/install-poetry@v1 @@ -47,24 +47,55 @@ jobs: virtualenvs-in-project: true virtualenvs-path: .venv + - name: Add poetry to path + run: echo "$(poetry env info --path)/bin" >> $GITHUB_PATH + - name: Set up cache uses: actions/cache@v5 id: cached-poetry-dependencies {% raw %}with: path: .venv - key: venv-${{ runner.os }}-${{ env.python-version }}-${{ hashFiles('poetry.lock') }} - restore-keys: venv-${{ runner.os }}-${{ env.python-version }}-{% endraw %} + key: venv-${{ runner.os }}-${{ matrix.python-version }}-${{ hashFiles('poetry.lock') }} + restore-keys: venv-${{ runner.os }}-${{ matrix.python-version }}-{% endraw %} - name: Install dependencies run: poetry install --no-interaction --all-extras + - name: Dynamic versioning + run: poetry self add "poetry-dynamic-versioning[plugin]" + + - name: Enable dynamic versioning + run: poetry dynamic-versioning enable + + - name: Check poetry + run: | + poetry check + + - name: Build + run: | + poetry build + + - name: Build MkDocs docs + env: + JUPYTER_PLATFORM_DIRS: 1 + run: poetry run mkdocs build -f ./mkdocs.yml -d ./_build/{% elif package_manager == 'uv'%} + + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + enable-cache: true + cache-dependency-glob: "**/uv.lock" + + - name: Install sdl dependencies + run: uv sync --all-groups --all-extras --no-interaction + - name: Build dependencies - run: poetry build + run: uv build - name: Build MkDocs docs env: JUPYTER_PLATFORM_DIRS: 1 - run: poetry run mkdocs build -f ./docs/mkdocs.yml -d ./_build/ + run: uv run mkdocs build -f ./mkdocs.yml -d ./_build/{%endif %} - name: Upload build artifacts uses: actions/upload-artifact@v6 diff --git a/project/README.md.jinja b/project/README.md.jinja index 0482bd6..b284835 100644 --- a/project/README.md.jinja +++ b/project/README.md.jinja @@ -4,10 +4,10 @@ [![Build](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/actions/workflows/build.yaml/badge.svg)](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/actions/workflows/build.yaml){% if include_docs %} [![Documentation](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/actions/workflows/docs.yaml/badge.svg)](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/actions/workflows/docs.yaml) [![Docs with MkDocs](https://img.shields.io/badge/MkDocs-docs?style=flat&logo=materialformkdocs&logoColor=white&color=%23526CFE)](https://squidfunk.github.io/mkdocs-material/){% endif %} -[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/) +{% if package_manager == 'poetry' %}[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/){% elif package_manager == 'uv'%}[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv){% endif %} [![linting: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff){% if use_precommit %} -[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](.pre-commit-config.yaml){% endif %} -[![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/) +{% if precommit_tool == 'pre-commit' %}[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit){% elif precommit_tool == 'prek' %}[![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek){% endif %}{% endif %} +{% if type_checker == 'pyright' %}[![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/){% elif type_checker == 'ty' %}[![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty){% endif %} [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit) [![Semantic Versions](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--versions-e10079.svg)](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/releases) [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-border.json)](https://github.com/copier-org/copier) @@ -28,12 +28,17 @@ With `pip`: ```bash python -m pip install {{ python_package_distribution_name }} ``` - -With [`poetry`](https://python-poetry.org/): +{% if package_manager == 'poetry' %} +With [`poetry`](https://python-poetry.org/docs/): ```bash poetry add {{ python_package_distribution_name }} ``` - +{% elif package_manager == 'uv'%} +With [`uv`](https://docs.astral.sh/uv/): +```bash +uv add {{ python_package_distribution_name }} +``` +{% endif %} ## How to use it @@ -45,11 +50,15 @@ import {{ python_package_import_name }} {% if include_docs %}## Docs - +{% if package_manager == 'poetry' %} ```bash -poetry run mkdocs build -f ./docs/mkdocs.yml -d ./_build/ +poetry run mkdocs build -f ./mkdocs.yml -d ./_build/ ``` - +{% elif package_manager == 'uv'%} +```bash +uv tool run mkdocs build -f ./mkdocs.yml -d ./_build/ +``` +{% endif %} {% endif %} ## Update template @@ -59,4 +68,4 @@ copier update --trust -A --vcs-ref=HEAD ## Credits -This project was generated with [![🚀 A generic python project template.](https://img.shields.io/badge/python--project--template-%F0%9F%9A%80-brightgreen)](https://github.com/twsl/python-project-template) +This project was generated with [![🚀 python project template.](https://img.shields.io/badge/python--project--template-%F0%9F%9A%80-brightgreen)](https://github.com/twsl/python-project-template) diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index e246c07..27ac6c1 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -1,7 +1,9 @@ -[build-system] +[build-system]{% if package_manager == 'poetry' %} requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"] -build-backend = "poetry_dynamic_versioning.backend" - +build-backend = "poetry_dynamic_versioning.backend"{% elif package_manager == 'uv'%} +requires = ["hatchling", "uv-dynamic-versioning"] +build-backend = "hatchling.build" +{% endif %} [project] name = "{{ python_package_distribution_name }}" version = "0.0.0" @@ -15,82 +17,94 @@ authors = [ keywords = [ "{{ python_package_distribution_name }}" ] +classifiers = [ +] dynamic = [ - "classifiers", - "dependencies" + "version" +] +dependencies = [{% if include_sample_code %} + "torch>=2.9.1" + "lightning>=2.6.0"{% endif %} ] +[project.optional-dependencies] +extra = [] + [project.urls] homepage = {% if repository_provider == "github.com"%}"https://{{ repository_namespace }}.github.io/{{ repository_name }}/"{% else %}"https://pages.{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}"{% endif %} repository = "https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}" documentation = {% if repository_provider == "github.com"%}"https://{{ repository_namespace }}.github.io/{{ repository_name }}/"{% else %}"https://pages.{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}"{% endif %} -[tool.poetry] +{% if package_manager == 'poetry' %}[tool.poetry] packages = [ { include = "{{ python_package_import_name }}", from = "src" } ] -classifiers = [ -] [tool.poetry.dependencies] -python = "^{{ python_version }}"{% if include_sample_code %} -torch = "^2.9.1" -lightning = "^2.6.0"{% endif %} - -[tool.poetry.group.dev.dependencies] -ruff = "^0.14.13" -bandit = "^1.9.3"{% if use_precommit %} -{% if precommit_tool == 'pre-commit' %}pre-commit = "^4.5.0"{% elif precommit_tool == 'prek' %}prek = "^0.2.30"{% endif %}{% endif %} -pyright = "^1.1.408" -vulture = "^2.14" -copier = "^9.11.1" -{% if include_notebooks %}ipykernel = "^6.31.0" -ipywidgets = "^8.1.8" -ipython = "^9.9.0" -jupytext = "^1.18.1" -nbconvert = "^7.16.6"{% endif %} - -[tool.poetry.group.test.dependencies] -pytest = "^9.0.2" -pytest-cov = "^7.0.0" -pytest-mock = "^3.15.1" -pytest-cases = "^3.9.1" -pytest-benchmark = {extras = ["aspect","histogram"], version = "^5.2.3"} -pytest-github-actions-annotate-failures = "^0.3.0" - -{% if include_docs %}[tool.poetry.group.docs.dependencies] -mkdocs = "^1.6.1" -mkdocs-material = "^9.7.1" -mkdocs-git-revision-date-localized-plugin = "^1.5.0" -mkdocs-awesome-nav = "^3.3.0" -mkdocs-git-authors-plugin = "^0.10.0" -mkapi = "^4.5.0" -markdown-callouts = "^0.4.0" -pymdown-extensions = "^10.20" -pygments = "^2.19.0"{% if include_notebooks %} -mkdocs-jupyter = "^0.25.1"{% endif %}{% endif %} - -[tool.poetry.group.debug] -optional = true - -[tool.poetry.group.debug.dependencies] -ipdb = "^0.13.9" -line_profiler = "^5.0.0" +python = "^{{ python_version }}" +{% elif package_manager == 'uv'%}[tool.uv] +default-groups = [ + "dev", + "spark", + "test",{% if include_docs %} + "docs",{% endif %} + "debug" +]{% endif %} + +[dependency-groups] +dev = [ + "ruff>=0.14.13", + {% if type_checker == 'pyright' %}"pyright>=1.1.408"{% elif type_checker == 'ty' %}"ty>=0.0.12"{% endif %}, + "bandit>=1.9.3",{% if use_precommit %} + {% if precommit_tool == 'pre-commit' %}"pre-commit>=4.5.0"{% elif precommit_tool == 'prek' %}"prek>=0.2.30"{% endif %},{% endif %} + "vulture>=2.14", + "copier>=9.11.1",{% if include_notebooks %} + "ipykernel>=6.31.0", + "ipywidgets>=8.1.8", + "ipython>=9.9.0", + "jupytext>=1.18.1", + "nbconvert>=7.16.6",{% endif %} +] +test = [ + "pytest>=9.0.2", + "pytest-cov>=7.0.0", + "pytest-mock>=3.15.1", + "pytest-cases>=3.9.1", + "pytest-benchmark[aspect,histogram]>=5.2.3", + "pytest-github-actions-annotate-failures>=0.3.0", +]{% if include_docs %} +docs = [ + "mkdocs>=1.6.1", + "mkdocs-material>=9.7.1", + "mkdocs-git-revision-date-localized-plugin>=1.5.0", + "mkdocs-awesome-nav>=3.3.0", + "mkdocs-git-authors-plugin>=0.10.0", + "mkapi>=4.5.0", + "markdown-callouts>=0.4.0", + "pymdown-extensions>=10.20", + "pygments>=2.19.0",{% if include_notebooks %} + "mkdocs-jupyter>=0.25.1",{% endif %} +]{% endif %} +debug = [ + "ipdb>=0.13.9", + "line-profiler>=5.0.0", +] [project.scripts] {{ python_package_command_line_name }} = "{{ python_package_import_name }}.cli:main" +{% if package_manager == 'poetry' %}[tool.poetry-dynamic-versioning.substitution] +folders = [ + { path = "src/{{ python_package_import_name }}" } +] + +# https://github.com/mtkennerly/poetry-dynamic-versioning [tool.poetry-dynamic-versioning] enable = false vcs = "git" style = "semver" pattern = "default-unprefixed" -[tool.poetry-dynamic-versioning.substitution] -folders = [ - { path = "src/{{ python_package_import_name }}" } -] - [tool.poetry-dynamic-versioning.files."src/{{ python_package_import_name }}/__about__.py"] persistent-substitution = false initial-content = """ @@ -99,6 +113,37 @@ initial-content = """ __version__ = "0.0.0" __version_tuple__ = (0, 0, 0) """ +{% elif package_manager == 'uv'%}[tool.hatch.build.targets.sdist] +include = ["src/{{ python_package_import_name }}"] + +[tool.hatch.build.targets.wheel] +include = ["src/{{ python_package_import_name }}"] + +[tool.hatch.build.targets.wheel.sources] +"src/{{ python_package_import_name }}" = "{{ python_package_import_name }}" + +[tool.hatch.version] +source = "uv-dynamic-versioning" + +[tool.uv-dynamic-versioning.substitution] +folders = [ + { path = "src/{{ python_package_import_name }}" } +] + +# https://github.com/ninoseki/uv-dynamic-versioning +[tool.uv-dynamic-versioning] +vcs = "git" +style = "semver" +pattern = "default-unprefixed" +fallback-version = "1.0.0" + +[tool.hatch.build.hooks.version] +path = "src/{{ python_package_import_name }}/__about__.py" +template = ''' +__version__ = "{version}" +''' +{% endif %} + [tool.pytest.ini_options] minversion = "8.0" diff --git a/project/{% if include_docs %}docs{% endif %}/docs/index.md b/project/{% if include_docs %}docs{% endif %}/index.md similarity index 100% rename from project/{% if include_docs %}docs{% endif %}/docs/index.md rename to project/{% if include_docs %}docs{% endif %}/index.md diff --git a/project/{% if include_docs %}docs{% endif %}/docs/styles/extra.css b/project/{% if include_docs %}docs{% endif %}/styles/extra.css similarity index 100% rename from project/{% if include_docs %}docs{% endif %}/docs/styles/extra.css rename to project/{% if include_docs %}docs{% endif %}/styles/extra.css diff --git a/project/{% if include_docs %}docs{% endif %}/docs/{% if include_notebooks %}notebooks{% endif %}/index.md b/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md similarity index 100% rename from project/{% if include_docs %}docs{% endif %}/docs/{% if include_notebooks %}notebooks{% endif %}/index.md rename to project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md diff --git a/project/{% if include_docs %}docs{% endif %}/docs/{% if include_notebooks %}notebooks{% endif %}/intro_notebook.ipynb b/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/intro_notebook.ipynb similarity index 100% rename from project/{% if include_docs %}docs{% endif %}/docs/{% if include_notebooks %}notebooks{% endif %}/intro_notebook.ipynb rename to project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/intro_notebook.ipynb diff --git a/project/{% if include_docs %}docs{% endif %}/mkdocs.yml.jinja b/project/{% if include_docs %}mkdocs.yml{% endif %}.jinja similarity index 100% rename from project/{% if include_docs %}docs{% endif %}/mkdocs.yml.jinja rename to project/{% if include_docs %}mkdocs.yml{% endif %}.jinja diff --git a/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja b/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja index 69d35e8..e39c0b7 100644 --- a/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja +++ b/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja @@ -14,12 +14,16 @@ repos: rev: v0.9.0 hooks: - id: pre-commit-update - +{% if package_manager == 'poetry' %} - repo: https://github.com/python-poetry/poetry rev: 2.2.1 hooks: - id: poetry-lock - - id: poetry-check + - id: poetry-check{% elif package_manager == 'uv'%} + - repo: https://github.com/astral-sh/uv-pre-commit + rev: 0.9.25 + hooks: + - id: uv-lock{% endif %} - repo: https://github.com/pre-commit/pre-commit-hooks rev: v6.0.0 @@ -63,7 +67,7 @@ repos: - id: ruff-check args: [--fix, -v] - id: ruff-format - +{% if type_checker == 'pyright' %} - repo: https://github.com/RobertCraigie/pyright-python rev: v1.1.408 hooks: @@ -71,7 +75,11 @@ repos: args: [--verbose, --project=.] entry: poetry run pyright language: system - types: [python] + types: [python]{% elif type_checker == 'ty' %} + - repo: https://github.com/allganize/ty-pre-commit + rev: v0.0.12 + hooks: + - id: ty-check{% endif %} - repo: https://github.com/jendrikseipp/vulture rev: v2.14 From ecbce05a3322640b46e9114705c33e6e7b5e31f1 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:01:27 +0000 Subject: [PATCH 02/16] Add mkdocs badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index b85d0b3..3ca8df4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ # Python Project Template [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-border.json)](https://github.com/copier-org/copier) +[![Docs with MkDocs](https://img.shields.io/badge/MkDocs-docs?style=flat&logo=materialformkdocs&logoColor=white&color=%23526CFE)](https://squidfunk.github.io/mkdocs-material/) [![linting: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit) [![Semantic Versions](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--versions-e10079.svg)](https://github.com/twsl/python-project-template/releases) From ae2790514eab6f0e2ac0b3c51067368ea6c6f4cf Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:15:48 +0000 Subject: [PATCH 03/16] Enhance Dockerfile and CI configuration for UV integration; add .copier-answers files for UV and Poetry --- .devcontainer/Dockerfile | 10 +++++- .github/assets/.copier-answers-poetry.yml | 35 +++++++++++++++++++ ...ier-answers.yml => .copier-answers-uv.yml} | 4 +-- .github/workflows/build.yaml | 5 +-- README.md | 6 +++- project/.devcontainer/Dockerfile.jinja | 6 ++-- project/pyproject.toml.jinja | 4 +-- 7 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 .github/assets/.copier-answers-poetry.yml rename .github/assets/{.copier-answers.yml => .copier-answers-uv.yml} (96%) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 2717b6b..158ca63 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -8,11 +8,19 @@ FROM mcr.microsoft.com/devcontainers/python:1-${VARIANT} # They are installed by the base image (python) which does not have the patch. RUN python3 -m pip install --upgrade setuptools -# Install poetry RUN pip install --upgrade pip +# Install poetry ENV PATH "/etc/poetry/bin:$PATH" RUN curl -sSLk https://install.python-poetry.org | POETRY_HOME=/etc/poetry python - \ && poetry completions bash >> ~/.bash_completion \ && poetry config virtualenvs.create false \ && poetry self add "poetry-dynamic-versioning[plugin]" + +# Install uv +ENV PATH="/root/.local/bin/:$PATH" +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ + +# RUN curl -sSLkf https://astral.sh/uv/install.sh | sh +RUN echo 'eval "$(uv generate-shell-completion bash)"' >> ~/.bashrc \ + && echo 'eval "$(uvx --generate-shell-completion bash)"' >> ~/.bashrc \ No newline at end of file diff --git a/.github/assets/.copier-answers-poetry.yml b/.github/assets/.copier-answers-poetry.yml new file mode 100644 index 0000000..772e593 --- /dev/null +++ b/.github/assets/.copier-answers-poetry.yml @@ -0,0 +1,35 @@ +# Changes here will be overwritten by Copier; NEVER EDIT MANUALLY +_src_path: ./ +author_email: 45483159+twsl@users.noreply.github.com +author_username: twsl +copier_auto_update: true +copyright_holder: twsl +copyright_holder_email: 45483159+twsl@users.noreply.github.com +copyright_license: MIT +copyright_year: 2025 +custom_install: true +github_runner: + - ubuntu-latest +github_runner_clean: false +github_runner_python_version: + - "3.12" +include_databricks: false +include_docs: true +include_notebooks: true +include_sample_code: false +line_ending: lf +package_manager: poetry +precommit_tool: pre-commit +primary_branch: main +project_description: "The python description" +project_name: example-project +python_package_command_line_name: example-project +python_package_distribution_name: example-project +python_package_import_name: example_project +python_version: "3.12" +repository_name: example-project +repository_namespace: twsl +repository_provider: test.ghe.com +self_signed: false +type_checker: pyright +use_precommit: true diff --git a/.github/assets/.copier-answers.yml b/.github/assets/.copier-answers-uv.yml similarity index 96% rename from .github/assets/.copier-answers.yml rename to .github/assets/.copier-answers-uv.yml index 47b22c3..c6af59a 100644 --- a/.github/assets/.copier-answers.yml +++ b/.github/assets/.copier-answers-uv.yml @@ -12,7 +12,7 @@ github_runner: - ubuntu-latest github_runner_clean: false github_runner_python_version: - - "3.11" + - "3.12" include_databricks: false include_docs: true include_notebooks: true @@ -26,7 +26,7 @@ project_name: example-project python_package_command_line_name: example-project python_package_distribution_name: example-project python_package_import_name: example_project -python_version: "3.11" +python_version: "3.12" repository_name: example-project repository_namespace: twsl repository_provider: test.ghe.com diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 1f665b1..d8c7e60 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,6 +13,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] + answers_file: [".copier-answers-uv.yml", ".copier-answers-poetry.yml"] defaults: run: shell: bash @@ -50,12 +51,12 @@ jobs: run: poetry install --no-interaction - name: Test - run: poetry run copier copy ./ ./dist --data-file "./.github/assets/.copier-answers.yml" -f --vcs-ref=HEAD + run: poetry run copier copy ./ ./dist --data-file "./.github/assets/${{ matrix.answers_file }}" -f --vcs-ref=HEAD - name: Upload artifacts uses: actions/upload-artifact@v6 with: - name: copier-results-${{ runner.os }} + name: copier-results-${{ runner.os }}-${{ matrix.answers_file }} path: ./dist/**/* include-hidden-files: true if: ${{ always() }} diff --git a/README.md b/README.md index 3ca8df4..59e7540 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,11 @@ A generic python project template based on [`copier`](https://copier.readthedocs ## TL;DR ```bash -copier copy --trust --vcs-ref=HEAD git+https://github.com/twsl/python-project-template path/to/destination +pip install copier +``` + +```bash +copier copy --trust --vcs-ref=HEAD git+https://github.com/twsl/python-project-template /path/to/destination ``` ## Features diff --git a/project/.devcontainer/Dockerfile.jinja b/project/.devcontainer/Dockerfile.jinja index 41089c0..f9facf5 100644 --- a/project/.devcontainer/Dockerfile.jinja +++ b/project/.devcontainer/Dockerfile.jinja @@ -8,14 +8,16 @@ FROM mcr.microsoft.com/devcontainers/python:1-${VARIANT} # They are installed by the base image (python) which does not have the patch. RUN python3 -m pip install --upgrade setuptools +RUN pip install --upgrade pip{% if package_manager == 'poetry' %} + # Install poetry -RUN pip install --upgrade pip -{% if package_manager == 'poetry' %} ENV PATH="/etc/poetry/bin:$PATH" RUN curl -sSL {% if self_signed %}-k{% endif %} https://install.python-poetry.org | POETRY_HOME=/etc/poetry python - \ && poetry completions bash >> ~/.bash_completion \ && poetry config virtualenvs.create false \ && poetry self add "poetry-dynamic-versioning[plugin]"{% elif package_manager == 'uv'%} + +# Install uv ENV PATH="/root/.local/bin/:$PATH" COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index 27ac6c1..9685f4e 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -141,9 +141,7 @@ fallback-version = "1.0.0" path = "src/{{ python_package_import_name }}/__about__.py" template = ''' __version__ = "{version}" -''' -{% endif %} - +'''{% endif %} [tool.pytest.ini_options] minversion = "8.0" From 07bf8f1bbab0343d47fa015363adab3e10b06fc1 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:17:31 +0000 Subject: [PATCH 04/16] Refactor build workflow to use answers_variant for Copier configuration --- .github/workflows/build.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index d8c7e60..6a3a3f5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -13,7 +13,7 @@ jobs: fail-fast: true matrix: os: [ubuntu-latest, windows-latest] - answers_file: [".copier-answers-uv.yml", ".copier-answers-poetry.yml"] + answers_variant: ["uv", "poetry"] defaults: run: shell: bash @@ -51,12 +51,12 @@ jobs: run: poetry install --no-interaction - name: Test - run: poetry run copier copy ./ ./dist --data-file "./.github/assets/${{ matrix.answers_file }}" -f --vcs-ref=HEAD + run: poetry run copier copy ./ ./dist --data-file "./.github/assets/.copier-answers-${{ matrix.answers_variant }}.yml" -f --vcs-ref=HEAD - name: Upload artifacts uses: actions/upload-artifact@v6 with: - name: copier-results-${{ runner.os }}-${{ matrix.answers_file }} + name: copier-results-${{ runner.os }}-${{ matrix.answers_variant }} path: ./dist/**/* include-hidden-files: true if: ${{ always() }} From be26bda34d555f67ad764eb67e5c95349c4729d2 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:59:12 +0000 Subject: [PATCH 05/16] Remove wrong group --- project/pyproject.toml.jinja | 1 - 1 file changed, 1 deletion(-) diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index 9685f4e..8da14c0 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -45,7 +45,6 @@ python = "^{{ python_version }}" {% elif package_manager == 'uv'%}[tool.uv] default-groups = [ "dev", - "spark", "test",{% if include_docs %} "docs",{% endif %} "debug" From f864408cafe7689fea6dace6c8b01cb4f19f7548 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:09:09 +0000 Subject: [PATCH 06/16] Fix dynamic version --- project/pyproject.toml.jinja | 19 ++++++++++++------- .../__about__.py | 6 ++---- .../__init__.py.jinja | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index 8da14c0..cc83fcc 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -6,7 +6,6 @@ build-backend = "hatchling.build" {% endif %} [project] name = "{{ python_package_distribution_name }}" -version = "0.0.0" requires-python = ">={{ python_version }}" description = "{{ project_description }}" readme = "README.md"{% if copyright_license != 'none' %} @@ -36,6 +35,7 @@ repository = "https://{{ repository_provider }}/{{ repository_namespace }}/{{ re documentation = {% if repository_provider == "github.com"%}"https://{{ repository_namespace }}.github.io/{{ repository_name }}/"{% else %}"https://pages.{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}"{% endif %} {% if package_manager == 'poetry' %}[tool.poetry] +version = "0.0.0" packages = [ { include = "{{ python_package_import_name }}", from = "src" } ] @@ -92,9 +92,15 @@ debug = [ [project.scripts] {{ python_package_command_line_name }} = "{{ python_package_import_name }}.cli:main" -{% if package_manager == 'poetry' %}[tool.poetry-dynamic-versioning.substitution] +{% if package_manager == 'poetry' %}[tool.poetry.requires-plugins] +poetry-dynamic-versioning = { version = ">=1.0.0,<2.0.0", extras = ["plugin"] } + +[tool.poetry-dynamic-versioning.substitution] folders = [ - { path = "src/{{ python_package_import_name }}" } + { path = "src/{{ python_package_import_name }}" } +] +patterns = [ + '''(^__version__\s*(?::.*?)?=\s*['"])[^'"]*(['"])''', ] # https://github.com/mtkennerly/poetry-dynamic-versioning @@ -107,10 +113,8 @@ pattern = "default-unprefixed" [tool.poetry-dynamic-versioning.files."src/{{ python_package_import_name }}/__about__.py"] persistent-substitution = false initial-content = """ -# file generated by poetry dynamic versioning during poetry build/install -# don't change, don't track in version control -__version__ = "0.0.0" -__version_tuple__ = (0, 0, 0) +# file generated by dynamic versioning during build when enabled +__version__ = "1.0.0" """ {% elif package_manager == 'uv'%}[tool.hatch.build.targets.sdist] include = ["src/{{ python_package_import_name }}"] @@ -139,6 +143,7 @@ fallback-version = "1.0.0" [tool.hatch.build.hooks.version] path = "src/{{ python_package_import_name }}/__about__.py" template = ''' +# file generated by dynamic versioning during build when enabled __version__ = "{version}" '''{% endif %} diff --git a/project/src/{{python_package_import_name}}/__about__.py b/project/src/{{python_package_import_name}}/__about__.py index ff591c8..162df37 100644 --- a/project/src/{{python_package_import_name}}/__about__.py +++ b/project/src/{{python_package_import_name}}/__about__.py @@ -1,4 +1,2 @@ -# file generated by poetry dynamic versioning during poetry build/install -# don't change, don't track in version control -__version__ = "0.0.0" -__version_tuple__ = (0, 0, 0) +# file generated by dynamic versioning during build when enabled +__version__ = "1.0.0" diff --git a/project/src/{{python_package_import_name}}/__init__.py.jinja b/project/src/{{python_package_import_name}}/__init__.py.jinja index 1536cd4..da2f1f0 100644 --- a/project/src/{{python_package_import_name}}/__init__.py.jinja +++ b/project/src/{{python_package_import_name}}/__init__.py.jinja @@ -1 +1 @@ -from {{ python_package_import_name }}.__about__ import __version__, __version_tuple__ +from {{ python_package_import_name }}.__about__ import __version__ From 5dc89cd570b610e4c11170fe38ea38238dda1f46 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:10:28 +0000 Subject: [PATCH 07/16] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 59e7540..593f543 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,11 @@ The devcontainer is already set up for you, just open the project in VSCode and To test the project you can run: ```bash -copier copy ./ ./dist --data-file "./.github/assets/.copier-answers.yml" -f --vcs-ref=HEAD +copier copy ./ ./dist --data-file "./.github/assets/.copier-answers-uv.yml" -f --vcs-ref=HEAD +``` + +```bash +copier copy ./ ./dist --data-file "./.github/assets/.copier-answers-poetry.yml" -f --vcs-ref=HEAD ``` ### Variables From d4f856194e4ab30b5b38dc4e3f9866f4df85c356 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:17:12 +0000 Subject: [PATCH 08/16] Fix remove env --- project/.devcontainer/devcontainer.json.jinja | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/project/.devcontainer/devcontainer.json.jinja b/project/.devcontainer/devcontainer.json.jinja index b10971c..49ee46c 100644 --- a/project/.devcontainer/devcontainer.json.jinja +++ b/project/.devcontainer/devcontainer.json.jinja @@ -9,12 +9,12 @@ "args": { "VARIANT": "{{ python_version }}-bookworm" } - },{% if self_signed %} - // https://github.com/microsoft/vscode-remote-release/issues/6092 + }, "remoteEnv": { - "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% if package_manager == 'uv'%} + {% if self_signed %}// https://github.com/microsoft/vscode-remote-release/issues/6092 + "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% endif %}{% if package_manager == 'uv'%} "UV_SYSTEM_PYTHON": "1"{% endif %} - },{% endif %} + }, // Features to add to the dev container. More info: https://containers.dev/features. "features": { "ghcr.io/devcontainers/features/git:1": {}, From 73104d326a481f94c7df5757f4a8815d22a90f5e Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:37:56 +0000 Subject: [PATCH 09/16] Set static version by default in dev container --- project/.devcontainer/devcontainer.json.jinja | 8 ++++++-- project/pyproject.toml.jinja | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/project/.devcontainer/devcontainer.json.jinja b/project/.devcontainer/devcontainer.json.jinja index 49ee46c..7fbdbe0 100644 --- a/project/.devcontainer/devcontainer.json.jinja +++ b/project/.devcontainer/devcontainer.json.jinja @@ -12,8 +12,12 @@ }, "remoteEnv": { {% if self_signed %}// https://github.com/microsoft/vscode-remote-release/issues/6092 - "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% endif %}{% if package_manager == 'uv'%} - "UV_SYSTEM_PYTHON": "1"{% endif %} + "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% endif %}{% if package_manager == 'poetry' %} + "POETRY_DYNAMIC_VERSIONING_BYPASS": "1.0.0"{% elif package_manager == 'uv'%} + "UV_SYSTEM_PYTHON": "1", + "UV_PROJECT_ENVIRONMENT": "/usr/local", + // Disable dynamic versioning during development + "UV_DYNAMIC_VERSIONING_BYPASS": "1.0.0"{% endif %} }, // Features to add to the dev container. More info: https://containers.dev/features. "features": { diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index cc83fcc..bc6091c 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -130,7 +130,7 @@ source = "uv-dynamic-versioning" [tool.uv-dynamic-versioning.substitution] folders = [ - { path = "src/{{ python_package_import_name }}" } + { path = "src/{{ python_package_import_name }}" } ] # https://github.com/ninoseki/uv-dynamic-versioning From 42e8375afb0aae0afd1fa00a4316c741412f6690 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:46:04 +0000 Subject: [PATCH 10/16] Update pyright/ty config --- project/pyproject.toml.jinja | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index bc6091c..732031c 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -281,13 +281,18 @@ quote-style = "double" [tool.bandit.assert_used] skips = ['*_test.py', '*/test_*.py'] - +{% if type_checker == 'pyright' %} [tool.pyright] pythonVersion = "{{ python_version }}" pythonPlatform = "Linux" include = ["src"] reportMissingImports = true -reportMissingTypeStubs = false +reportMissingTypeStubs = false{% elif type_checker == 'ty' %} +[tool.ty.environment] +python-version = "{{ python_version }}" +python-platform = "linux" +root = ["./src"] +{% endif %} [tool.pre-commit-update.yaml] mapping = 2 From 4a7a59e33838c54bbfe487cbd17a9115d04b7ec0 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 14:51:19 +0000 Subject: [PATCH 11/16] Update vscode settings --- project/.devcontainer/devcontainer.json.jinja | 3 --- project/.vscode/extensions.json.jinja | 3 ++- project/.vscode/{settings.json => settings.json.jinja} | 7 ++----- 3 files changed, 4 insertions(+), 9 deletions(-) rename project/.vscode/{settings.json => settings.json.jinja} (89%) diff --git a/project/.devcontainer/devcontainer.json.jinja b/project/.devcontainer/devcontainer.json.jinja index 7fbdbe0..814cb9b 100644 --- a/project/.devcontainer/devcontainer.json.jinja +++ b/project/.devcontainer/devcontainer.json.jinja @@ -60,7 +60,6 @@ "python.analysis.inlayHints.variableTypes": true, "python.analysis.inlayHints.functionReturnTypes": true, "python.analysis.diagnosticMode": "workspace", - "python.analysis.typeCheckingMode": "strict", "python.sortImports": true, "python.testing.autoTestDiscoverOnSaveEnabled": false, "python.testing.unittestEnabled": false, @@ -84,8 +83,6 @@ "notebook.source.fixAll": "explicit", "notebook.source.organizeImports": "explicit" }, - "testExplorer.codeLens": true, - "testExplorer.gutterDecoration": true, "git.enableSmartCommit": true, "git.autofetch": true, "autoDocstring.docstringFormat": "google-notypes", diff --git a/project/.vscode/extensions.json.jinja b/project/.vscode/extensions.json.jinja index 542e7c5..99e20af 100644 --- a/project/.vscode/extensions.json.jinja +++ b/project/.vscode/extensions.json.jinja @@ -1,7 +1,7 @@ { "recommendations": [ "ms-python.python", - "ms-python.vscode-pylance", + {% if type_checker == 'pyright' %}"ms-python.vscode-pylance"{% elif type_checker == 'ty' %}"astral-sh.ty"{% endif %}, "ms-toolsai.jupyter", "GitHub.copilot", "GitHub.copilot-chat", @@ -20,6 +20,7 @@ "njpwerner.autodocstring", "rodolphebarbanneau.python-docstring-highlighter", "mechatroner.rainbow-csv", + "oderwat.indent-rainbow", "uctakeoff.vscode-counter", "bierner.github-markdown-preview", "yahyabatulu.vscode-markdown-alert", diff --git a/project/.vscode/settings.json b/project/.vscode/settings.json.jinja similarity index 89% rename from project/.vscode/settings.json rename to project/.vscode/settings.json.jinja index b7a0021..6329463 100644 --- a/project/.vscode/settings.json +++ b/project/.vscode/settings.json.jinja @@ -8,14 +8,13 @@ ], "files.eol": "\n", "python.envFile": "${workspaceFolder}/.env", - "python.languageServer": "Pylance", + "python.languageServer": {% if type_checker == 'pyright' %}"Pylance"{% elif type_checker == 'ty' %}"None"{% endif %}, "python.analysis.autoImportCompletions": true, "python.analysis.completeFunctionParens": true, "python.analysis.autoFormatStrings": true, "python.analysis.inlayHints.variableTypes": true, "python.analysis.inlayHints.functionReturnTypes": true, "python.analysis.diagnosticMode": "workspace", - "python.analysis.typeCheckingMode": "strict", "python.terminal.activateEnvironment": true, "python.testing.autoTestDiscoverOnSaveEnabled": false, "python.testing.unittestEnabled": false, @@ -35,8 +34,6 @@ "source.fixAll.ruff": "always" } }, - "testExplorer.codeLens": true, - "testExplorer.gutterDecoration": true, "git.enableSmartCommit": true, "git.autofetch": true, "autoDocstring.docstringFormat": "google-notypes", @@ -45,4 +42,4 @@ "autoDocstring.startOnNewLine": true, "http.proxyStrictSSL": false, "telemetry.telemetryLevel": "off" -} +} \ No newline at end of file From 7858a7cd6c2ecb7b193fb3628dba10cd7da5734b Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:13:21 +0000 Subject: [PATCH 12/16] Fix notebooks, mkdocs --- project/README.md.jinja | 4 ++-- .../{% if include_notebooks %}notebooks{% endif %}/index.md | 2 +- project/{% if include_docs %}mkdocs.yml{% endif %}.jinja | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/project/README.md.jinja b/project/README.md.jinja index b284835..f89f829 100644 --- a/project/README.md.jinja +++ b/project/README.md.jinja @@ -6,8 +6,8 @@ [![Docs with MkDocs](https://img.shields.io/badge/MkDocs-docs?style=flat&logo=materialformkdocs&logoColor=white&color=%23526CFE)](https://squidfunk.github.io/mkdocs-material/){% endif %} {% if package_manager == 'poetry' %}[![Poetry](https://img.shields.io/endpoint?url=https://python-poetry.org/badge/v0.json)](https://python-poetry.org/){% elif package_manager == 'uv'%}[![uv](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/uv/main/assets/badge/v0.json)](https://github.com/astral-sh/uv){% endif %} [![linting: ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff){% if use_precommit %} -{% if precommit_tool == 'pre-commit' %}[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit){% elif precommit_tool == 'prek' %}[![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek){% endif %}{% endif %} {% if type_checker == 'pyright' %}[![Checked with pyright](https://microsoft.github.io/pyright/img/pyright_badge.svg)](https://microsoft.github.io/pyright/){% elif type_checker == 'ty' %}[![ty](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ty/main/assets/badge/v0.json)](https://github.com/astral-sh/ty){% endif %} +{% if precommit_tool == 'pre-commit' %}[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit){% elif precommit_tool == 'prek' %}[![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek){% endif %}{% endif %} [![security: bandit](https://img.shields.io/badge/security-bandit-yellow.svg)](https://github.com/PyCQA/bandit) [![Semantic Versions](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--versions-e10079.svg)](https://{{ repository_provider }}/{{ repository_namespace }}/{{ repository_name }}/releases) [![Copier](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/copier-org/copier/master/img/badge/badge-grayscale-border.json)](https://github.com/copier-org/copier) @@ -56,7 +56,7 @@ poetry run mkdocs build -f ./mkdocs.yml -d ./_build/ ``` {% elif package_manager == 'uv'%} ```bash -uv tool run mkdocs build -f ./mkdocs.yml -d ./_build/ +uv run mkdocs build -f ./mkdocs.yml -d ./_build/ ``` {% endif %} {% endif %} diff --git a/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md b/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md index e6e087a..a4952c7 100644 --- a/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md +++ b/project/{% if include_docs %}docs{% endif %}/{% if include_notebooks %}notebooks{% endif %}/index.md @@ -2,4 +2,4 @@ Put your notebooks here -- {ref}`intro_notebook.ipynb` +- [intro_notebook.ipynb](intro_notebook.ipynb) diff --git a/project/{% if include_docs %}mkdocs.yml{% endif %}.jinja b/project/{% if include_docs %}mkdocs.yml{% endif %}.jinja index 7af9e2f..89ec697 100644 --- a/project/{% if include_docs %}mkdocs.yml{% endif %}.jinja +++ b/project/{% if include_docs %}mkdocs.yml{% endif %}.jinja @@ -115,4 +115,4 @@ markdown_extensions: custom_checkbox: true - pymdownx.tilde - pymdownx.snippets: - base_path: !relative $config_dir/../ # Relative to the root directory ($config_dir is where mkdocs.yml is located) + base_path: !relative $config_dir/ # Relative to the root directory ($config_dir is where mkdocs.yml is located) From ebf4985bf435427434d39fa8755928f2819c2637 Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:18:03 +0000 Subject: [PATCH 13/16] Simplify poetry dynamic version --- project/.github/workflows/release.yaml.jinja | 6 ------ .../{% if include_docs %}docs.yaml{% endif %}.jinja | 6 ------ project/pyproject.toml.jinja | 2 +- 3 files changed, 1 insertion(+), 13 deletions(-) diff --git a/project/.github/workflows/release.yaml.jinja b/project/.github/workflows/release.yaml.jinja index abe1eb3..f23b880 100644 --- a/project/.github/workflows/release.yaml.jinja +++ b/project/.github/workflows/release.yaml.jinja @@ -47,12 +47,6 @@ jobs: - name: Install dependencies run: poetry install --no-interaction --all-extras - - name: Dynamic versioning - run: poetry self add "poetry-dynamic-versioning[plugin]" - - - name: Enable dynamic versioning - run: poetry dynamic-versioning enable - - name: Check poetry run: | poetry check diff --git a/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja b/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja index 069aeef..378e7b8 100644 --- a/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja +++ b/project/.github/workflows/{% if include_docs %}docs.yaml{% endif %}.jinja @@ -61,12 +61,6 @@ jobs: - name: Install dependencies run: poetry install --no-interaction --all-extras - - name: Dynamic versioning - run: poetry self add "poetry-dynamic-versioning[plugin]" - - - name: Enable dynamic versioning - run: poetry dynamic-versioning enable - - name: Check poetry run: | poetry check diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index 732031c..8eefd58 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -105,7 +105,7 @@ patterns = [ # https://github.com/mtkennerly/poetry-dynamic-versioning [tool.poetry-dynamic-versioning] -enable = false +enable = true vcs = "git" style = "semver" pattern = "default-unprefixed" From 19949783657e7b1d1ecec5dd51f443a60998b1db Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:31:29 +0000 Subject: [PATCH 14/16] Fix default groups --- project/.github/workflows/build.yaml.jinja | 13 +++++++------ project/pyproject.toml.jinja | 15 ++++++++------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/project/.github/workflows/build.yaml.jinja b/project/.github/workflows/build.yaml.jinja index 19d4183..dc461ac 100644 --- a/project/.github/workflows/build.yaml.jinja +++ b/project/.github/workflows/build.yaml.jinja @@ -40,8 +40,8 @@ jobs: {% raw %}- name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: - python-version: ${{ matrix.python-version }} -# cache: 'poetry'{% endraw %}{% if package_manager == 'poetry' %} + python-version: ${{ matrix.python-version }}{% endraw %}{% if package_manager == 'poetry' %} +# cache: 'poetry' - name: Install Poetry uses: snok/install-poetry@v1 @@ -74,7 +74,7 @@ jobs: run: uv sync --all-groups --all-extras --no-interaction{%endif %}{% if use_precommit %}{% if precommit_tool == 'pre-commit' %} - name: Run pre-commit - uses: pre-commit/action@v3.0.1 + uses: pre-commit/action@v3 continue-on-error: true env: SKIP: poetry-lock{% elif precommit_tool == 'prek' %} @@ -82,11 +82,12 @@ jobs: - name: Run prek uses: j178/prek-action@v1 continue-on-error: true - env: - SKIP: poetry-lock{% endif %}{% endif %}{% if package_manager == 'poetry'%} + env:{% endif %}{% endif %}{% if package_manager == 'poetry'%} + SKIP: poetry-lock - name: Build dependencies run: poetry build{% elif package_manager == 'uv'%} + SKIP: uv-lock - name: Build dependencies run: uv build{% endif %} @@ -110,7 +111,7 @@ jobs: # MishaKav/pytest-coverage-comment - name: Coverage summary report - uses: irongut/CodeCoverageSummary@v1.3.0 + uses: irongut/CodeCoverageSummary@v1 {% raw %}with: filename: coverage-${{ runner.os }}-${{ matrix.python-version }}.xml badge: true diff --git a/project/pyproject.toml.jinja b/project/pyproject.toml.jinja index 8eefd58..4e17545 100644 --- a/project/pyproject.toml.jinja +++ b/project/pyproject.toml.jinja @@ -43,12 +43,13 @@ packages = [ [tool.poetry.dependencies] python = "^{{ python_version }}" {% elif package_manager == 'uv'%}[tool.uv] -default-groups = [ - "dev", - "test",{% if include_docs %} - "docs",{% endif %} - "debug" -]{% endif %} +default-groups = "all" +# default-groups = [ +# "dev", +# "test",{% if include_docs %} +# "docs",{% endif %} +# "debug" +# ]{% endif %} [dependency-groups] dev = [ @@ -184,7 +185,7 @@ exclude_lines = [ ] [tool.ruff] -line-length = 120 # Must agree with Black +line-length = 120 extend-include = ["*.ipynb"] exclude = [ "migrations", From 243ec8210b819c51e77f64e7b2345095d048ab0d Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:45:22 +0000 Subject: [PATCH 15/16] Fix minor issues --- .pre-commit-config.yaml | 14 +++++++------- project/.devcontainer/devcontainer.json.jinja | 3 +-- project/.github/workflows/build.yaml.jinja | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index db469a3..7c3d85d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: - id: pre-commit-update - repo: https://github.com/python-poetry/poetry - rev: 2.2.1 + rev: 2.3.1 hooks: - id: poetry-check - id: poetry-lock @@ -40,12 +40,12 @@ repos: - id: detect-private-key - repo: https://gitlab.com/bmares/check-json5 - rev: v1.0.0 + rev: v1.0.1 hooks: - id: check-json5 - # - repo: https://github.com/aristanetworks/j2lint.git - # rev: v1.1.0 - # hooks: - # - id: j2lint - # args: [--ignore, S7, --, --warn, V2, --] + # - repo: https://github.com/aristanetworks/j2lint.git + # rev: v1.1.0 + # hooks: + # - id: j2lint + # args: [--ignore, S7, --, --warn, V2, --] diff --git a/project/.devcontainer/devcontainer.json.jinja b/project/.devcontainer/devcontainer.json.jinja index 814cb9b..df25424 100644 --- a/project/.devcontainer/devcontainer.json.jinja +++ b/project/.devcontainer/devcontainer.json.jinja @@ -10,8 +10,7 @@ "VARIANT": "{{ python_version }}-bookworm" } }, - "remoteEnv": { - {% if self_signed %}// https://github.com/microsoft/vscode-remote-release/issues/6092 + "remoteEnv": {% raw %}{{% endraw %}{% if self_signed %}// https://github.com/microsoft/vscode-remote-release/issues/6092 "NODE_TLS_REJECT_UNAUTHORIZED": "0",{% endif %}{% if package_manager == 'poetry' %} "POETRY_DYNAMIC_VERSIONING_BYPASS": "1.0.0"{% elif package_manager == 'uv'%} "UV_SYSTEM_PYTHON": "1", diff --git a/project/.github/workflows/build.yaml.jinja b/project/.github/workflows/build.yaml.jinja index dc461ac..3db7257 100644 --- a/project/.github/workflows/build.yaml.jinja +++ b/project/.github/workflows/build.yaml.jinja @@ -76,8 +76,7 @@ jobs: - name: Run pre-commit uses: pre-commit/action@v3 continue-on-error: true - env: - SKIP: poetry-lock{% elif precommit_tool == 'prek' %} + env:{% elif precommit_tool == 'prek' %} - name: Run prek uses: j178/prek-action@v1 From e131332642251a52c795f29babbde0c1400d20cd Mon Sep 17 00:00:00 2001 From: twsl <45483159+twsl@users.noreply.github.com> Date: Wed, 21 Jan 2026 15:45:41 +0000 Subject: [PATCH 16/16] Update pre-commit poetry --- ... if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja b/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja index e39c0b7..f89a127 100644 --- a/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja +++ b/project/{% if use_precommit %}.pre-commit-config.yaml{% endif %}.jinja @@ -16,7 +16,7 @@ repos: - id: pre-commit-update {% if package_manager == 'poetry' %} - repo: https://github.com/python-poetry/poetry - rev: 2.2.1 + rev: 2.3.1 hooks: - id: poetry-lock - id: poetry-check{% elif package_manager == 'uv'%}