migrate to uv

This commit is contained in:
Gabriel Augendre 2025-01-05 11:18:04 +01:00
parent 59a5008617
commit eb3d934960
19 changed files with 1180 additions and 519 deletions

View file

@ -1,5 +1,5 @@
FROM mcr.microsoft.com/devcontainers/python:3.13-bullseye
FROM mcr.microsoft.com/devcontainers/python:3.13-bookworm
RUN apt-get update && apt-get upgrade -y
RUN pip install pip-tools invoke
COPY requirements.in requirements.txt requirements-dev.in requirements-dev.txt constraints.txt tasks.py ./
RUN invoke sync-dependencies
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
COPY pyproject.toml uv.lock tasks.py ./
RUN uv sync --frozen

2
.dockerignore Normal file
View file

@ -0,0 +1,2 @@
.venv
node_modules

View file

@ -14,22 +14,21 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
cache: pip
- name: Install dependencies
run: |
pip install pip-tools
pip-sync requirements.txt requirements-dev.txt
python-version-file: "pyproject.toml"
- name: Install the project
run: uv sync --all-extras --dev --frozen --no-install-project
- name: Setup pre-commit cache
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-3|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
- name: Check pre-commit
run: pre-commit run --show-diff-on-failure --color=always --all-files
run: uv run pre-commit run --show-diff-on-failure --color=always --all-files
- name: Test
run: pytest --cov=. --cov-branch --cov-report term-missing:skip-covered
run: uv run pytest --cov=. --cov-branch --cov-report term-missing:skip-covered
working-directory: ./src/

View file

@ -17,15 +17,15 @@ jobs:
uses: actions/checkout@v4
with:
ref: master
- name: Install uv
uses: astral-sh/setup-uv@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
cache: pip
python-version-file: "pyproject.toml"
- name: Update dependencies
run: |
pip install pip-tools invoke
invoke update-dependencies --no-sync
uv lock --upgrade
- name: Generate token
uses: tibdex/github-app-token@v2
id: generate-token

View file

@ -14,7 +14,7 @@
<array />
</option>
<option name="outputFromStdout" value="false" />
<option name="program" value="$USER_HOME$/.local/pipx/venvs/pre-commit/bin/pre-commit" />
<option name="program" value="$USER_HOME$/.local/bin/pre-commit" />
<option name="runOnExternalChanges" value="false" />
<option name="scopeName" value="Project Files" />
<option name="trackOnlyRoot" value="false" />

View file

@ -1,6 +1,3 @@
[tools]
python = {version="3.13", virtualenv=".venv"}
[env]
ENV_FILE = "{{config_root}}/envs/local-envs.env"
DATABASE_URL = "sqlite:///{{config_root}}/db/db.sqlite3"

View file

@ -1,6 +1,4 @@
exclude: \.min\.(js|css)(\.map)?$|^\.idea/
ci:
skip: [pip-compile]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
@ -62,18 +60,7 @@ repos:
rev: v2.5.0
hooks:
- id: pyproject-fmt
- repo: https://github.com/jazzband/pip-tools
rev: 7.4.1
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.5.13
hooks:
- id: pip-compile
name: pip-compile requirements.txt
args: [-q, --allow-unsafe, --no-strip-extras, requirements.in]
files: ^requirements\.(in|txt)$
- id: pip-compile
name: pip-compile constraints.txt
args: [-q, --allow-unsafe, --strip-extras, --output-file=constraints.txt, requirements.in]
files: ^requirements\.in|constraints\.txt$
- id: pip-compile
name: pip-compile requirements-dev.txt
args: [-q, --allow-unsafe, --no-strip-extras, --constraint=constraints.txt, requirements-dev.in]
files: ^requirements-dev\.(in|txt)$
- id: uv-lock

View file

@ -11,10 +11,26 @@ RUN date +'%Y-%m-%d %H:%M %Z' > /build-date
##############################################
# install python dependencies
##############################################
FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder
ENV UV_COMPILE_BYTECODE=1 UV_LINK_MODE=copy
WORKDIR /app
RUN --mount=type=cache,target=/root/.cache/uv \
--mount=type=bind,source=uv.lock,target=uv.lock \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
uv sync --frozen --no-install-project --no-dev
ADD . /app
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-dev
##############################################
# Main image
##############################################
FROM python:3.13.1-slim-bullseye AS final
FROM python:3.13.1-slim-bookworm AS final
ARG DEBIAN_FRONTEND=noninteractive
@ -32,10 +48,7 @@ RUN apt-get update -y \
# Create directory structure
##############################################
WORKDIR /app
COPY --chown=django:django pyproject.toml requirements.txt ./
ADD --chown=django:django ./src ./src
COPY --chown=django:django tasks.py ./tasks.py
COPY --from=builder --chown=django:django /app /app
RUN mkdir -p /app/data /app/db
RUN chown django:django /app /app/data /app/db
@ -45,7 +58,8 @@ ENV SECRET_KEY "changeme"
ENV DEBUG "false"
ENV DATABASE_URL "sqlite:////app/db/db.sqlite3"
RUN python -m pip install --no-cache-dir -r requirements.txt
ENV PATH="/app/.venv/bin:$PATH"
WORKDIR /app/src
RUN python manage.py collectstatic --noinput --clear

