Skip to content

Commit e561226

Browse files
committed
Apply changes from cookiecutter-python-package
1 parent 7b94d3d commit e561226

51 files changed

Lines changed: 3256 additions & 763 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/dependabot.yml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,9 @@ updates:
44
directory: /
55
schedule:
66
interval: monthly
7-
commit-message:
8-
prefix: ":pushpin: "
7+
cooldown:
8+
default-days: 7
9+
groups:
10+
github-actions:
11+
patterns:
12+
- "*"

‎.github/workflows/input-for-demo.txt‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ steven@vandegraaf.xyz
88
sgraaf
99

1010

11-
11+
1
1212
4
13-
2
13+
1414
2

‎.github/workflows/update_demo.yml‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,20 @@ jobs:
1515
runs-on: ubuntu-latest
1616
steps:
1717
- name: Checkout ${{ env.TEMPLATE }}
18-
uses: actions/checkout@v4
18+
uses: actions/checkout@v7
1919
with:
2020
path: ${{ env.TEMPLATE }}
2121

2222
- name: Checkout ${{ env.DEMO }}
23-
uses: actions/checkout@v4
23+
uses: actions/checkout@v7
2424
with:
2525
repository: "sgraaf/${{ env.DEMO }}"
2626
token: ${{ secrets.X_GITHUB_PAT }}
2727
path: ${{ env.CURRENT_DEMO }}
2828

2929
- name: Install the latest version of uv with caching enabled
3030
id: setup-uv
31-
uses: astral-sh/setup-uv@v5
31+
uses: astral-sh/setup-uv@v10.1.0
3232
with:
3333
enable-cache: true
3434

@@ -39,8 +39,10 @@ jobs:
3939
4040
- name: Commit and push changes
4141
run: |
42-
mv "${{ env.CURRENT_DEMO }}/.git" "${{ env.DEMO }}"
43-
cd "${{ env.DEMO }}"
42+
# Sync the generated files into the checkout rather than moving `.git`: `actions/checkout` persists the
43+
# credentials via an `includeIf "gitdir:..."` entry, which no longer matches once `.git` has been moved
44+
rsync -a --delete --exclude .git "${{ env.DEMO }}/" "${{ env.CURRENT_DEMO }}/"
45+
cd "${{ env.CURRENT_DEMO }}"
4446
git config user.name "Automated"
4547
git config user.email "actions@users.noreply.github.com"
4648
git add -A
@@ -58,4 +60,4 @@ jobs:
5860
-H "X-GitHub-Api-Version: 2022-11-28" \
5961
"$GITHUB_API_URL/repos/$GITHUB_REPOSITORY/commits/$GITHUB_SHA/comments" \
6062
-d @-
61-
working-directory: ${{ env.DEMO }}
63+
working-directory: ${{ env.CURRENT_DEMO }}

‎.pre-commit-config.yaml‎

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,44 @@
1-
ci:
2-
autofix_commit_msg: |
3-
:art: [pre-commit.ci] auto fixes from pre-commit.com hooks
4-
5-
for more information, see https://pre-commit.ci
6-
autoupdate_schedule: quarterly
7-
autoupdate_commit_msg: ":arrow_up: [pre-commit.ci] pre-commit autoupdate"
8-
9-
exclude: "^{{ cookiecutter\\.app_name }}/"
1+
exclude: "^{{ cookiecutter.app_name }}/"
102

113
repos:
124
- repo: https://github.com/pre-commit/pre-commit-hooks
13-
rev: v5.0.0
5+
rev: v6.0.0
146
hooks:
157
- id: check-added-large-files
168
- id: check-json
179
- id: check-toml
1810
- id: check-yaml
1911
- id: end-of-file-fixer
2012
- id: trailing-whitespace
13+
- repo: https://github.com/abravalheri/validate-pyproject
14+
rev: "0.26"
15+
hooks:
16+
- id: validate-pyproject
17+
additional_dependencies: ["validate-pyproject-schema-store[all]"]
2118
- repo: https://github.com/python-jsonschema/check-jsonschema
22-
rev: 0.33.2
19+
rev: 0.38.0
2320
hooks:
2421
- id: check-dependabot
2522
- id: check-github-workflows
26-
- repo: https://github.com/charliermarsh/ruff-pre-commit
27-
rev: v0.12.3
23+
- repo: https://github.com/astral-sh/ruff-pre-commit
24+
rev: v0.16.8
2825
hooks:
2926
- id: ruff-check
3027
args:
3128
- --fix
3229
- --unsafe-fixes
3330
- --show-fixes
3431
- id: ruff-format
32+
- repo: https://github.com/codespell-project/codespell
33+
rev: v2.4.3
34+
hooks:
35+
- id: codespell
36+
- repo: https://github.com/hukkin/mdformat
37+
rev: 1.0.0
38+
hooks:
39+
- id: mdformat
3540
- repo: https://github.com/rbubley/mirrors-prettier
36-
rev: v3.6.2
41+
rev: v3.9.7
3742
hooks:
3843
- id: prettier
44+
types: [yaml]

