slop game oder so

This commit is contained in:
2026-09-24 17:57:54 +02:00
commit 4c997eee21
166 changed files with 14976 additions and 0 deletions
+72
View File
@@ -0,0 +1,72 @@
"""Baut das Upload-Paket für cPanel: nur die Dateien, die der Server braucht.
Aufruf (im Projektordner, beliebiges Betriebssystem)::
python scripts/build_deploy_zip.py # -> dist/glory_defense.zip
python scripts/build_deploy_zip.py -o paket.zip
Warum ein eigenes Skript statt „ZIP-Datei erstellen“: Windows PowerShell 5.1
(`Compress-Archive`) schreibt Pfade mit Backslash ins Archiv. Manche Entpacker unter
Linux erzeugen daraus flache Dateinamen wie ``app\\api.py`` – dann findet Passenger
das Paket ``app`` nicht. Außerdem landen hier garantiert weder ``.env`` (Geheimnisse)
noch ``instance/`` (Datenbank) noch Caches im Paket.
"""
from __future__ import annotations
import argparse
import sys
import zipfile
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent
DEFAULT_OUTPUT = PROJECT_ROOT / "dist" / "glory_defense.zip"
#: Einzeldateien und Ordner, die auf den Server gehören.
INCLUDE_FILES = ("passenger_wsgi.py", "requirements.txt", ".env.example")
INCLUDE_DIRS = ("app",)
#: Wird nie mitgepackt, auch wenn es unterhalb von INCLUDE_DIRS liegt.
EXCLUDED_DIR_NAMES = frozenset({"__pycache__", ".pytest_cache", ".ruff_cache", "node_modules"})
EXCLUDED_SUFFIXES = frozenset({".pyc", ".pyo"})
def iter_deploy_files(root: Path = PROJECT_ROOT) -> list[Path]:
"""Alle Dateien des Upload-Pakets, sortiert (für reproduzierbare Archive)."""
files = [root / name for name in INCLUDE_FILES if (root / name).is_file()]
for directory in INCLUDE_DIRS:
for path in (root / directory).rglob("*"):
relative_parts = path.relative_to(root).parts
if not path.is_file() or EXCLUDED_DIR_NAMES.intersection(relative_parts):
continue
if path.suffix in EXCLUDED_SUFFIXES:
continue
files.append(path)
return sorted(files)
def build_zip(target: Path, root: Path = PROJECT_ROOT) -> list[str]:
"""Schreibt das ZIP und gibt die enthaltenen Pfade (mit ``/``) zurück."""
target.parent.mkdir(parents=True, exist_ok=True)
names = []
with zipfile.ZipFile(target, "w", compression=zipfile.ZIP_DEFLATED) as archive:
for path in iter_deploy_files(root):
# as_posix(): immer „/“ als Trenner, unabhängig vom Betriebssystem.
name = path.relative_to(root).as_posix()
archive.write(path, name)
names.append(name)
return names
def main(argv: list[str] | None = None) -> int:
"""Kommandozeilen-Einstieg."""
parser = argparse.ArgumentParser(description="Upload-Paket für cPanel bauen.")
parser.add_argument("-o", "--output", type=Path, default=DEFAULT_OUTPUT, help="Ziel-ZIP")
args = parser.parse_args(argv)
names = build_zip(args.output)
size_kb = args.output.stat().st_size / 1024
print(f"{args.output} erstellt: {len(names)} Dateien, {size_kb:.0f} KB")
return 0
if __name__ == "__main__":
sys.exit(main())