Skip to content

Commit b28fa02

Browse files
authored
Merge pull request #103 from trailofbits/modernize-python-template
Modernize python template
2 parents b605641 + 856c54c commit b28fa02

11 files changed

Lines changed: 62 additions & 112 deletions

File tree

.github/workflows/tests.yml

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,13 @@ jobs:
3535
3636
cd /tmp/python-project
3737
git init . && git add . && git commit -m "Initial commit"
38-
make dev
39-
make reformat
38+
make format
4039
41-
git diff --exit-code || { >&2 echo "please reformat"; exit 1; }
40+
git diff --exit-code || { >&2 echo "please format"; exit 1; }
4241
4342
make lint
4443
make test
45-
make package
44+
make build
4645
make doc
4746
cd .. && rm -rf /tmp/python-project
4847
@@ -54,14 +53,13 @@ jobs:
5453
5554
cd /tmp/python-project
5655
git init . && git add . && git commit -m "Initial commit"
57-
make dev
58-
make reformat
56+
make format
5957
60-
git diff --exit-code || { >&2 echo "please reformat"; exit 1; }
58+
git diff --exit-code || { >&2 echo "please format"; exit 1; }
6159
6260
make lint
6361
make test
64-
make package
62+
make build
6563
make doc
6664
cd .. && rm -rf /tmp/python-project
6765
@@ -73,14 +71,13 @@ jobs:
7371
7472
cd /tmp/tob-r-and-e-python-project
7573
git init . && git add . && git commit -m "Initial commit"
76-
make dev
77-
make reformat
74+
make format
7875
79-
git diff --exit-code || { >&2 echo "please reformat"; exit 1; }
76+
git diff --exit-code || { >&2 echo "please format"; exit 1; }
8077
8178
make lint
8279
make test
83-
make package
80+
make build
8481
make doc
8582
cd .. && rm -rf /tmp/tob-r-and-e-python-project
8683
@@ -92,14 +89,13 @@ jobs:
9289
9390
cd /tmp/bit-trails
9491
git init . && git add . && git commit -m "Initial commit"
95-
make dev
96-
make reformat
92+
make format
9793
98-
git diff --exit-code || { >&2 echo "please reformat"; exit 1; }
94+
git diff --exit-code || { >&2 echo "please format"; exit 1; }
9995
10096
make lint
10197
make test
102-
make package
98+
make build
10399
make doc
104100
cd .. && rm -rf /tmp/bit-trails
105101
@@ -112,13 +108,12 @@ jobs:
112108
113109
cd /tmp/python-project
114110
git init . && git add . && git commit -m "Initial commit"
115-
make dev
116-
make reformat
111+
make format
117112
118-
git diff --exit-code || { >&2 echo "please reformat"; exit 1; }
113+
git diff --exit-code || { >&2 echo "please format"; exit 1; }
119114
120115
make lint
121116
make test
122-
make package
117+
make build
123118
make doc
124119
cd .. && rm -rf /tmp/python-project

.github/workflows/zizmor.yml

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,16 @@ permissions: {}
1010

1111
jobs:
1212
zizmor:
13-
name: zizmor latest via PyPI
1413
runs-on: ubuntu-latest
1514
permissions:
16-
security-events: write # needed by upload-sarif for all repositories
15+
security-events: write
16+
contents: read # only needed for private repos
17+
actions: read # only needed for private repos
1718
steps:
1819
- name: Checkout repository
1920
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
2021
with:
2122
persist-credentials: false
2223

23-
- name: Install the latest version of uv
24-
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
25-
2624
- name: Run zizmor 🌈
27-
# Run it for both this repo and the templated cookiecutter repo.
28-
run: uvx zizmor --format sarif . {{cookiecutter.project_slug}}/.github/workflows > results.sarif
29-
env:
30-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31-
32-
- name: Upload SARIF file
33-
uses: github/codeql-action/upload-sarif@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.29.5
34-
with:
35-
sarif_file: results.sarif
36-
category: zizmor
25+
uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
version: 2
22

33
updates:
4-
- package-ecosystem: pip
4+
- package-ecosystem: uv
55
directory: /
66
groups:
77
python:

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ jobs:
1818
- name: Install uv
1919
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
2020

