From 9ea2a97bb26ac6c1bc4a4f3494ab07bbd2190fcd Mon Sep 17 00:00:00 2001 From: haztecaso Date: Tue, 29 Jul 2025 20:26:54 +0200 Subject: [PATCH 1/9] add version file --- .../src/{{cookiecutter.project_slug}}/version.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py b/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py index 00eb123..a6a318f 100644 --- a/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py +++ b/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py @@ -1,19 +1,20 @@ """Utilities to retrieve the information of the program version.""" +import platform +import sys +from textwrap import dedent + # Do not edit the version manually, let `make bump` do it. __version__ = "0.1.0" def version_info() -> str: - import platform - import sys - from textwrap import dedent """Display the version of the program, python and the platform.""" return dedent( f"""\ ------------------------------------------------------------------ - {{cookiecutter.project_slug}}: {__version__} + {{cookiecutter.project_underscore_slug}}: {__version__} Python: {sys.version.split(" ", maxsplit=1)[0]} Platform: {platform.platform()} ------------------------------------------------------------------""" From bcf414254898ca4ca8d690fb3ab03313d3d08212 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Tue, 29 Jul 2025 20:41:28 +0200 Subject: [PATCH 2/9] fix cookiecutter vars --- .../src/{{cookiecutter.project_slug}}/version.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py b/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py index a6a318f..00eb123 100644 --- a/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py +++ b/{{cookiecutter.project_slug}}/src/{{cookiecutter.project_slug}}/version.py @@ -1,20 +1,19 @@ """Utilities to retrieve the information of the program version.""" -import platform -import sys -from textwrap import dedent - # Do not edit the version manually, let `make bump` do it. __version__ = "0.1.0" def version_info() -> str: + import platform + import sys + from textwrap import dedent """Display the version of the program, python and the platform.""" return dedent( f"""\ ------------------------------------------------------------------ - {{cookiecutter.project_underscore_slug}}: {__version__} + {{cookiecutter.project_slug}}: {__version__} Python: {sys.version.split(" ", maxsplit=1)[0]} Platform: {platform.platform()} ------------------------------------------------------------------""" From f5511bcf1b584db2bfb5261c34d63f2f10dfacb8 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Wed, 30 Jul 2025 00:52:03 +0200 Subject: [PATCH 3/9] update readme --- {{cookiecutter.project_slug}}/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/README.md b/{{cookiecutter.project_slug}}/README.md index 4544e28..5440f4b 100644 --- a/{{cookiecutter.project_slug}}/README.md +++ b/{{cookiecutter.project_slug}}/README.md @@ -1,7 +1,15 @@ # {{ cookiecutter.project_name }} -{{ cookiecutter.project_short_description }} +
+*{{ cookiecutter.project_short_description }}* +
+ +
+![Test](https://github.com/{{cookiecutter.github_username}}/{{cookiecutter.project_slug}}/actions/workflows/test.yml/badge.svg) +
+ +--- {% if cookiecutter.use_mkdocs == 'y' %} -[docs](https://{{cookiecutter.github_username}}.github.io/{{cookiecutter.project_slug}}) +[**Documentation**](https://{{cookiecutter.github_username}}.github.io/{{cookiecutter.project_slug}}) {%- endif %} From fba9010e2dce601aaa389d1e708f74cf5fc866d8 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Wed, 30 Jul 2025 21:51:53 +0200 Subject: [PATCH 4/9] rename github workflows --- {{cookiecutter.project_slug}}/.github/workflows/docs.yml | 2 +- {{cookiecutter.project_slug}}/.github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml index baf0ed6..4fa5eb0 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml @@ -1,4 +1,4 @@ -name: docs +name: Docs on: push: diff --git a/{{cookiecutter.project_slug}}/.github/workflows/test.yml b/{{cookiecutter.project_slug}}/.github/workflows/test.yml index a741956..233202c 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/test.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/test.yml @@ -1,4 +1,4 @@ -name: test +name: Test on: push: From ab673429d9a026431cbac26c3baee1b0cf6b8f94 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Wed, 30 Jul 2025 21:52:01 +0200 Subject: [PATCH 5/9] separate test dependency group --- tests/test_template.py | 8 +++++++- {{cookiecutter.project_slug}}/pyproject.toml | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/test_template.py b/tests/test_template.py index 65a7e1f..cfa6d9b 100644 --- a/tests/test_template.py +++ b/tests/test_template.py @@ -121,6 +121,12 @@ def test_pytest_runs(project: Result): test_dir = project_path / "tests" assert test_dir.is_dir(), f"Expected tests directory not found: {test_dir}" + # Sync test dependencies + process = run_command("uv sync --group test", project_path) + assert ( + process.returncode == 0 + ), f"uv sync failed with error: {process.stderr}\nOutput: {process.stdout}" + process = run_command("uv run pytest -xvs", project_path) assert ( @@ -151,7 +157,7 @@ def test_mkdocs_runs(project: Result): assert ( process.returncode == 0 - ), f"pytest failed with error: {process.stderr}\nOutput: {process.stdout}" + ), f"mkdocs failed with error: {process.stderr}\nOutput: {process.stdout}" assert ( "Documentation built in" in process.stderr ), f"Expected 'Documentation built in' in mkdocs build stderr, but got: {process.stderr}" diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index 2ab1c07..b5326cc 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -28,6 +28,8 @@ dev = [ "isort", "pre-commit", "pyright", +] +test = [ "pytest", {%- if cookiecutter.use_asyncio.lower() == "y" %} "pytest-asyncio", From b5f70ef050876ee428f1e69dcc34d740ff36e71f Mon Sep 17 00:00:00 2001 From: haztecaso Date: Wed, 30 Jul 2025 22:13:22 +0200 Subject: [PATCH 6/9] improve workflows names --- .github/workflows/test.yml | 4 ++-- {{cookiecutter.project_slug}}/.github/workflows/docs.yml | 6 ++---- {{cookiecutter.project_slug}}/.github/workflows/test.yml | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3ea9a1d..e81e65a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -10,8 +10,8 @@ permissions: contents: read jobs: - tests: - name: tests + pytest: + name: Run tests runs-on: ubuntu-latest steps: diff --git a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml index 4fa5eb0..31a065b 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/docs.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/docs.yml @@ -3,9 +3,6 @@ name: Docs on: push: branches: [ "main" ] - pull_request: - branches: [ "main" ] - # Allow manual trigger workflow_dispatch: permissions: @@ -13,13 +10,13 @@ permissions: pages: write id-token: write -# Allow only one concurrent deployment concurrency: group: "pages" cancel-in-progress: false jobs: build: + name: Mkdocs build runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -47,6 +44,7 @@ jobs: path: ./site deploy: + name: Deploy to github pages environment: name: github-pages url: {% raw -%}${{ github.event.repository.html_url }}/{%- endraw %} diff --git a/{{cookiecutter.project_slug}}/.github/workflows/test.yml b/{{cookiecutter.project_slug}}/.github/workflows/test.yml index 233202c..90baf1d 100644 --- a/{{cookiecutter.project_slug}}/.github/workflows/test.yml +++ b/{{cookiecutter.project_slug}}/.github/workflows/test.yml @@ -10,8 +10,8 @@ permissions: contents: read jobs: - uv-example: - name: python + pytest: + name: Run tests runs-on: ubuntu-latest steps: From c3eb9e1e92587dc1847820394153ecfef36b9cb3 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Thu, 31 Jul 2025 18:01:36 +0200 Subject: [PATCH 7/9] include readme in docs --- README.md | 41 ++++++++------------ {{cookiecutter.project_slug}}/docs/index.md | 24 +----------- {{cookiecutter.project_slug}}/mkdocs.yml | 20 +++++----- {{cookiecutter.project_slug}}/pyproject.toml | 1 + 4 files changed, 29 insertions(+), 57 deletions(-) diff --git a/README.md b/README.md index 8cb584d..a83422f 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,28 @@ ![Nix Flakes](https://img.shields.io/badge/Nix-Flakes-blue?logo=nixos&logoColor=white) ![uv](https://img.shields.io/badge/Package_Manager-uv-blue) [![Tests](https://img.shields.io/badge/CI-Tests-green?logo=github&logoColor=white)](https://github.com/haztecaso/python-template/actions) -[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) A modern cookiecutter template for Python projects using `uv` as the package manager, Nix flakes for reproducibility, and a clean development setup. +## 🚀 Usage + +### Creating a new project + +If you want to keep your project in sync with this template, you can use +*cruft*. + +```bash +cruft create gh:haztecaso/python-template +``` + +Otherwise you can stick with *cookiecutter*. + +```bash +cookiecutter gh:haztecaso/python-template +``` + ## Features ### Current Features @@ -42,26 +58,3 @@ A modern cookiecutter template for Python projects using `uv` as the package man - 🔄 **Enhanced CI**: GitHub Action test matrix for multi-environment testing - 🐍 **PyPy**: Registry setup and GitHub Action for multi-interpreter testing -## 🚀 Usage - -This template requires the [Nix package manager](https://nixos.org/). You can install `cookiecutter` in your preferred way or create a temporal shell with it: - -```bash -nix-shell -p cookiecutter -``` - -### Creating a new project - -```bash -cookiecutter gh:haztecaso/python-template -``` - -### Initial setup - -```bash -# If you use direnv -direnv allow - -# manually activate the development environment -nix develop -``` diff --git a/{{cookiecutter.project_slug}}/docs/index.md b/{{cookiecutter.project_slug}}/docs/index.md index a848124..808c67e 100644 --- a/{{cookiecutter.project_slug}}/docs/index.md +++ b/{{cookiecutter.project_slug}}/docs/index.md @@ -1,23 +1 @@ -{{ cookiecutter.project_short_description }} - -## Installation - -```bash -pip install {{ cookiecutter.project_slug }} -``` - -## Usage - -```python -from {{ cookiecutter.project_slug }} import example - -# Add usage examples here -``` - -## Features - -* Add your project features here - -## License - -{{ cookiecutter.open_source_license }} +{! include_markdown "../README.md" start="" !} diff --git a/{{cookiecutter.project_slug}}/mkdocs.yml b/{{cookiecutter.project_slug}}/mkdocs.yml index f19f8ab..8dfb256 100644 --- a/{{cookiecutter.project_slug}}/mkdocs.yml +++ b/{{cookiecutter.project_slug}}/mkdocs.yml @@ -34,9 +34,6 @@ markdown_extensions: - abbr - def_list - admonition - # We need the markdown-include to inject files into other files - - markdown_include.include: - base_path: docs - meta - toc: permalink: true @@ -65,7 +62,15 @@ markdown_extensions: - pymdownx.tilde plugins: - - search + - autolinks + - include-markdown: + opening_tag: "{!" + closing_tag: "!}" + - git-revision-date-localized: + type: timeago + fallback_to_build_date: true + - minify: + minify_html: true - mkdocstrings: handlers: python: @@ -73,12 +78,7 @@ plugins: show_source: true show_submodules: true docstring_style: google - - autolinks - - git-revision-date-localized: - type: timeago - fallback_to_build_date: true - - minify: - minify_html: true + - search - section-index nav: diff --git a/{{cookiecutter.project_slug}}/pyproject.toml b/{{cookiecutter.project_slug}}/pyproject.toml index b5326cc..2487956 100644 --- a/{{cookiecutter.project_slug}}/pyproject.toml +++ b/{{cookiecutter.project_slug}}/pyproject.toml @@ -43,6 +43,7 @@ docs = [ "mkdocs-autolinks-plugin", "mkdocs-git-revision-date-localized-plugin", "mkdocs-htmlproofer-plugin", + "mkdocs-include-markdown-plugin", "mkdocs-material", "mkdocs-minify-plugin", "mkdocs-section-index", From ad78ed486423226ee292ab0b1c96fa90f6542c82 Mon Sep 17 00:00:00 2001 From: haztecaso Date: Thu, 31 Jul 2025 18:01:46 +0200 Subject: [PATCH 8/9] simplify hook --- hooks/post_gen_project.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hooks/post_gen_project.sh b/hooks/post_gen_project.sh index 2990c23..9a318a1 100755 --- a/hooks/post_gen_project.sh +++ b/hooks/post_gen_project.sh @@ -13,5 +13,6 @@ uv sync --dev uv run black src tests uv run isort src tests nix build -git init && git branch -m "main" && git add . +git init --initial-branch=main && git add . uv run pre-commit install --hook-type commit-msg --hook-type pre-commit +clear From 17268344c8611c64973d1061677c061745fa6a3d Mon Sep 17 00:00:00 2001 From: haztecaso Date: Thu, 31 Jul 2025 18:15:54 +0200 Subject: [PATCH 9/9] remove clear from hook --- hooks/post_gen_project.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/hooks/post_gen_project.sh b/hooks/post_gen_project.sh index 9a318a1..cbdebb6 100755 --- a/hooks/post_gen_project.sh +++ b/hooks/post_gen_project.sh @@ -15,4 +15,3 @@ uv run isort src tests nix build git init --initial-branch=main && git add . uv run pre-commit install --hook-type commit-msg --hook-type pre-commit -clear