View file

@ -7,8 +7,7 @@ Manage your RPG party & character using an interactive web app accessible from a
## Quick start
Clone, then
```shell
pip install -U pip pip-tools invoke
inv sync-dependencies
uv sync
pre-commit install --install-hooks
inv test
./src/manage.py migrate

View file

@ -1,96 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile --allow-unsafe --output-file=constraints.txt --strip-extras requirements.in
#
asgiref==3.8.1
# via
# django
# django-htmx
attrs==24.3.0
# via
# outcome
# trio
certifi==2024.12.14
# via
# requests
# selenium
charset-normalizer==3.4.1
# via requests
confusable-homoglyphs==3.3.1
# via django-registration
django==5.1.4
# via
# -r requirements.in
# django-anymail
# django-bootstrap5
# django-extensions
# django-htmx
# django-linear-migrations
# django-registration
django-anymail==12.0
# via -r requirements.in
django-bootstrap5==24.3
# via -r requirements.in
django-cleanup==9.0.0
# via -r requirements.in
django-environ==0.11.2
# via -r requirements.in
django-extensions==3.2.3
# via -r requirements.in
django-htmx==1.21.0
# via -r requirements.in
django-linear-migrations==2.16.0
# via -r requirements.in
django-registration==5.1.0
# via -r requirements.in
gunicorn==23.0.0
# via -r requirements.in
h11==0.14.0
# via wsproto
idna==3.10
# via
# requests
# trio
markdown==3.7
# via -r requirements.in
outcome==1.3.0.post0
# via trio
packaging==24.2
# via gunicorn
pillow==11.0.0
# via -r requirements.in
pysocks==1.7.1
# via urllib3
requests==2.32.3
# via
# -r requirements.in
# django-anymail
selenium==4.27.1
# via -r requirements.in
sniffio==1.3.1
# via trio
sortedcontainers==2.4.0
# via trio
sqlparse==0.5.3
# via django
trio==0.28.0
# via
# selenium
# trio-websocket
trio-websocket==0.11.1
# via selenium
typing-extensions==4.12.2
# via selenium
urllib3==2.3.0
# via
# django-anymail
# requests
# selenium
websocket-client==1.8.0
# via selenium
whitenoise==6.8.2
# via -r requirements.in
wsproto==1.2.0
# via trio-websocket

View file

@ -1,5 +1,3 @@
version: "2.4"
services:
django:
extends:

View file

@ -1,5 +1,3 @@
version: "2.4"
services:
django:
build: .

View file

@ -1,9 +1,45 @@
###############################################################################
# pytest
###############################################################################
[project]
name = "charasheet"
version = "0.0.1"
requires-python = ">=3.13"
classifiers = [ "Programming Language :: Python :: 3 :: Only", "Programming Language :: Python :: 3.13" ]
dependencies = [
"django>=4.1",
"django-anymail[mailgun]>=8.6",
"django-bootstrap5>=22.1",
"django-cleanup>=6",
"django-environ>=0.9",
"django-extensions>=3.1.5",
"django-htmx>=1.12.2",
"django-linear-migrations>=2.2",
"django-registration>=3.3",
"gunicorn>=20.1",
"markdown>=3.2",
"pillow>=9.3",
"requests>=2.28.1",
"selenium>=4.5",
"whitenoise>=6.2",
]
[dependency-groups]
dev = [
"black>=22.12",
"bpython>=0.22.1",
"django-browser-reload>=1.6",
"django-debug-toolbar>=3.2",
"hypothesis>=6.56.4",
"invoke>=2",
"model-bakery>=1.3.1",
"pre-commit>=2.1",
"pytest>=6",
"pytest-cov>=3",
"pytest-django>=4.1",
"pytest-selenium>=4",
"ruff>=0.0.237",
]
[tool.ruff]
target-version = "py311"
target-version = "py313"
src = [
"src",
@ -80,6 +116,9 @@ python_files = [
"tests.py",
]
[tool.uv]
package = false
###############################################################################
# ruff
###############################################################################

View file

@ -1,14 +0,0 @@
django-debug-toolbar>=3.2
pytest>=6.0
pytest-cov>=3.0.0
pytest-django>=4.1.0
pytest-selenium>=4.0.0
pre-commit>=2.1
model-bakery>=1.3.1
bpython>=0.22.1
invoke>=2.0.0
hypothesis>=6.56.4
django-browser-reload>=1.6.0
black>=22.12.0
pip-tools>=6.0
ruff>=0.0.237

View file

@ -1,219 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile --allow-unsafe --constraint=constraints.txt requirements-dev.in
#
asgiref==3.8.1
# via
# -c constraints.txt
# django
# django-browser-reload
attrs==24.3.0
# via
# -c constraints.txt
# hypothesis
# outcome
# trio
black==24.10.0
# via -r requirements-dev.in
blessed==1.20.0
# via curtsies
bpython==0.24
# via -r requirements-dev.in
build==1.2.2.post1
# via pip-tools
certifi==2024.12.14
# via
# -c constraints.txt
# requests
# selenium
cfgv==3.4.0
# via pre-commit
charset-normalizer==3.4.1
# via
# -c constraints.txt
# requests
click==8.1.8
# via
# black
# pip-tools
coverage[toml]==7.6.10
# via pytest-cov
curtsies==0.4.2
# via bpython
cwcwidth==0.1.9
# via
# bpython
# curtsies
distlib==0.3.9
# via virtualenv
django==5.1.4
# via
# -c constraints.txt
# django-browser-reload
# django-debug-toolbar
# model-bakery
django-browser-reload==1.17.0
# via -r requirements-dev.in
django-debug-toolbar==4.4.6
# via -r requirements-dev.in
filelock==3.16.1
# via virtualenv
greenlet==3.1.1
# via bpython
h11==0.14.0
# via
# -c constraints.txt
# wsproto
hypothesis==6.123.2
# via -r requirements-dev.in
identify==2.6.4
# via pre-commit
idna==3.10
# via
# -c constraints.txt
# requests
# trio
iniconfig==2.0.0
# via pytest
invoke==2.2.0
# via -r requirements-dev.in
jinja2==3.1.5
# via pytest-html
markupsafe==3.0.2
# via jinja2
model-bakery==1.20.0
# via -r requirements-dev.in
mypy-extensions==1.0.0
# via black
nodeenv==1.9.1
# via pre-commit
outcome==1.3.0.post0
# via
# -c constraints.txt
# trio
packaging==24.2
# via
# -c constraints.txt
# black
# build
# pytest
pathspec==0.12.1
# via black
pip-tools==7.4.1
# via -r requirements-dev.in
platformdirs==4.3.6
# via
# black
# virtualenv
pluggy==1.5.0
# via pytest
pre-commit==4.0.1
# via -r requirements-dev.in
pygments==2.18.0
# via bpython
pyproject-hooks==1.2.0
# via
# build
# pip-tools
pysocks==1.7.1
# via
# -c constraints.txt
# urllib3
pytest==8.3.4
# via
# -r requirements-dev.in
# pytest-base-url
# pytest-cov
# pytest-django
# pytest-html
# pytest-metadata
# pytest-selenium
# pytest-variables
pytest-base-url==2.1.0
# via pytest-selenium
pytest-cov==6.0.0
# via -r requirements-dev.in
pytest-django==4.9.0
# via -r requirements-dev.in
pytest-html==4.1.1
# via pytest-selenium
pytest-metadata==3.1.1
# via pytest-html
pytest-selenium==4.1.0
# via -r requirements-dev.in
pytest-variables==3.1.0
# via pytest-selenium
pyxdg==0.28
# via bpython
pyyaml==6.0.2
# via pre-commit
requests==2.32.3
# via
# -c constraints.txt
# bpython
# pytest-base-url
# pytest-selenium
ruff==0.8.4
# via -r requirements-dev.in
selenium==4.27.1
# via
# -c constraints.txt
# pytest-selenium
six==1.17.0
# via blessed
sniffio==1.3.1
# via
# -c constraints.txt
# trio
sortedcontainers==2.4.0
# via
# -c constraints.txt
# hypothesis
# trio
sqlparse==0.5.3
# via
# -c constraints.txt
# django
# django-debug-toolbar
tenacity==9.0.0
# via pytest-selenium
trio==0.28.0
# via
# -c constraints.txt
# selenium
# trio-websocket
trio-websocket==0.11.1
# via
# -c constraints.txt
# selenium
typing-extensions==4.12.2
# via
# -c constraints.txt
# selenium
urllib3[socks]==2.3.0
# via
# -c constraints.txt
# requests
# selenium
virtualenv==20.28.0
# via pre-commit
wcwidth==0.2.13
# via blessed
websocket-client==1.8.0
# via
# -c constraints.txt
# selenium
wheel==0.45.1
# via pip-tools
wsproto==1.2.0
# via
# -c constraints.txt
# trio-websocket
# The following packages are considered to be unsafe in a requirements file:
pip==24.3.1
# via pip-tools
setuptools==75.6.0
# via pip-tools

View file

@ -1,15 +0,0 @@
django>=4.1
django-cleanup>=6.0
django-environ>=0.9.0
django-htmx>=1.12.2
django-linear-migrations>=2.2.0
django-extensions>=3.1.5
whitenoise>=6.2
selenium>=4.5.0
Markdown>=3.2
django-registration>=3.3
django-anymail[mailgun]>=8.6
django-bootstrap5>=22.1
requests>=2.28.1
gunicorn>=20.1.0
Pillow>=9.3.0

View file

@ -1,96 +0,0 @@
#
# This file is autogenerated by pip-compile with Python 3.13
# by the following command:
#
# pip-compile --allow-unsafe requirements.in
#
asgiref==3.8.1
# via
# django
# django-htmx
attrs==24.3.0
# via
# outcome
# trio
certifi==2024.12.14
# via
# requests
# selenium
charset-normalizer==3.4.1
# via requests
confusable-homoglyphs==3.3.1
# via django-registration
django==5.1.4
# via
# -r requirements.in
# django-anymail
# django-bootstrap5
# django-extensions
# django-htmx
# django-linear-migrations
# django-registration
django-anymail[mailgun]==12.0
# via -r requirements.in
django-bootstrap5==24.3
# via -r requirements.in
django-cleanup==9.0.0
# via -r requirements.in
django-environ==0.11.2
# via -r requirements.in
django-extensions==3.2.3
# via -r requirements.in
django-htmx==1.21.0
# via -r requirements.in
django-linear-migrations==2.16.0
# via -r requirements.in
django-registration==5.1.0
# via -r requirements.in
gunicorn==23.0.0
# via -r requirements.in
h11==0.14.0
# via wsproto
idna==3.10
# via
# requests
# trio
markdown==3.7
# via -r requirements.in
outcome==1.3.0.post0
# via trio
packaging==24.2
# via gunicorn
pillow==11.0.0
# via -r requirements.in
pysocks==1.7.1
# via urllib3
requests==2.32.3
# via
# -r requirements.in
# django-anymail
selenium==4.27.1
# via -r requirements.in
sniffio==1.3.1
# via trio
sortedcontainers==2.4.0
# via trio
sqlparse==0.5.3
# via django
trio==0.28.0
# via
# selenium
# trio-websocket
trio-websocket==0.11.1
# via selenium
typing-extensions==4.12.2
# via selenium
urllib3[socks]==2.3.0
# via
# django-anymail
# requests
# selenium
websocket-client==1.8.0
# via selenium
whitenoise==6.8.2
# via -r requirements.in
wsproto==1.2.0
# via trio-websocket

View file

@ -10,39 +10,15 @@ TEST_ENV = {"ENV_FILE": BASE_DIR / "envs" / "test-envs.env"}
@task
def update_dependencies(ctx: Context, *, sync: bool = True):
return compile_dependencies(ctx, update=True, sync=sync)
@task
def compile_dependencies(ctx: Context, *, update: bool = False, sync: bool = False):
common_args = "-q --allow-unsafe"
if update:
common_args += " --upgrade"
def update_dependencies(ctx: Context):
with ctx.cd(BASE_DIR):
ctx.run(
f"pip-compile {common_args} --no-strip-extras requirements.in",
pty=True,
echo=True,
)
ctx.run(
f"pip-compile {common_args} --strip-extras -o constraints.txt requirements.in",
pty=True,
echo=True,
)
ctx.run(
f"pip-compile {common_args} --no-strip-extras -c constraints.txt requirements-dev.in",
pty=True,
echo=True,
)
if sync:
sync_dependencies(ctx)
ctx.run("uv lock --upgrade", pty=True, echo=True)
@task
def sync_dependencies(ctx: Context):
with ctx.cd(BASE_DIR):
ctx.run("pip-sync requirements.txt requirements-dev.txt", pty=True, echo=True)
ctx.run("uv sync", pty=True, echo=True)
@task

1092
uv.lock generated Normal file

File diff suppressed because it is too large Load diff