slop game oder so
This commit is contained in:
@@ -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())
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Kopiert Phaser aus node_modules nach app/static/js/lib/.
|
||||
*
|
||||
* Warum kopieren statt CDN: Das Spiel soll ohne externe Abhängigkeiten laufen
|
||||
* (Offline-Betrieb, Datenschutz, strikte Content-Security-Policy). Die kopierte
|
||||
* Datei wird mit ausgeliefert; auf dem Server ist daher kein Node nötig.
|
||||
*
|
||||
* Aufruf: npm run vendor:phaser
|
||||
*/
|
||||
import { copyFileSync, mkdirSync, readFileSync } from 'node:fs';
|
||||
import { dirname, join } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const source = join(root, 'node_modules', 'phaser');
|
||||
const target = join(root, 'app', 'static', 'js', 'lib');
|
||||
|
||||
const { version } = JSON.parse(readFileSync(join(source, 'package.json'), 'utf8'));
|
||||
if (!version.startsWith('3.')) {
|
||||
throw new Error(`Erwartet wird Phaser 3.x, gefunden: ${version}`);
|
||||
}
|
||||
|
||||
mkdirSync(target, { recursive: true });
|
||||
copyFileSync(join(source, 'dist', 'phaser.min.js'), join(target, 'phaser.min.js'));
|
||||
copyFileSync(join(source, 'LICENSE.md'), join(target, 'PHASER_LICENSE.md'));
|
||||
console.log(`Phaser ${version} nach ${target} kopiert.`);
|
||||
Reference in New Issue
Block a user