Skip to content

Commit 489f080

Browse files
authored
Merge pull request #13 from nekeal/prek-uv-pyrefly
prek uv pyrefly
2 parents b070e03 + d5ace47 commit 489f080

16 files changed

Lines changed: 304 additions & 171 deletions

File tree

.github/workflows/test.yml

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
steps:
99
- uses: actions/checkout@v4
1010
- name: Download actionlint
11-
run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.6.21
11+
run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.11
1212
shell: bash
1313
- name: Check workflow files
1414
run: ./actionlint -color
@@ -19,22 +19,28 @@ jobs:
1919

2020
steps:
2121
- uses: actions/checkout@v4
22-
- uses: actions/setup-python@v5
22+
- name: Install uv
23+
uses: astral-sh/setup-uv@v7
2324
with:
25+
enable-cache: false
2426
python-version: "3.12"
25-
- run: python -m pip install pre-commit
26-
- run: pre-commit run --all-files
27+
activate-environment: true
28+
- run: uv pip install prek
29+
- run: prek run --all-files
2730

2831
test:
2932
runs-on: ubuntu-latest
3033

3134
steps:
3235
- uses: actions/checkout@v4
33-
- uses: actions/setup-python@v5
36+
- name: Install uv
37+
uses: astral-sh/setup-uv@v7
3438
with:
39+
enable-cache: false
3540
python-version: "3.12"
36-
- run: python -m pip install cookiecutter pytest pyyaml toml
37-
- run: pytest
41+
activate-environment: true
42+
- run: uv pip install cookiecutter pytest pyyaml toml
43+
- run: uv run pytest
3844

3945
lint-generated-project:
4046
runs-on: ubuntu-latest
@@ -44,8 +50,8 @@ jobs:
4450
- uses: actions/setup-python@v5
4551
with:
4652
python-version: "3.12"
47-
- run: python -m pip install cookiecutter poetry
48-
- run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.6.21
53+
- run: python -m pip install cookiecutter uv prek
54+
- run: bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) 1.7.11
4955
- name: Generate project
5056
run: |
5157
cookiecutter --config-file tests/context.yaml --no-input .
@@ -63,6 +69,6 @@ jobs:
6369
- name: Lint project
6470
run: |
6571
cd example-project
66-
poetry install
67-
poetry run pre-commit run -a
68-
poetry run mkdocs build
72+
uv sync
73+
prek run --all-files
74+
uv run mkdocs build

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,5 @@
11
__pycache__/
2+
3+
# Claude Code
4+
.agents/
5+
.claude/