21-
- name: setup
22-
run: |
23-
make dev INSTALL_EXTRA=doc
24-
2521
- name: build docs
2622
run: |
2723
make doc

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ jobs:
2020
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
2121

2222
- name: lint
23-
run: make lint INSTALL_EXTRA=lint
23+
run: make lint

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
2121

2222
- name: Build distributions
23-
run: uv build
23+
run: make build
2424

2525
- name: Upload distributions
2626
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ jobs:
1313
strategy:
1414
matrix:
1515
python:
16-
- "3.9"
1716
- "3.10"
1817
- "3.11"
1918
- "3.12"
19+
- "3.13"
2020
runs-on: ubuntu-latest
2121
steps:
2222
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
@@ -25,9 +25,8 @@ jobs:
2525

2626
- name: Install uv
2727
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
28-
29-
- name: Install Python ${{ matrix.python }}
30-
run: uv python install ${{ matrix.python }}
28+
with:
29+
python-version: ${{ matrix.python }}
3130

3231
- name: test
33-
run: make test INSTALL_EXTRA=test
32+
run: make test

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

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,16 @@ permissions: {}
1010

1111
jobs:
1212
zizmor:
13-
name: zizmor latest via PyPI
1413
runs-on: ubuntu-latest
1514
permissions:
16-
security-events: write # needed by upload-sarif for all repositories
17-
contents: read # needed by upload-sarif for private repositories
18-
actions: read # needed by upload-sarif for private repositories
15+
security-events: write
16+
contents: read # only needed for private repos
17+
actions: read # only needed for private repos
1918
steps:
2019
- name: Checkout repository
2120
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
2221
with:
2322
persist-credentials: false
2423

25-
- name: Install the latest version of uv
26-
uses: astral-sh/setup-uv@557e51de59eb14aaaba2ed9621916900a91d50c6 # v6.6.1
27-
2824
- name: Run zizmor 🌈
29-
run: uvx zizmor --format sarif . > results.sarif
30-
env:
31-
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32-
33-
- name: Upload SARIF file
34-
uses: github/codeql-action/upload-sarif@f1f6e5f6af878fb37288ce1c627459e94dbf7d01 # v3.29.5
35-
with:
36-
sarif_file: results.sarif
37-
category: zizmor
25+
uses: zizmorcore/zizmor-action@5ca5fc7a4779c5263a3ffa0e1f693009994446d1 # v0.1.2

{{cookiecutter.project_slug}}/Makefile

Lines changed: 9 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,9 @@ SHELL := /bin/bash
22

33
PY_IMPORT = {{ cookiecutter.__project_import }}
44

5-
ALL_PY_SRCS := $(shell find src -name '*.py') \
6-
$(shell find test -name '*.py')
7-
8-
# Optionally overriden by the user, if they're using a virtual environment manager.
9-
# Warning: changing this name to something else than '.venv' will make working with
10-
# uv harder.
11-
VENV ?= .venv
12-
13-
# On Windows, venv scripts/shims are under `Scripts` instead of `bin`.
14-
VENV_BIN := $(VENV)/bin
15-
ifeq ($(OS),Windows_NT)
16-
VENV_BIN := $(VENV)/Scripts
17-
endif
18-
19-
# Optionally overridden by the user in the `release` target.
20-
BUMP_ARGS :=
21-
225
# Optionally overridden by the user in the `test` target.
236
TESTS :=
247

25-
# Optionally overridden by the user/CI, to limit the installation to a specific
26-
# subset of development dependencies.
27-
INSTALL_EXTRA := dev
28-
298
# If the user selects a specific test pattern to run, set `pytest` to fail fast
309
# and only run tests that match the pattern.
3110
# Otherwise, run all tests and enable coverage assertions, since we expect
@@ -42,21 +21,14 @@ endif
4221
all:
4322
@echo "Run my targets individually!"
4423

45-
.PHONY: dev
46-
dev: $(VENV)/pyvenv.cfg
47-
4824
{%- if cookiecutter.entry_point %}
4925
.PHONY: run
50-
run: $(VENV)/pyvenv.cfg
26+
run:
5127
uv run {{ cookiecutter.entry_point }} $(ARGS)
5228
{%- endif %}
5329

