Skip to content

Commit

Permalink
Switch to uv
Browse files Browse the repository at this point in the history
  • Loading branch information
brianhelba committed Feb 13, 2025
1 parent 3f197ec commit 3e06794
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 74 deletions.
26 changes: 7 additions & 19 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,11 @@ jobs:
with:
# Tags are needed to compute the current version number
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
- name: Install Python packages
run: |
pip install --upgrade pip
pip install tox
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Run tests
run: |
tox
uvx tox
working-directory: django-resonant-settings
test-cookecutter:
runs-on: ubuntu-latest
Expand Down Expand Up @@ -56,20 +50,14 @@ jobs:
with:
# Tags are needed to compute the current version number
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: "{{ cookiecutter.project_slug }}/.python-version"
- name: Install Python packages
run: |
pip install --upgrade pip
pip install cookiecutter tox
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Eject from cookiecutter
run: |
cookiecutter --no-input . project_name=Resonant ${{ matrix.cookiecutter-variables }}
uvx cookiecutter --no-input . project_name=Resonant ${{ matrix.cookiecutter-variables }}
- name: Run tox tests from new project
run: |
tox
uvx tox
env:
DJANGO_DATABASE_URL: postgres://postgres:postgres@localhost:5432/django
DJANGO_CELERY_BROKER_URL: amqp://localhost:5672/
Expand Down
12 changes: 3 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,11 @@ jobs:
with:
# Tags are needed to compute the current version number
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.x"
- name: Install Python build
run: |
pip install --upgrade pip
pip install build
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Build the Python distribution
run: |
python -m build
uv build
working-directory: django-resonant-settings
- name: Publish the Python distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# cookiecutter-resonant