‎README.md‎

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,34 @@
11
# cookiecutter-python-cli-app
22

3-
[![Supported Python Versions](https://img.shields.io/badge/python-3.9%20|%203.10%20|%203.11%20|%203.12%20|%203.13-blue)](https://github.com/sgraaf/cookiecutter-python-cli-app)
4-
[![Nox](https://img.shields.io/badge/%F0%9F%A6%8A-Nox-D85E00.svg)](https://github.com/wntrblm/nox)
3+
[![Supported Python Versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12%20%7C%203.13%20%7C%203.14-blue)](https://github.com/sgraaf/cookiecutter-python-cli-app)
54
[![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)
5+
[![prek](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/j178/prek/master/docs/assets/badge-v0.json)](https://github.com/j178/prek)
66
[![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)
7-
[![Checked with mypy](http://www.mypy-lang.org/static/mypy_badge.svg)](http://mypy-lang.org/)
8-
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
7+
[![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)
98

109
A [cookiecutter](https://cookiecutter.readthedocs.io/) template for creating a new Python command-line application with [Click](https://click.palletsprojects.com/).
1110

1211
See https://github.com/sgraaf/cookiecutter-python-cli-app-demo for a demo of this template.
1312

1413
## Usage
1514

16-
```sh
15+
```shell
1716
cookiecutter gh:sgraaf/cookiecutter-python-cli-app
1817
```
1918

2019
## Features
2120

22-
<!-- TODO: mention optional use of rich, choice of licenses, git and venv initialization -->
23-
24-
- Beautiful and powerful command-line interfaces with [Click](https://click.palletsprojects.com/)
25-
- Linting with autofix (i.e. removing unused imports, formatting and Python syntax upgrades) with [ruff](https://beta.ruff.rs/docs/)
26-
- Code formatting with [ruff](https://beta.ruff.rs/docs/) and [Prettier](https://prettier.io/)
27-
- Static type-checking with [mypy](http://www.mypy-lang.org/)
28-
- Checks and fixes before every commit with [pre-commit](https://pre-commit.com/)
29-
- Testing with [pytest](https://docs.pytest.org/en/stable/index.html)
30-
- Project automation with [Nox](https://nox.thea.codes/en/stable/)
21+
- Beautiful and powerful command-line interfaces with [Click](https://click.palletsprojects.com/), optionally enhanced with [rich-click](https://ewels.github.io/rich-click/)
22+
- Linting with autofix (i.e. removing unused imports, detecting code smells and Python syntax upgrades) with [Ruff](https://docs.astral.sh/ruff/)
23+
- Code formatting with [Ruff](https://docs.astral.sh/ruff/), [Mdformat](https://mdformat.readthedocs.io/en/stable/) and [Prettier](https://prettier.io/)
24+
- Static type-checking [ty](https://docs.astral.sh/ty/) for the entire project, and with [mypy](http://www.mypy-lang.org/), [Pyrefly](https://pyrefly.org/), [Pyright](https://microsoft.github.io/pyright/#/) and [Zuban](https://zubanls.com/) for the public API (i.e., the test suite)
25+
- Checks and fixes before every commit with [prek](https://prek.j178.dev/)
26+
- Testing with [pytest](https://docs.pytest.org/en/stable/)
3127
- Extremely fast Python package and project management with [uv](https://docs.astral.sh/uv/)
32-
- Continuous Integration with [GitHub Actions](https://github.com/features/actions) and [pre-commit.ci](https://pre-commit.ci/)
28+
- Continuous Integration with [GitHub Actions](https://github.com/features/actions)
3329
- Automated version updates for GitHub Actions with [Dependabot](https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot)
34-
- Documentation with [Sphinx](https://www.sphinx-doc.org/en/master/), [MyST](https://myst-parser.readthedocs.io/en/latest/), and [Read the Docs](https://readthedocs.org/) using the [Furo](https://pradyunsg.me/furo/) theme
30+
- Documentation with [Sphinx](https://www.sphinx-doc.org/en/master/), [MyST](https://myst-parser.readthedocs.io/en/latest/) and [Read the Docs](https://readthedocs.org/), using the [Furo](https://pradyunsg.me/furo/) theme, with an always up-to-date CLI reference courtesy of [cog](https://cog.readthedocs.io/en/latest/)
31+
- A choice of 15 licenses, and optional Git repository initialization
3532
- Automated release builds and uploads to [PyPI](https://pypi.org/)
3633

37-
This template supports Python 3.9, 3.10, 3.11, 3.12 and 3.13.
34+
This template supports Python 3.10, 3.11, 3.12, 3.13 and 3.14.

‎cookiecutter.json‎

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,21 @@
1010
"version": "{% now 'utc', '%Y' %}.1.0",
1111
"copyright_year": "{% now 'utc', '%Y' %}",
1212
"license": [
13-
"mit",
14-
"gpl-3.0",
15-
"apache-2.0",
16-
"gpl-2.0",
17-
"bsd-3-clause",
18-
"agpl-3.0",
19-
"unlicense"
13+
"MIT",
14+
"Apache-2.0",
15+
"GPL-3.0-only",
16+
"AGPL-3.0-only",
17+
"BSD-3-Clause",
18+
"GPL-3.0-or-later",
19+
"LGPL-3.0-only",
20+
"AGPL-3.0-or-later",
21+
"GPL-2.0-only",
22+
"BSD-2-Clause",
23+
"MPL-2.0",
24+
"LGPL-3.0-or-later",
25+
"GPL-2.0-or-later",
26+
"ISC",
27+
"Unlicense"
2028
],
2129
"development_status": [
2230
"Development Status :: 1 - Planning",
@@ -27,28 +35,42 @@
2735
"Development Status :: 6 - Mature",
2836
"Development Status :: 7 - Inactive"
2937
],
38+
"min_python_version": [
39+
"3.10",
40+
"3.11",
41+
"3.12",
42+
"3.13",
43+
"3.14"
44+
],
3045
"init_git": [true, false],
31-
"init_venv": [true, false],
3246
"__prompts__": {
3347
"friendly_name": "The friendly name of your app (for use in documentation, etc.)",
3448
"app_name": "The name (slug) of your app",
3549
"package_name": "The name of your package",
36-
"short_description": "A short description of your projec",
37-
"use_rich": "Use [link=https://github.com/Textualize/rich]Rich[/link] for rich text and beautiful formatting in the terminal",
50+
"short_description": "A short description of your app",
51+
"use_rich": "Use [link=https://github.com/ewels/rich-click]rich-click[/link] for rich text and beautiful formatting in the terminal",
3852
"author": "Your (full) name",
39-
"email": "Your e-mail address",
53+
"email": "Your email address",
4054
"github_username": "Your GitHub username or organization",
4155
"version": "The version of your package",
4256
"copyright_year": "The copyright year of your package",
4357
"license": {
4458
"__prompt__": "Choose a license for your package",
45-
"mit": "MIT",
46-
"gpl-3.0": "GNU General Public License v3.0",
47-
"apache-2.0": "Apache license 2.0",
48-
"gpl-2.0": "GNU General Public License v2.0",
49-
"bsd-3-clause": "BSD 3-clause \"New\" or \"Revised\" license",
50-
"agpl-3.0": "GNU Affero General Public License v3.0",
51-
"unlicense": "The Unlicense"
59+
"MIT": "MIT License",
60+
"Apache-2.0": "Apache License 2.0",
61+
"GPL-3.0-only": "GNU General Public License v3.0 only",
62+
"AGPL-3.0-only": "GNU Affero General Public License v3.0 only",
63+
"BSD-3-Clause": "BSD 3-Clause \"New\" or \"Revised\" License",
64+
"GPL-3.0-or-later": "GNU General Public License v3.0 or later",
65+
"LGPL-3.0-only": "GNU Lesser General Public License v3.0 only",
66+
"AGPL-3.0-or-later": "GNU Affero General Public License v3.0 or later",
67+
"GPL-2.0-only": "GNU General Public License v2.0 only",
68+
"BSD-2-Clause": "BSD 2-Clause \"Simplified\" License",
69+
"MPL-2.0": "Mozilla Public License 2.0",
70+
"LGPL-3.0-or-later": "GNU Lesser General Public License v3.0 or later",
71+
"GPL-2.0-or-later": "GNU General Public License v2.0 or later",
72+
"ISC": "ISC License",
73+
"Unlicense": "The Unlicense"
5274
},
5375
"development_status": {
5476
"__prompt__": "Choose a development status for your package",
@@ -60,7 +82,14 @@
6082
"Development Status :: 6 - Mature": "Mature",
6183
"Development Status :: 7 - Inactive": "Inactive"
6284
},
63-
"init_venv": "Initialize a virtual environment (venv)",
85+
"min_python_version": {
86+
"__prompt__": "Choose the minimum Python version for your package",
87+
"3.10": "Python 3.10",
88+
"3.11": "Python 3.11",
89+
"3.12": "Python 3.12",
90+
"3.13": "Python 3.13",
91+
"3.14": "Python 3.14"
92+
},
6493
"init_git": "Initialize a Git repository"
6594
}
6695
}

‎hooks/post_gen_project.py‎

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,66 @@
11
import shutil
22
import subprocess
33
import sys
4+
from functools import partial
45

6+
run = partial(subprocess.run, check=False)
57

6-
def possibly_install_uv() -> None:
7-
if shutil.which("uv") is None:
8-
# install uv
9-
subprocess.run(
10-
[sys.executable, "-m", "pip", "install", "--user", "uv"], check=False
11-
)
128

9+
def possibly_install_pipx() -> None:
10+
if shutil.which("pipx") is None:
11+
# install pipx
12+
run([sys.executable, "-m", "pip", "install", "--user", "pipx"])
13+
# add pipx to PATH
14+
run([sys.executable, "-m", "pipx", "ensurepath"])
1315

14-
def possibly_install_nox() -> None:
15-
if shutil.which("nox") is None:
16-
# possibly install uv
17-
possibly_install_uv()
1816

19-
# install nox
20-
subprocess.run(["uv", "tool", "install", "nox"], check=False)
17+
def possibly_install_uv() -> None:
18+
if shutil.which("uv") is None:
19+
# possibly install pipx
20+
possibly_install_pipx()
2121

22+
# install uv
23+
run([sys.executable, "-m", "pipx", "install", "uv"])
2224

23-
def possibly_install_pre_commit() -> None:
24-
if shutil.which("pre-commit") is None:
25-
# possibly install uv
26-
possibly_install_uv()
2725

28-
# install pre-commit
29-
subprocess.run(
30-
["uv", "tool", "install", "pre-commit", "--with", "pre-commit-uv"],
31-
check=False,
32-
)
26+
def initialize_venv() -> None:
27+
# create virtual environment and install dependencies
28+
run(["uv", "sync", "--dev"])
3329

3430

3531
def initialize_git_repository() -> None:
3632
# initialize Git repository
37-
subprocess.run(["git", "init", "-b", "main"], check=False)
33+
run(["git", "init", "-b", "main"])
3834

3935
# update and install pre-commit hooks
40-
subprocess.run(["pre-commit", "autoupdate"], check=False)
41-
subprocess.run(["pre-commit", "install", "--install-hooks"], check=False)
36+
run(["uv", "run", "prek", "update"])
37+
run(["uv", "run", "prek", "install", "--prepare-hooks"])
4238

4339
# add files
44-
subprocess.run(["git", "add", "."], check=False)
40+
run(["git", "add", "."])
4541

46-
# run nox "cog" and "pre-commit" sessions
47-
subprocess.run(["nox", "--session", "cog", "pre-commit"], check=False)
42+
# run the pre-commit hooks (which, amongst others, runs cog)
43+
run(["uv", "run", "prek", "run", "--all-files"])
4844

4945
# possibly re-add files
50-
subprocess.run(["git", "add", "."], check=False)
46+
run(["git", "add", "."])
5147

5248
# commit
53-
subprocess.run(
49+
run(
5450
[
5551
"git",
5652
"commit",
5753
"-m",
58-
":cookie: Initial commit from `cookiecutter-python-cli-app`",
54+
"Initial commit from `cookiecutter-python-cli-app`",
5955
],
60-
check=False,
6156
)
6257

6358

64-
def initialize_venv() -> None:
65-
# run nox "dev" session
66-
subprocess.run(["nox", "--session", "dev"], check=False)
67-
68-
6959
if __name__ == "__main__":
70-
# possibly install nox (and uv)
71-
possibly_install_nox()
72-
# possibly install pre-commit (and uv)
73-
possibly_install_pre_commit()
60+
# possibly install uv (and pipx)
61+
possibly_install_uv()
62+
# create venv and install dependencies
63+
initialize_venv()
7464
# perform git initialization
7565
if "{{ cookiecutter.init_git }}" == "True":
7666
initialize_git_repository()
77-
# create venv and install dependencies
78-
if "{{ cookiecutter.init_venv }}" == "True":
79-
initialize_venv()

0 commit comments

Comments
 (0)