Update commands to automatically run pnpm for relevant commands

Signed-off-by: Tobias O <tobias.olenyi@tum.de>
This commit is contained in:
Tobias O
2025-10-02 15:51:23 +13:00
committed by Tobias O
parent be5ff369e0
commit 2fa0be52ef
2 changed files with 148 additions and 0 deletions

View File

@ -0,0 +1,67 @@
"""
Custom collectstatic command that automatically builds CSS first.
Overrides Django's default collectstatic to include pnpm build.
"""
import subprocess
import sys
from pathlib import Path
from django.conf import settings
from django.contrib.staticfiles.management.commands.collectstatic import (
Command as CollectstaticCommand,
)
class Command(CollectstaticCommand):
help = "Collect static files (automatically builds CSS first)"
def handle(self, *args, **options):
"""Build CSS before collecting static files."""
self.stdout.write(self.style.SUCCESS("Building CSS with pnpm..."))
try:
# Run pnpm build
result = subprocess.run(
["pnpm", "run", "build"],
cwd=settings.BASE_DIR,
capture_output=True,
text=True,
timeout=60, # 60 second timeout
)
if result.returncode != 0:
self.stdout.write(self.style.ERROR("✗ CSS build failed:"))
self.stdout.write(result.stderr)
sys.exit(1)
# Verify output.css was created
output_css = Path(settings.BASE_DIR) / "static" / "css" / "output.css"
if not output_css.exists():
self.stdout.write(
self.style.ERROR("✗ CSS build failed: output.css not generated")
)
sys.exit(1)
# Show file size
size_kb = output_css.stat().st_size / 1024
self.stdout.write(
self.style.SUCCESS(f"✓ CSS built successfully ({size_kb:.1f}KB)\n")
)
except FileNotFoundError:
self.stdout.write(
self.style.ERROR(
"✗ Error: pnpm not found. Install pnpm to build CSS.\n"
"See README.md for setup instructions."
)
)
sys.exit(1)
except subprocess.TimeoutExpired:
self.stdout.write(self.style.ERROR("✗ CSS build timed out (>60s)"))
sys.exit(1)
except Exception as e:
self.stdout.write(self.style.ERROR(f"✗ CSS build error: {e}"))
sys.exit(1)
# Run normal collectstatic
super().handle(*args, **options)

View File

@ -0,0 +1,81 @@
"""
Custom runserver command that automatically starts CSS watcher.
Overrides Django's default runserver to include pnpm dev.
"""
import signal
import subprocess
import sys
from django.conf import settings
from django.contrib.staticfiles.management.commands.runserver import (
Command as RunserverCommand,
)
class Command(RunserverCommand):
help = "Run development server with automatic CSS building"
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.css_process = None
def handle(self, *args, **options):
"""Start CSS watcher before running Django dev server."""
self.stdout.write(self.style.SUCCESS("Starting CSS watcher (pnpm dev)..."))
# Start pnpm dev in background
try:
self.css_process = subprocess.Popen(
["pnpm", "run", "dev"],
cwd=settings.BASE_DIR,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
)
self.stdout.write(self.style.SUCCESS("✓ CSS watcher started\n"))
except FileNotFoundError:
self.stdout.write(
self.style.WARNING(
"Warning: pnpm not found. CSS will not be rebuilt automatically.\n"
'Install pnpm or run "pnpm run dev" manually in another terminal.\n'
)
)
except Exception as e:
self.stdout.write(
self.style.WARNING(f"Warning: Could not start CSS watcher: {e}\n")
)
# Register cleanup handler
original_sigint = signal.getsignal(signal.SIGINT)
original_sigterm = signal.getsignal(signal.SIGTERM)
def cleanup(signum, frame):
self.stdout.write("\nShutting down...")
if self.css_process:
self.css_process.terminate()
try:
self.css_process.wait(timeout=5)
self.stdout.write(self.style.SUCCESS("✓ CSS watcher stopped"))
except subprocess.TimeoutExpired:
self.css_process.kill()
# Call original handler
if signum == signal.SIGINT and callable(original_sigint):
original_sigint(signum, frame)
elif signum == signal.SIGTERM and callable(original_sigterm):
original_sigterm(signum, frame)
sys.exit(0)
signal.signal(signal.SIGINT, cleanup)
signal.signal(signal.SIGTERM, cleanup)
# Run Django dev server
try:
super().handle(*args, **options)
finally:
# Cleanup on normal exit
if self.css_process:
self.css_process.terminate()
try:
self.css_process.wait(timeout=5)
except subprocess.TimeoutExpired:
self.css_process.kill()