""" 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)