54-
$(VENV)/pyvenv.cfg: pyproject.toml
55-
uv venv $(VENV)
56-
uv pip install -e '.[$(INSTALL_EXTRA)]'
57-
5830
.PHONY: lint
59-
lint: $(VENV)/pyvenv.cfg
31+
lint:
6032
uv run ruff format --check && \
6133
uv run ruff check && \
6234
uv run mypy
@@ -65,29 +37,25 @@ lint: $(VENV)/pyvenv.cfg
6537
uv run interrogate -c pyproject.toml .
6638
{%- endif %}
6739

68-
.PHONY: reformat
69-
reformat:
40+
.PHONY: format
41+
format:
7042
uv run ruff format && \
7143
uv run ruff check --fix
7244

73-
.PHONY: test tests
74-
test tests: $(VENV)/pyvenv.cfg
45+
.PHONY: test
46+
test:
7547
uv run pytest --cov=$(PY_IMPORT) $(T) $(TEST_ARGS)
7648
uv run coverage report -m $(COV_ARGS)
7749

7850
.PHONY: doc
7951
{%- if cookiecutter.documentation == 'pdoc' %}
80-
doc: $(VENV)/pyvenv.cfg
52+
doc:
8153
uv run pdoc -o html $(PY_IMPORT)
8254
{%- elif cookiecutter.documentation == 'none' %}
8355
doc:
8456
@echo "No documentation set up"
8557
{%- endif %}
8658

87-
.PHONY: package
88-
package: $(VENV)/pyvenv.cfg
59+
.PHONY: build
60+
build:
8961
uv build
90-
91-
.PHONY: edit
92-
edit:
93-
$(EDITOR) $(ALL_PY_SRCS)

{{cookiecutter.project_slug}}/pyproject.toml

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "{{ cookiecutter.project_slug }}"
3-
dynamic = ["version"]
3+
version = "{{ cookiecutter.version }}"
44
description = "{{ cookiecutter.project_description }}"
55
readme = "README.md"
66
license-files = ["LICENSE"]
@@ -20,12 +20,13 @@ classifiers = [
2020
"Programming Language :: Python :: 3",
2121
]
2222
dependencies = []
23-
requires-python = ">=3.9"
23+
requires-python = ">=3.10"
2424

25-
[tool.setuptools.dynamic]
26-
version = { attr = "{{ cookiecutter.__project_import }}.__version__" }
25+
[build-system]
26+
requires = ["uv_build>=0.8.14,<0.9.0"]
27+
build-backend = "uv_build"
2728

28-
[project.optional-dependencies]
29+
[dependency-groups]
2930
doc = [
3031
{%- if cookiecutter.documentation == "pdoc" -%}
3132
"pdoc"
@@ -35,7 +36,7 @@ test = ["pytest", "pytest-cov", "pretend", "coverage[toml]"]
3536
lint = [
3637
# NOTE: ruff is under active development, so we pin conservatively here
3738
# and let Dependabot periodically perform this update.
38-
"ruff ~= 0.6.2",
39+
"ruff ~= 0.12",
3940
"mypy >= 1.0",
4041
"types-html5lib",
4142
"types-requests",
@@ -44,7 +45,11 @@ lint = [
4445
"interrogate",
4546
{%- endif %}
4647
]
47-
dev = ["{{ cookiecutter.project_slug }}[doc,test,lint]", "twine", "build"]
48+
dev = [
49+
{include-group = "doc"},
50+
{include-group = "test"},
51+
{include-group = "lint"},
52+
]
4853

4954
{% if cookiecutter.entry_point -%}
5055
[project.scripts]
@@ -110,3 +115,11 @@ exclude = ["env", "test", "{{ cookiecutter.__project_src_path }}/_cli.py"]
110115
ignore-semiprivate = true
111116
fail-under = 100
112117
{%- endif %}
118+
119+
[tool.uv.sources]
120+
{{ cookiecutter.project_slug }} = { workspace = true }
121+
122+
{%- if cookiecutter.project_namespace_import %}
123+
[tool.uv.build-backend]
124+
module-name = "{{ cookiecutter.__project_import }}"
125+
{%- endif %}

0 commit comments

Comments
 (0)