Add initial project skeleton using djinit to enable rapid development, CI integration, and deployment setup. New Features - Create .djinit with unified project structure and Tailwind/HTMX enabled. - Add .env.sample with default Django, database, and frontend URLs. - Generate comprehensive .gitignore covering Python, Django, OS, and secret files. - Provide Procfile for Gunicorn web process and release migrations. - Scaffold README.md with project overview and features. - Add manage.py enhanced with environ for .env support. - Initialize pyproject.toml with modern metadata and ruff linting config. - Add requirements.txt mirroring dependencies. - Include runtime.txt pinning Python 3.13. - Update uv.lock to lock dependency versions. Enhancements - Upgrade to latest Django 6.0.5 and DRF ecosystem. - Configure ruff with line-length 88 and isort settings. - Use gunicorn with optimal worker configuration. - Include dj-database-url and psycopg binary for robust PostgreSQL connectivity. Bug Fixes - None.
229 lines
5.6 KiB
Makefile
229 lines
5.6 KiB
Makefile
# Justfile for .
|
|
# Task runner for Django development
|
|
# Install just: https://github.com/casey/just
|
|
|
|
# Default task: show available commands
|
|
default:
|
|
@just --list
|
|
|
|
# Run development server
|
|
dev:
|
|
uv run python manage.py runserver
|
|
|
|
# Run development server with custom host and port
|
|
dev-server HOST="0.0.0.0" PORT="8000":
|
|
uv run python manage.py runserver {{ HOST }}:{{ PORT }}
|
|
|
|
# Create migrations for all apps
|
|
makemigrations:
|
|
uv run python manage.py makemigrations
|
|
|
|
# Create migrations for specific app
|
|
makemigrations-app APP:
|
|
uv run python manage.py makemigrations {{ APP }}
|
|
|
|
# Run all migrations
|
|
migrate:
|
|
uv run python manage.py migrate
|
|
|
|
# Reset database (delete all migrations)
|
|
reset-db:
|
|
uv run python manage.py flush --noinput
|
|
uv run python manage.py migrate
|
|
|
|
# Create superuser
|
|
createsuperuser:
|
|
uv run python manage.py createsuperuser
|
|
|
|
# Collect static files
|
|
collectstatic:
|
|
uv run python manage.py collectstatic --noinput
|
|
|
|
# Run Django shell
|
|
shell:
|
|
uv run python manage.py shell
|
|
|
|
# Run Django shell plus (IPython)
|
|
shell-plus:
|
|
uv run python manage.py shell_plus
|
|
|
|
# Run tests
|
|
test:
|
|
uv run python manage.py test
|
|
|
|
# Run tests with coverage
|
|
test-coverage:
|
|
uv run pytest --cov=. --cov-report=html --cov-report=term
|
|
|
|
# Lint code with ruff
|
|
lint:
|
|
uv run ruff check .
|
|
|
|
# Format code with ruff
|
|
format:
|
|
uv run ruff format .
|
|
|
|
# Lint and format code
|
|
style:
|
|
uv run ruff check .
|
|
uv run ruff format .
|
|
|
|
# Check security issues
|
|
check:
|
|
uv run python manage.py check
|
|
|
|
# Check security issues (production settings)
|
|
check-deploy:
|
|
uv run python manage.py check --deploy
|
|
|
|
# Show all database migrations status
|
|
showmigrations:
|
|
uv run python manage.py showmigrations
|
|
|
|
# Sync dependencies (uv equivalent of pip freeze)
|
|
requirements:
|
|
#!/usr/bin/env -S uv run python
|
|
import tomllib
|
|
from pathlib import Path
|
|
pyproject = Path("pyproject.toml")
|
|
if not pyproject.exists():
|
|
print("pyproject.toml not found")
|
|
raise SystemExit(1)
|
|
data = tomllib.loads(pyproject.read_text())
|
|
deps = data.get("project", {}).get("dependencies", [])
|
|
Path("requirements.txt").write_text("\n".join(deps) + "\n")
|
|
print("Generated requirements.txt from pyproject.toml")
|
|
|
|
# Run all linting and checks
|
|
ci:
|
|
uv run ruff check .
|
|
uv run ruff format --check .
|
|
uv run python manage.py check
|
|
|
|
# Start interactive shell
|
|
shell-ipython:
|
|
uv run python manage.py shell_plus
|
|
|
|
# Clear all cache
|
|
clear-cache:
|
|
uv run python manage.py clear_cache
|
|
|
|
# Show Django version
|
|
version:
|
|
uv run python manage.py version
|
|
|
|
# Run database shell
|
|
dbshell:
|
|
uv run python manage.py dbshell
|
|
|
|
# Start production server with gunicorn
|
|
server:
|
|
uv run gunicorn core.wsgi:application --bind 0.0.0.0:8000
|
|
|
|
# Start production server with gunicorn workers
|
|
server-prod WORKERS="4":
|
|
uv run gunicorn core.wsgi:application --bind 0.0.0.0:8000 --workers {{ WORKERS }}
|
|
|
|
# Start production server with gunicorn and reload on file changes
|
|
server-watch:
|
|
uv run gunicorn core.wsgi:application --bind 0.0.0.0:8000 --reload
|
|
|
|
# Clean Python cache files
|
|
clean:
|
|
find . -type d -name "__pycache__" -exec rm -rf {} +
|
|
find . -type f -name "*.pyc" -delete
|
|
find . -type f -name "*.pyo" -delete
|
|
find . -type f -name ".coverage" -delete
|
|
find . -type d -name "*.egg-info" -exec rm -rf {} +
|
|
rm -rf htmlcov/
|
|
rm -rf .pytest_cache/
|
|
|
|
# Pin dependencies in pyproject.toml using versions from uv.lock, keeping >= and extras
|
|
pin-deps:
|
|
#!/usr/bin/env -S uv run python
|
|
import tomllib, re
|
|
from pathlib import Path
|
|
|
|
lock = Path("uv.lock")
|
|
if not lock.exists():
|
|
print("uv.lock not found — run `uv sync` first")
|
|
raise SystemExit(0)
|
|
|
|
data = tomllib.loads(lock.read_text())
|
|
packages = {p["name"].lower(): p["version"] for p in data.get("package", [])}
|
|
|
|
py = Path("pyproject.toml")
|
|
lines = py.read_text().splitlines()
|
|
|
|
pattern = re.compile(r'^(\s*)"([^"]+)"(,?)')
|
|
|
|
out = []
|
|
for line in lines:
|
|
m = pattern.match(line)
|
|
if not m:
|
|
out.append(line)
|
|
continue
|
|
|
|
indent, dep, comma = m.groups()
|
|
|
|
base = dep
|
|
extras = ""
|
|
operator = ">="
|
|
version = None
|
|
|
|
# extras: django[postgres]
|
|
if "[" in base and "]" in base:
|
|
before, after = base.split("[", 1)
|
|
extras = "[" + after.split("]")[0] + "]"
|
|
base = before
|
|
|
|
# detect >= or ==
|
|
if ">=" in dep:
|
|
operator = ">="
|
|
base, version = dep.split(">=")
|
|
base = base.strip()
|
|
elif "==" in dep:
|
|
operator = "=="
|
|
base, version = dep.split("==")
|
|
base = base.strip()
|
|
else:
|
|
base = dep
|
|
|
|
base_lower = base.lower()
|
|
new_version = packages.get(base_lower)
|
|
|
|
if new_version:
|
|
new_dep = f'{base}{extras}{operator}{new_version}'
|
|
line = f'{indent}"{new_dep}"{comma}'
|
|
|
|
out.append(line)
|
|
|
|
py.write_text("\n".join(out) + "\n")
|
|
print("Pinned dependencies (>= preserved, extras preserved).")
|
|
|
|
|
|
# Setup project for development (using uv)
|
|
setup:
|
|
uv sync
|
|
just pin-deps
|
|
uv run python manage.py migrate
|
|
uv run python manage.py createsuperuser
|
|
|
|
# Complete setup including static files
|
|
setup-complete:
|
|
uv sync
|
|
uv run python manage.py migrate
|
|
uv run python manage.py collectstatic --noinput
|
|
uv run python manage.py createsuperuser
|
|
|
|
# Install a new package
|
|
install PACKAGE:
|
|
uv add {{ PACKAGE }}
|
|
|
|
# Install a dev package
|
|
install-dev PACKAGE:
|
|
uv add --dev {{ PACKAGE }}
|
|
|
|
# Remove a package
|
|
remove PACKAGE:
|
|
uv remove {{ PACKAGE }}
|