Skip to content

Commit 9e69252

Browse files
committed
Migrate template to uv
1 parent 72ca2e3 commit 9e69252

17 files changed

Lines changed: 152 additions & 480 deletions

File tree

README.md

Lines changed: 16 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ The Cookiecutter template will give you:
6565

6666
- a global settings file that all modules can import;
6767

68-
- a `pyproject.toml` file and an initial Poetry lockfile;
68+
- a `pyproject.toml` file and an initial `uv.lock` file;
6969

7070
- a default linter configuration;
7171

@@ -76,7 +76,7 @@ The Cookiecutter template will give you:
7676
- a configuration file for Read the Docs;
7777

7878
- a set of `poe` tasks for running the module scripts, tests and the
79-
linter (for details, run `poetry run poe tasks`);
79+
linter (for details, run `uv run poe tasks`);
8080

8181
- a virtual environment with initial dependencies installed and
8282
ready to use;
@@ -95,117 +95,36 @@ The Cookiecutter template will give you:
9595

9696
To use this Cookiecutter template, you need:
9797

98-
1. The Python version manager `pyenv`.
98+
1. The Python project management tool [uv](https://docs.astral.sh/uv).
9999

100-
2. A system-wide Python installation.
100+
2. Optionally, Cookiecutter version 2.6.0 or newer.
101101

102-
3. Cookiecutter version 2.6.0 or newer.
102+
### Installing uv
103103

104-
4. The Python dependency manager `poetry`.
104+
To install uv, see its
105+
[installation instructions](https://docs.astral.sh/uv/getting-started/installation/).
105106

106-
### Installing pyenv
107-
108-
You need the Python version manager `pyenv` so you can set up your
109-
generated package, and to make sure you can always keep that package
110-
up and running, regardless of your system Python.
111-
112-
#### Installing pyenv on Windows
113-
114-
While `pyenv` doesn’t support Windows, you can use a drop-in
115-
replacement called `pyenv-win`.
116-
117-
To install `pyenv-win` on Windows, go to
118-
[github.com/pyenv-win/pyenv-win](https://github.com/pyenv-win/pyenv-win#installation)
119-
and follow one of the installation methods.
120-
121-
#### Installing pyenv on Linux
122-
123-
To install `pyenv` on Linux or WSL2, first make sure Python 3 is
124-
installed. Then follow the _Basic GitHub Checkout_ method described
125-
at [github.com/pyenv/pyenv](https://github.com/pyenv/pyenv#basic-github-checkout).
126-
127-
#### Installing pyenv on macOS
128-
129-
To install `pyenv` on macOS, run:
130-
131-
```shell
132-
brew install pyenv
133-
```
134-
135-
#### Checking your system-wide pyenv installation
136-
137-
To verify your `pyenv` is working, run:
138-
139-
```shell
140-
pyenv --version
141-
```
142-
143-
### Checking your system-wide Python installation
144-
145-
Make sure you have Python 3.8 or higher installed on your system
146-
and available in your PATH.
147-
148-
To check, run:
149-
150-
```shell
151-
python --version
152-
```
153-
154-
If that fails, try:
107+
To verify uv is working, run:
155108

156109
```shell
157-
python3 --version
110+
uv
158111
```
159112

160-
Proceed after you’ve confirmed one of those to work.
161-
162113
### Installing Cookiecutter
163114

164-
To install Cookiecutter, follow Cookiecutter’s [installation
165-
instructions](https://cookiecutter.readthedocs.io/en/stable/installation.html).
166-
167-
### Installing Poetry
168-
169-
You’ll need `poetry` to manage the generated Python package.
170-
171-
#### Installing Poetry on Windows
172-
173-
To install Poetry on Windows, use one of the
174-
[installation methods](https://python-poetry.org/docs/master/#installing-with-the-official-installer)
175-
described in Poetry’s documentation.
176-
177-
#### Installing Poetry on Linux
178-
179-
If you’re on Linux or WSL2, use your system package manager to
180-
install Poetry.
181-
182-
Alternatively, use one of the
183-
[installation methods](https://python-poetry.org/docs/master/#installing-with-the-official-installer)
184-
described in Poetry’s documentation.
115+
Installing Cookiecutter is optional, because you can run
116+
`uvx cookiecutter` without installing Cookiecutter.
185117

186-
#### Installing Poetry on macOS
187-
188-
To install Poetry on macOS, run:
189-
190-
```shell
191-
brew install poetry
192-
```
193-
194-
#### Checking your Poetry installation
195-
196-
To verify Poetry is working, run:
197-
198-
```shell
199-
poetry --version
200-
```
118+
If you prefer to install Cookiecutter, follow Cookiecutter’s [installation
119+
instructions](https://cookiecutter.readthedocs.io/en/stable/installation.html).
201120

202121
### Basic usage
203122

204123
To run the template generator, make sure you have a working
205124
Cookiecutter installation. Then run:
206125

207126
```shell
208-
cookiecutter gh:claui/cookiecutter-python-package
127+
uvx cookiecutter gh:claui/cookiecutter-python-package
209128
```
210129

211130
### Alternative usage
@@ -221,12 +140,12 @@ abbreviations:
221140
Then, to generate a project, run:
222141
223142
```shell
224-
cookiecutter python
143+
uvx cookiecutter python
225144
```
226145

227146
## License
228147

229-
Copyright (c) 2021 – 2024 Claudia Pellegrino <[email protected]>
148+
Copyright (c) 2021 – 2025 Claudia Pellegrino <[email protected]>
230149

231150
Licensed under the Apache License, Version 2.0 (the "License");
232151
you may not use this file except in compliance with the License.

hooks/post_gen_project.py

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,50 +30,12 @@
3030
{% endif -%}
3131

3232
{%- if cookiecutter.install_dependencies_now == "y" %}
33-
def sysexit_formatted(message: str) -> None:
34-
width = max((len(line) for line in message))
35-
print('', width * '-', *message, width * '-',
36-
file=sys.stderr, sep='\n')
37-
sys.exit()
38-
39-
pyenv_commands = [
40-
'pyenv install -s',
41-
'pyenv exec python -m venv .venv',
42-
]
43-
4433
try:
45-
for pyenv_command in pyenv_commands:
46-
subprocess.run(pyenv_command, check=True, shell=True)
47-
except subprocess.CalledProcessError as e:
48-
sysexit_formatted([
49-
f'Pyenv failed with exit code {e.returncode}.',
50-
'Go to the {{ cookiecutter.pypi_package_name }}'
51-
' directory and re-run:',
52-
*[
53-
f' {command}'
54-
for command in pyenv_commands + ['poetry install']
55-
],
56-
])
57-
58-
poetry_environment = os.environ.copy()
59-
poetry_environment.update({
60-
'LANG': poetry_environment.get('LANG', 'en_US.UTF-8'),
61-
# https://github.com/python-poetry/poetry/issues/1917
62-
'PYTHON_KEYRING_BACKEND': 'keyring.backends.null.Keyring',
63-
})
64-
65-
logger.info('Running poetry. This may take a while.')
66-
try:
67-
subprocess.run(
68-
'poetry install',
69-
env=poetry_environment,
70-
check=True,
71-
shell=True,
72-
stdout=sys.stderr,
73-
)
34+
subprocess.run(['uv', 'python', 'install'], check=True, stdout=sys.stderr)
35+
subprocess.run(['uv', 'lock'], check=True, stdout=sys.stderr)
7436
except subprocess.CalledProcessError as e:
7537
print(
76-
f'Poetry failed with exit code {e.returncode}.',
38+
f'uv failed with exit code {e.returncode}.',
7739
'Fix any issues, then go to the '
7840
'{{ cookiecutter.pypi_package_name }} directory and re-run:',
7941
f' {e.cmd}',

hooks/pre_gen_project.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
== '{{ cookiecutter.first_module_name }}':
3636
sys.exit('Package name and first module name cannot be the same')
3737

38-
if not shutil.which('poetry'):
38+
if not shutil.which('uv'):
3939
sys.exit(
4040
"""
41-
This Cookiecutter template depends on Poetry.
42-
For instructions on how to install Poetry, see `README.md`.
41+
This Cookiecutter template depends on uv.
42+
For instructions on how to install uv, see `README.md`.
4343
"""
4444
)

{{ cookiecutter.pypi_package_name }}/.github/workflows/ci.yml

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ on:
55
- workflow_call
66

77
env:
8-
CI_POETRY_VERSION: "1.7.1"
8+
CI_UV_VERSION: "0.6.9"
99

1010
jobs:
1111
ci-checks:
@@ -15,54 +15,25 @@ jobs:
1515
- name: Check out source tree
1616
uses: actions/checkout@v4
1717

18-
- name: Load cached Poetry installation
19-
id: load-cached-poetry
20-
uses: actions/cache@v4
18+
- name: Install uv
19+
uses: astral-sh/setup-uv@v5
2120
with:
22-
path: ~/.local
23-
key: poetry-release-v{{ '${{' }} env.CI_POETRY_VERSION }}
24-
25-
- name: Update PATH
26-
if: steps.load-cached-poetry.outputs.cache-hit == 'true'
27-
run: |
28-
echo ~/.local/bin >> "${GITHUB_PATH}"
29-
30-
- name: Install Poetry
31-
uses: snok/install-poetry@v1
32-
if: steps.load-cached-poetry.outputs.cache-hit != 'true'
33-
with:
34-
version: {{ '${{' }} env.CI_POETRY_VERSION }}
35-
virtualenvs-create: true
36-
virtualenvs-in-project: true
21+
version: env.CI_UV_VERSION
3722

3823
- name: Print current package version
39-
run: poetry version --no-ansi --no-interaction
40-
41-
- name: Use specified Python version
42-
uses: actions/setup-python@v5
43-
with:
44-
cache: poetry
45-
python-version-file: .python-version
46-
47-
- name: Install dependencies
48-
# See also:
49-
# https://github.com/python-poetry/poetry/issues/7184
50-
run: poetry install --no-ansi --no-interaction --no-root
51-
52-
- name: Install target package
53-
run: poetry install --no-ansi --no-interaction
24+
run: uv tree -d 0
5425

5526
- name: Run static typechecking
56-
run: poetry run poe typecheck
27+
run: uv run poe typecheck
5728

5829
- name: Run linter
59-
run: poetry run poe linter
30+
run: uv run poe linter
6031

6132
- name: Check for formatting style violations not covered by the linter
62-
run: poetry run poe formatcheck
33+
run: uv run poe formatcheck
6334

6435
- name: Run unit tests
65-
run: poetry run poe tests
36+
run: uv run poe tests
6637

6738
- name: Run man page and HTML documentation generator
68-
run: poetry run poe doc
39+
run: uv run poe doc

{{ cookiecutter.pypi_package_name }}/.github/workflows/prepare-release.yml

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ on:
55
inputs:
66
target_version:
77
description: |-
8-
New version number for the release (or a Poetry bump rule)
8+
New version number for the release (or `major`, `minor`, `patch`)
99
required: true
1010

1111
env:
12-
CI_POETRY_VERSION: "1.7.1"
12+
CI_UV_VERSION: "0.6.9"
1313

1414
jobs:
1515
bump-version:
@@ -20,39 +20,24 @@ jobs:
2020
- name: Check out source tree
2121
uses: actions/checkout@v4
2222

23-
- name: Load cached Poetry installation
24-
id: load-cached-poetry
25-
uses: actions/cache@v4
23+
- name: Install uv
24+
uses: astral-sh/setup-uv@v5
2625
with:
27-
path: ~/.local
28-
key: poetry-release-v{{ '${{' }} env.CI_POETRY_VERSION }}
29-
30-
- name: Update PATH
31-
if: steps.load-cached-poetry.outputs.cache-hit == 'true'
32-
run: |
33-
echo ~/.local/bin >> "${GITHUB_PATH}"
34-
35-
- name: Install Poetry
36-
uses: snok/install-poetry@v1
37-
if: steps.load-cached-poetry.outputs.cache-hit != 'true'
38-
with:
39-
version: {{ '${{' }} env.CI_POETRY_VERSION }}
40-
virtualenvs-create: true
41-
virtualenvs-in-project: true
26+
version: env.CI_UV_VERSION
4227

4328
- name: Print current package version
44-
run: poetry version --no-ansi --no-interaction
29+
run: uv tree -d 0
4530

4631
- name: Bump package version
4732
env:
4833
TARGET_VERSION: {{ '${{' }} inputs.target_version }}
49-
run: poetry version --no-ansi --no-interaction "${TARGET_VERSION}"
34+
run: uvx bump-my-version bump "${TARGET_VERSION}"
5035

5136
- id: gather_new_version
5237
name: Gather bumped package version
5338
run: |
5439
env -i >> "${GITHUB_OUTPUT}" \
55-
"new_version=$(poetry version --no-ansi --no-interaction --short)"
40+
"new_version=$(uvx bump-my-version show current_version)"
5641
5742
- name: Print bumped package version
5843
env:

{{ cookiecutter.pypi_package_name }}/.redport/manifest.rpt.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,7 @@
1414
{%- else -%}
1515
"replay": "cookiecutter_replay/{{ cookiecutter._repo_dir.split('/')[-1] }}.json",
1616
{%- endif %}
17-
"patches": [
18-
"patches/disable-install-step.patch"
19-
],
20-
"nextPatches": [
21-
"patches/disable-install-step.patch"
22-
]
17+
"patches": [],
18+
"nextPatches": []
2319
}
2420
}

0 commit comments

Comments
 (0)