README.md

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ A [cookiecutter](https://cookiecutter.readthedocs.io/en/latest/README.html) (pro
2727
* Powered by [mkdocs-material](https://github.com/squidfunk/mkdocs-material)
2828
* Auto-generated API documentation from docstrings via [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings)
2929
* See the extensive list of [MkDocs plugins](https://github.com/mkdocs/mkdocs/wiki/MkDocs-Plugins) which can help you
30-
to tune the documentation to fit your project's needs
30+
to tune the documentation to fit your project's needs
3131

3232
#### Automated releases
3333

@@ -42,9 +42,10 @@ A [cookiecutter](https://cookiecutter.readthedocs.io/en/latest/README.html) (pro
4242

4343
#### Bells and whistles
4444

45-
* [Poetry](https://python-poetry.org/docs/) for managing dependencies and packaging
46-
* [pre-commit](https://pre-commit.com/) for running all the goodies listed below
47-
* [mypy](https://mypy.readthedocs.io/en/stable/) for static type checking
45+
* [uv](https://docs.astral.sh/uv/) for managing dependencies and packaging
46+
* [hatchling](https://github.com/pypa/hatch) as the build backend
47+
* [prek](https://github.com/j178/prek) for running all the goodies listed below
48+
* [pyrefly](https://pyrefly.org/) for static type checking
4849
* [ruff](https://docs.astral.sh/ruff/) for automatic formatting, linting and automatically fixing some linting errors
4950

5051
#### Automation

cookiecutter.json

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"3.10+",
1313
"3.11+",
1414
"3.12+",
15-
"3.13+"
15+
"3.13+",
16+
"3.14+"
1617
],
1718
"_python_version_specs": {
1819
"3.9+": {
@@ -21,33 +22,43 @@
2122
"3.10",
2223
"3.11",
2324
"3.12",
24-
"3.13"
25+
"3.13",
26+
"3.14"
2527
]
2628
},
2729
"3.10+": {
2830
"versions": [
2931
"3.10",
3032
"3.11",
3133
"3.12",
32-
"3.13"
34+
"3.13",
35+
"3.14"
3336
]
3437
},
3538
"3.11+": {
3639
"versions": [
3740
"3.11",
3841
"3.12",
39-
"3.13"
42+
"3.13",
43+
"3.14"
4044
]
4145
},
4246
"3.12+": {
4347
"versions": [
4448
"3.12",
45-
"3.13"
49+
"3.13",
50+
"3.14"
4651
]
4752
},
4853
"3.13+": {
4954
"versions": [
50-
"3.13"
55+
"3.13",
56+
"3.14"
57+
]
58+
},
59+
"3.14+": {
60+
"versions": [
61+
"3.14"
5162
]
5263
}
5364
},

pyproject.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[project]
2+
name = "cookiecutter-python-package"
3+
version = "0.1.0"
4+
description = "Cookiecutter template for Python packages"
5+
authors = [{name = "Szymon Cader", email = "szymon.sc.cader@gmail.com"}]
6+
readme = "README.md"
7+
requires-python = ">=3.11"
8+
dependencies = [
9+
"cookiecutter>=2.2.3",
10+
"pytest>=7.4.0",
11+
"pyyaml>=6.0.1",
12+
"toml>=0.10.2",
13+
]
14+
15+
[dependency-groups]
16+
dev = [
17+
"flake8-to-ruff>=0.0.233",
18+
"black>=23.7.0",
19+
"pre-commit>=3.3.3",
20+
"python-redmine>=2.4.0",
21+
"cffi>=1.17.1",
22+
]
23+
24+
[build-system]
25+
requires = ["hatchling"]
26+
build-backend = "hatchling.build"
27+
28+
[tool.hatch.build.targets.wheel]
29+
packages = ["."]

tests/test_project_generation.py

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import subprocess
12
from typing import Any
23

34
import pytest
@@ -38,16 +39,27 @@ def test_generate_new_project(tmp_path, generated_project_path):
3839
assert generated_project_path == tmp_path / PROJECT_NAME
3940

4041

41-
def test_poetry_uses_dev_group(generated_project_path):
42+
def test_uses_hatchling_build_system(generated_project_path):
4243
pyproject_toml_content = generated_project_path.joinpath(
4344
"pyproject.toml"
4445
).read_text()
4546

46-
assert "dev-dependencies" not in pyproject_toml_content
47-
assert "[tool.poetry.group.dev.dependencies]" in pyproject_toml_content.splitlines()
47+
assert '[build-system]' in pyproject_toml_content
48+
assert 'hatchling' in pyproject_toml_content
49+
assert 'poetry' not in pyproject_toml_content
4850

4951

50-
def test_python_version_is_correctly_included_in_black_config(generated_project_path):
52+
def test_uses_dependency_groups(generated_project_path):
53+
pyproject_toml_content = generated_project_path.joinpath(
54+
"pyproject.toml"
55+
).read_text()
56+
57+
assert '[dependency-groups]' in pyproject_toml_content
58+
assert 'pyrefly' in pyproject_toml_content
59+
assert 'prek' in pyproject_toml_content
60+
61+
62+
def test_python_version_is_correctly_included_in_ruff_config(generated_project_path):
5163
parsed_pyproject_toml = toml.loads(
5264
generated_project_path.joinpath("pyproject.toml").read_text()
5365
)
@@ -65,7 +77,7 @@ def test_python_version_is_correctly_included_in_github_workflow(
6577

6678
assert parsed_github_workflow["jobs"]["test"]["strategy"]["matrix"][
6779
"python-version"
68-
] == ["3.9", "3.10", "3.11", "3.12", "3.13"]
80+
] == ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"]
6981

7082

7183
def test_specific_files_and_packages_are_not_include_if_package_is_meant_to_be_not_releasable(tmp_path):
@@ -77,5 +89,40 @@ def test_specific_files_and_packages_are_not_include_if_package_is_meant_to_be_n
7789
parsed_pyproject_toml = toml.loads(
7890
project_path.joinpath("pyproject.toml").read_text()
7991
)
80-
assert "python-kacl" not in parsed_pyproject_toml["tool"]["poetry"]["group"]["dev"]["dependencies"]
92+
dev_deps = parsed_pyproject_toml.get("dependency-groups", {}).get("dev", [])
93+
assert "python-kacl" not in dev_deps
8194
assert "pypi" not in Path(project_path / "README.md").read_text().lower()
95+
96+
97+
def test_dependencies_can_be_installed(generated_project_path):
98+
"""Verify that all dependencies in the generated project can be installed with uv sync."""
99+
result = subprocess.run(
100+
["uv", "sync"],
101+
cwd=generated_project_path,
102+
capture_output=True,
103+
text=True,
104+
)
105+
assert result.returncode == 0, f"uv sync failed: {result.stderr}"
106+
107+
108+
def test_precommit_hooks_pass(generated_project_path):
109+
"""Verify that all pre-commit hooks pass on the generated project."""
110+
subprocess.run(
111+
["git", "init"],
112+
cwd=generated_project_path,
113+
capture_output=True,
114+
text=True,
115+
)
116+
subprocess.run(
117+
["git", "add", "."],
118+
cwd=generated_project_path,
119+
capture_output=True,
120+
text=True,
121+
)
122+
result = subprocess.run(
123+
["uv", "run", "prek", "run", "--all-files"],
124+
cwd=generated_project_path,
125+
capture_output=True,
126+
text=True,
127+
)
128+
assert result.returncode == 0, f"prek run failed:\nstdout: {result.stdout}\nstderr: {result.stderr}"

{{cookiecutter.project_slug}}/.github/actions/python-poetry-env/action.yml

Lines changed: 0 additions & 21 deletions
This file was deleted.

{{cookiecutter.project_slug}}/.github/workflows/cookiecutter.yml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,28 @@ jobs:
1515
python-version: "3.12"
1616

1717
- name: Install dependencies
18-
run: python -m pip install cruft poetry jello tabulate
18+
run: python -m pip install cruft jello tabulate prek
1919

2020
- name: Update project structure
2121
run: |
2222
cruft update -y
2323
2424
- name: Check if there are changes
2525
id: changes
26-
run: echo "::set-output name=changed::$(git status --porcelain | wc -l)"
26+
run: echo "changed=$(git status --porcelain | wc -l)" >> "$GITHUB_OUTPUT"
2727

28-
- name: apply additional changes and fixes
28+
- name: Install uv
29+
if: steps.changes.outputs.changed > 0
30+
uses: astral-sh/setup-uv@v7
31+
with:
32+
enable-cache: false
33+
34+
- name: Apply additional changes and fixes
2935
if: steps.changes.outputs.changed > 0
3036
run: |
31-
poetry lock --no-update # add new dependencies
32-
poetry install
33-
poetry run pre-commit run -a || true # we have to fix other issues manually
37+
uv lock # add new dependencies
38+
uv sync
39+
prek run --all-files
3440
3541
- name: Get template versions
3642
id: get_versions
@@ -39,8 +45,8 @@ jobs:
3945
run: |
4046
CURRENT_VERSION=$(git show HEAD:.cruft.json | jello -r "_['commit'][:8]")
4147
NEXT_VERSION=$(jello -r "_['commit'][:8]" < .cruft.json)
42-
echo ::set-output name="current_version::$CURRENT_VERSION"
43-
echo ::set-output name="next_version::$NEXT_VERSION"
48+
echo "current_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
49+
echo "next_version=$NEXT_VERSION" >> "$GITHUB_OUTPUT"
4450
4551
- name: Get changelog
4652
id: get_changelog
@@ -60,15 +66,15 @@ jobs:
6066
body="${body//'%'/'%25'}"
6167
body="${body//$'\n'/'%0A'}"
6268
body="${body//$'\r'/'%0D'}"
63-
echo ::set-output name="changelog::$body"
69+
echo "changelog=$body" >> "$GITHUB_OUTPUT"
6470
6571
# behaviour if PR already exists: https://github.com/marketplace/actions/create-pull-request#action-behaviour
6672
- name: Create Pull Request
6773
env:
6874
# a PAT is required to be able to update workflows
6975
GITHUB_TOKEN: ${{ secrets.AUTO_UPDATE_GITHUB_TOKEN }}
7076
if: ${{ steps.changes.outputs.changed > 0 && env.GITHUB_TOKEN != 0 }}
71-
uses: peter-evans/create-pull-request@v3
77+
uses: peter-evans/create-pull-request@v6
7278
with:
7379
token: ${{ env.GITHUB_TOKEN }}
7480
commit-message: >-

0 commit comments

Comments
 (0)