# Creation
* Install [`cookiecutter`](https://pypi.org/project/cookiecutter/)
* Run: `cookiecutter gh:kitware-resonant/cookiecutter-resonant`
* [Install `uv`](https://docs.astral.sh/uv/getting-started/installation/)
* Run: `uvx cookiecutter gh:kitware-resonant/cookiecutter-resonant`
* Fill variables, as documented below.
* This will create a new directory for you.
* In the new directory, initialize Git and connect it to your upstream repository.
Expand Down
6 changes: 6 additions & 0 deletions hooks/post_gen_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import os
import shutil
import subprocess
import sys

EXAMPLE_CODE_REMOVE = [
Expand Down Expand Up @@ -35,9 +36,14 @@ def include_example_code_hook():
sys.exit(1)


def uv_lock_hook():
subprocess.check_call(['uv', 'lock'])


def run_hooks():
if '{{ cookiecutter.include_example_code }}' != 'yes':
include_example_code_hook()
uv_lock_hook()


if __name__ == "__main__":
Expand Down
12 changes: 3 additions & 9 deletions {{ cookiecutter.project_slug }}/.github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version-file: .python-version
- name: Install tox
run: |
pip install --upgrade pip
pip install tox
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Run tests
run: |
tox
uvx tox
env:
DJANGO_DATABASE_URL: postgres://postgres:postgres@localhost:5432/django
DJANGO_CELERY_BROKER_URL: amqp://localhost:5672/
Expand Down
43 changes: 19 additions & 24 deletions {{ cookiecutter.project_slug }}/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
This is the simplest configuration for developers to start with.

### Initial Setup
1. Run `docker compose run --rm django ./manage.py migrate`
2. Run `docker compose run --rm django ./manage.py createsuperuser`
1. Run `docker compose run --rm django uv run ./manage.py migrate`
2. Run `docker compose run --rm django uv run ./manage.py createsuperuser`
and follow the prompts to create your own user

### Run Application
Expand All @@ -18,49 +18,44 @@ Occasionally, new package dependencies or schema changes will necessitate
maintenance. To non-destructively update your development stack at any time:
1. Run `docker compose pull`
2. Run `docker compose build --pull --no-cache`
3. Run `docker compose run --rm django ./manage.py migrate`
3. Run `docker compose run --rm django uv run ./manage.py migrate`

## Develop Natively (advanced)
This configuration still uses Docker to run attached services in the background,
but allows developers to run Python code on their native system.

### Initial Setup
1. Run `docker compose -f ./docker-compose.yml up -d`
2. Install Python 3.13
3. Create and activate a new Python virtualenv
4. Run `pip install -e .[dev]`
5. Run `source ./dev/export-env.sh`
6. Run `./manage.py migrate`
7. Run `./manage.py createsuperuser` and follow the prompts to create your own user
2. [Install `uv`](https://docs.astral.sh/uv/getting-started/installation/)
3. Run `export UV_ENV_FILE=./dev/.env.docker-compose-native`
4. Run `uv run ./manage.py migrate`
5. Run `uv run ./manage.py createsuperuser` and follow the prompts to create your own user

### Run Application
1. Ensure `docker compose -f ./docker-compose.yml up -d` is still active
2. Run:
1. `source ./dev/export-env.sh`
2. `./manage.py runserver`
3. Run in a separate terminal:
1. `source ./dev/export-env.sh`
2. `celery --app {{ cookiecutter.pkg_name }}.celery worker --loglevel INFO --without-heartbeat`
1. Ensure `docker compose -f ./docker-compose.yml up -d` is still active
2. Run: `UV_ENV_FILE=./dev/.env.docker-compose-native uv run ./manage.py runserver`
3. Run in a separate terminal: `UV_ENV_FILE=./dev/.env.docker-compose-native uv run celery --app {{ cookiecutter.pkg_name }}.celery worker --loglevel INFO --without-heartbeat`
4. When finished, run `docker compose stop`
5. To destroy the stack and start fresh, run `docker compose down -v`

## Testing
### Initial Setup
tox is used to execute all tests.
tox is installed automatically with the `dev` package extra.
tox is used to manage the execution of all tests.
[Install `uv`](https://docs.astral.sh/uv/getting-started/installation/) and run tox with
`uvx tox ...`.

When running the "Develop with Docker" configuration, all tox commands must be run as
`docker compose run --rm django tox`; extra arguments may also be appended to this form.
`docker compose run --rm django uvx tox`; extra arguments may also be appended to this form.

### Running Tests
Run `tox` to launch the full test suite.
Run `uvx tox` to launch the full test suite.

Individual test environments may be selectively run.
This also allows additional options to be be added.
Useful sub-commands include:
* `tox -e lint`: Run only the style checks
* `tox -e type`: Run only the type checks
* `tox -e test`: Run only the pytest-driven tests
* `uvx tox -e lint`: Run only the style checks
* `uvx tox -e type`: Run only the type checks
* `uvx tox -e test`: Run only the pytest-driven tests

To automatically reformat all code to comply with
some (but not all) of the style checks, run `tox -e format`.
some (but not all) of the style checks, run `uvx tox -e format`.
11 changes: 5 additions & 6 deletions {{ cookiecutter.project_slug }}/dev/django.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
FROM python:3.13-slim
FROM ghcr.io/astral-sh/uv:debian

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Docker Compose will also mount this at runtime.
RUN --mount=source=.,target=/opt/django-project \
pip install --no-cache-dir --editable /opt/django-project[dev]

# Use a directory name which will never be an import name, as isort considers this as first-party.
WORKDIR /opt/django-project

# Docker Compose will also mount this at runtime.
RUN --mount=source=.,target=. \
uv sync --compile-bytecode --no-cache
7 changes: 2 additions & 5 deletions {{ cookiecutter.project_slug }}/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,15 @@ dependencies = [
"sentry-sdk[celery,django]",
]

[project.optional-dependencies]
[dependency-groups]
dev = [
"django-browser-reload",
"django-debug-toolbar",
"django-minio-storage",
"django-s3-file-field[minio]",
"iptools",
"ipython",
"tox",
{include-group = "type"},
]

[dependency-groups]
lint = [
"flake8",
"flake8-black",
Expand Down
5 changes: 5 additions & 0 deletions {{ cookiecutter.project_slug }}/tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
[tox]
min_version = 4.22
requires =
tox
tox-uv
env_list =
lint,
type,
Expand Down Expand Up @@ -52,6 +55,8 @@ commands =
[flake8]
max-line-length = 100
show-source = True
extend-exclude =
.venv/,
ignore =
# closing bracket does not match indentation of opening bracket’s line
E123
Expand Down

0 comments on commit 3e06794

Please sign in to comment.