Merge pull request 'Fix #196: scripts/ nach Ausführungsort aufgeräumt (Host / Container / intern)' (#199) from fds2610-bot/Steuerkram:main into main
Reviewed-on: https://codeberg.org/fds2610/Steuerkram/pulls/199
This commit is contained in:
commit
aa5ab7c06d
29 changed files with 113 additions and 146 deletions
16
CLAUDE.md
16
CLAUDE.md
|
|
@ -56,9 +56,9 @@ Tests liegen in `tests/` und folgen dem Namensschema `NN_FunktionsnameTest.php`.
|
||||||
Jede Testklasse erweitert `TestCase` und implementiert `run()`.
|
Jede Testklasse erweitert `TestCase` und implementiert `run()`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec -u www-data web php tests/run.php # alle Tests ausführen
|
./scripts/test.sh # alle Tests ausführen
|
||||||
docker compose exec -u www-data web ./scripts/run-tests.sh # Tests + automatische Issue-Erstellung bei Fehlern
|
docker compose exec -u www-data web ./scripts/container/run-tests.sh # Tests + automatische Issue-Erstellung bei Fehlern
|
||||||
docker compose exec -u www-data web ./scripts/run-tests.sh 42 # Tests; bei Fehlern Kommentar in Issue #42
|
docker compose exec -u www-data web ./scripts/container/run-tests.sh 42 # Tests; bei Fehlern Kommentar in Issue #42
|
||||||
```
|
```
|
||||||
|
|
||||||
**Immer `-u www-data`:** ohne die Option laufen die Tests als root und legen
|
**Immer `-u www-data`:** ohne die Option laufen die Tests als root und legen
|
||||||
|
|
@ -97,9 +97,9 @@ es Playwright-Tests in `tests/e2e/`, die im Container des e2e-runner laufen
|
||||||
(auf dem Host wird nichts installiert). Details: `tests/e2e/README.md`.
|
(auf dem Host wird nichts installiert). Details: `tests/e2e/README.md`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/e2e-user.php # einmalig: Testnutzer anlegen
|
docker compose exec web php scripts/container/e2e-user.php # einmalig: Testnutzer anlegen
|
||||||
tests/e2e/run.sh # alle E2E-Tests
|
./scripts/e2e.sh # alle E2E-Tests
|
||||||
docker compose exec web php scripts/e2e-cleanup.php --force # Reste entfernen
|
docker compose exec web php scripts/container/e2e-cleanup.php --force # Reste entfernen
|
||||||
```
|
```
|
||||||
|
|
||||||
Fehlt Docker, der Runner oder das Image, wird mit Exit 0 übersprungen.
|
Fehlt Docker, der Runner oder das Image, wird mit Exit 0 übersprungen.
|
||||||
|
|
@ -123,7 +123,7 @@ Redirects, gerenderte Views, JavaScript-Umrechnungen, DOM-XSS.
|
||||||
Schemaänderungen (neue Spalten, Tabellen, Kontenanpassungen) kommen **ausschließlich** als nummerierte Migrations-Datei in `migrations/`:
|
Schemaänderungen (neue Spalten, Tabellen, Kontenanpassungen) kommen **ausschließlich** als nummerierte Migrations-Datei in `migrations/`:
|
||||||
|
|
||||||
- Schema: `NNN_kurze_beschreibung.sql` (NNN = nächste freie dreistellige Nummer, z.B. `011_...`)
|
- Schema: `NNN_kurze_beschreibung.sql` (NNN = nächste freie dreistellige Nummer, z.B. `011_...`)
|
||||||
- Migrationen werden **nie manuell** eingespielt – `scripts/migrate.php` erledigt das automatisch beim Container-Start
|
- Migrationen werden **nie manuell** eingespielt – `scripts/intern/migrate.php` erledigt das automatisch beim Container-Start
|
||||||
- Jede Migration muss idempotent sein oder mit `IF NOT EXISTS` / `ON DUPLICATE KEY` abgesichert werden
|
- Jede Migration muss idempotent sein oder mit `IF NOT EXISTS` / `ON DUPLICATE KEY` abgesichert werden
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
|
@ -131,7 +131,7 @@ Schemaänderungen (neue Spalten, Tabellen, Kontenanpassungen) kommen **ausschlie
|
||||||
ls migrations/ | tail -1
|
ls migrations/ | tail -1
|
||||||
|
|
||||||
# Migration manuell testen (ohne Neustart):
|
# Migration manuell testen (ohne Neustart):
|
||||||
docker compose exec web php scripts/migrate.php
|
docker compose exec web php scripts/intern/migrate.php
|
||||||
```
|
```
|
||||||
|
|
||||||
## Geplante Aufgaben (Cron)
|
## Geplante Aufgaben (Cron)
|
||||||
|
|
|
||||||
10
Changes.md
10
Changes.md
|
|
@ -2,6 +2,16 @@
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 2026-08-21 – scripts/ nach Ausführungsort aufgeräumt: Host / Container / intern (#196)
|
||||||
|
|
||||||
|
- **`scripts/`:** Bislang lagen 16 Skripte mit vier verschiedenen Aufrufkonventionen flach nebeneinander – von außen war nicht erkennbar, was direkt vom Host aufrufbar ist, was `docker compose exec` braucht und was nie manuell laufen darf. Jetzt gibt es genau ein Ordnungskriterium: `scripts/` (Host, ausnahmslos direkt aufrufbar), `scripts/container/` (`docker compose exec web ...`) und `scripts/intern/` (Entrypoint/Container-Start, nie manuell).
|
||||||
|
- **Verschoben und auf Bindestriche vereinheitlicht:** `analyse_nextcloud.sh` → `scripts/analyse-nextcloud.sh`; `e2e-cleanup.php`, `e2e-user.php`, `ki-batch.php`, `nextcloud-import.php`, `reset-password.php`, `seed-testdata.php`, `run-tests.sh` → `scripts/container/`; `encrypt_bank_secrets.php` → `scripts/container/encrypt-bank-secrets.php`; `migrate.php`, `uploads-uebernahme.sh` → `scripts/intern/`. `backup.sh`, `restore.sh`, `update.sh`, `migrate-datenverzeichnis.sh` bleiben unverändert in `scripts/`.
|
||||||
|
- **`scripts/migrate-uploads-to-bindmount.sh`** entfernt: beschrieb einen Umzug in ein `./uploads/`-Verzeichnis, das es seit dem Datenverzeichnis-Umbau nicht mehr gibt, und verwies selbst bereits auf seinen Nachfolger `migrate-datenverzeichnis.sh`.
|
||||||
|
- **`scripts/test.sh`, `scripts/e2e.sh`** (neu): dünne Host-Wrapper für die beiden meistgenutzten Abläufe – delegieren an `docker compose exec -u www-data web php tests/run.php` bzw. `tests/e2e/run.sh`, ohne eigene Logik.
|
||||||
|
- **`docker-entrypoint.sh`, `scripts/update.sh`, `scripts/restore.sh`, `scripts/migrate-datenverzeichnis.sh`** sowie die PHP-Einstiegspunkte selbst (`dirname(__DIR__)`/`chdir(dirname(__DIR__))`-Aufrufe) auf die neue Verzeichnistiefe angepasst.
|
||||||
|
- **`tests/71_DatenverzeichnisPfadeTest.php`, `tests/75_AnalyseNextcloudSkriptTest.php`, `tests/76_DatenverzeichnisUebernahmeTest.php`:** Pfade auf die neue Struktur nachgezogen.
|
||||||
|
- Doku (`README.md`, `CLAUDE.md`, `docs/konfiguration.md`, `docs/update-backup.md`, `docs/datenbankstruktur.md`, `tests/e2e/README.md`) folgt den neuen Pfaden; Verweise in älteren Changelog-Einträgen oben bleiben unverändert, da sie den zum jeweiligen Zeitpunkt gültigen Stand dokumentieren.
|
||||||
|
|
||||||
## 2026-08-21 – Lieferantenliste (/suppliers) lief in HTTP 500: fehlender View-Import (#198)
|
## 2026-08-21 – Lieferantenliste (/suppliers) lief in HTTP 500: fehlender View-Import (#198)
|
||||||
|
|
||||||
- **`src/Views/suppliers/list.php`:** Die View rief `View::formatDate()` ohne `use Steuerkram\View;` auf. Views werden per `include` eingebunden und laufen dadurch im globalen Namespace – das `use` des einbindenden Controllers gilt dort nicht, der Aufruf ging also auf `\View::formatDate()` und die Seite starb mit `Class "View" not found`. Sichtbar wurde das erst mit dem ersten Lieferanten, weil die Zeile in der `foreach`-Schleife steht. Import ergänzt; alle übrigen Views hatten ihn bereits.
|
- **`src/Views/suppliers/list.php`:** Die View rief `View::formatDate()` ohne `use Steuerkram\View;` auf. Views werden per `include` eingebunden und laufen dadurch im globalen Namespace – das `use` des einbindenden Controllers gilt dort nicht, der Aufruf ging also auf `\View::formatDate()` und die Seite starb mit `Class "View" not found`. Sichtbar wurde das erst mit dem ersten Lieferanten, weil die Zeile in der `foreach`-Schleife steht. Import ergänzt; alle übrigen Views hatten ihn bereits.
|
||||||
|
|
|
||||||
18
README.md
18
README.md
|
|
@ -137,7 +137,7 @@ docker compose up -d --build
|
||||||
|
|
||||||
## Belege automatisch aus Nextcloud importieren
|
## Belege automatisch aus Nextcloud importieren
|
||||||
|
|
||||||
Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werden. Das CLI-Skript `scripts/nextcloud-import.php` liest alle unterstützten Dateien (PDF, JPEG, PNG, TIFF, XML) aus dem konfigurierten Ordner, legt sie als Belege an und verschiebt sie anschließend in einen Erledigte-Ordner (oder löscht sie, wenn kein Ziel-Ordner konfiguriert ist).
|
Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werden. Das CLI-Skript `scripts/container/nextcloud-import.php` liest alle unterstützten Dateien (PDF, JPEG, PNG, TIFF, XML) aus dem konfigurierten Ordner, legt sie als Belege an und verschiebt sie anschließend in einen Erledigte-Ordner (oder löscht sie, wenn kein Ziel-Ordner konfiguriert ist).
|
||||||
|
|
||||||
### Konfiguration
|
### Konfiguration
|
||||||
|
|
||||||
|
|
@ -148,7 +148,7 @@ Empfehlung: Ein Nextcloud-App-Passwort verwenden (Nextcloud → Einstellungen
|
||||||
### Manueller Aufruf
|
### Manueller Aufruf
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/nextcloud-import.php
|
docker compose exec web php scripts/container/nextcloud-import.php
|
||||||
```
|
```
|
||||||
|
|
||||||
### Automatisch per Cron (auf dem Host)
|
### Automatisch per Cron (auf dem Host)
|
||||||
|
|
@ -159,7 +159,7 @@ Für den automatischen Abruf muss ein Cron-Eintrag auf dem Host angelegt werden.
|
||||||
|
|
||||||
```cron
|
```cron
|
||||||
*/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
*/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
||||||
php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
php scripts/container/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
Kein `sudo` im Befehl nötig. Nachteil: Root-Crons sind schwerer zu überblicken.
|
Kein `sudo` im Befehl nötig. Nachteil: Root-Crons sind schwerer zu überblicken.
|
||||||
|
|
@ -177,7 +177,7 @@ Anschließend in der User-Crontab (ohne `sudo`):
|
||||||
|
|
||||||
```cron
|
```cron
|
||||||
*/15 * * * * docker compose -f /home/fds/projects/Steuerkram/docker-compose.yml exec -T web \
|
*/15 * * * * docker compose -f /home/fds/projects/Steuerkram/docker-compose.yml exec -T web \
|
||||||
php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
php scripts/container/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Hinweis:** Das `-T`-Flag ist bei Cron zwingend erforderlich – ohne TTY schlägt `docker compose exec` sonst still fehl.
|
> **Hinweis:** Das `-T`-Flag ist bei Cron zwingend erforderlich – ohne TTY schlägt `docker compose exec` sonst still fehl.
|
||||||
|
|
@ -256,7 +256,7 @@ Das Skript erstellt ein Dump der Datenbank sowie ein Archiv der Uploads im Verze
|
||||||
|
|
||||||
Seit dem 11.04.2026 bin ich mit meiner Software für mich selber produktiv. Ab diesem Zeitpunkt sollten keine breaking changes mehr vorkommen.
|
Seit dem 11.04.2026 bin ich mit meiner Software für mich selber produktiv. Ab diesem Zeitpunkt sollten keine breaking changes mehr vorkommen.
|
||||||
|
|
||||||
Datenbankmigrationen werden **automatisch** beim nächsten Container-Start eingespielt – kein manueller Eingriff nötig. Das Script `scripts/migrate.php` prüft beim Start, welche Migrations-Dateien noch nicht angewendet wurden, und führt sie der Reihe nach aus.
|
Datenbankmigrationen werden **automatisch** beim nächsten Container-Start eingespielt – kein manueller Eingriff nötig. Das Script `scripts/intern/migrate.php` prüft beim Start, welche Migrations-Dateien noch nicht angewendet wurden, und führt sie der Reihe nach aus.
|
||||||
|
|
||||||
### Vollständige Update-Anleitung
|
### Vollständige Update-Anleitung
|
||||||
|
|
||||||
|
|
@ -295,7 +295,7 @@ git log --oneline -5
|
||||||
docker compose up -d --build
|
docker compose up -d --build
|
||||||
```
|
```
|
||||||
|
|
||||||
Dieser Befehl baut das PHP-Image neu (falls sich `Dockerfile` oder `composer.json` geändert haben) und startet alle Container. Der Web-Container führt beim Start automatisch `scripts/migrate.php` aus.
|
Dieser Befehl baut das PHP-Image neu (falls sich `Dockerfile` oder `composer.json` geändert haben) und startet alle Container. Der Web-Container führt beim Start automatisch `scripts/intern/migrate.php` aus.
|
||||||
|
|
||||||
#### Schritt 4 – Migrationen prüfen
|
#### Schritt 4 – Migrationen prüfen
|
||||||
|
|
||||||
|
|
@ -355,15 +355,15 @@ Anschließend im Browser unter `http://localhost:8080` (oder dem konfigurierten
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec -u www-data web php tests/run.php # PHP-Suite (Models, Services, Berechnungen)
|
./scripts/test.sh # PHP-Suite (Models, Services, Berechnungen)
|
||||||
tests/e2e/run.sh # Browser-Tests (Routing, Views, Formular-JS)
|
./scripts/e2e.sh # Browser-Tests (Routing, Views, Formular-JS)
|
||||||
```
|
```
|
||||||
|
|
||||||
Die PHP-Suite läuft ohne weitere Voraussetzungen. Das `-u www-data` gehört dazu:
|
Die PHP-Suite läuft ohne weitere Voraussetzungen. Das `-u www-data` gehört dazu:
|
||||||
sonst laufen die Tests als root und hinterlassen in `data/` Dateien, die Apache/PHP
|
sonst laufen die Tests als root und hinterlassen in `data/` Dateien, die Apache/PHP
|
||||||
später nicht mehr beschreiben kann. Die E2E-Tests brauchen Docker,
|
später nicht mehr beschreiben kann. Die E2E-Tests brauchen Docker,
|
||||||
das [e2e-runner-Projekt](../e2e-runner/) und einen Testnutzer
|
das [e2e-runner-Projekt](../e2e-runner/) und einen Testnutzer
|
||||||
(`docker compose exec web php scripts/e2e-user.php`); fehlt etwas davon, werden
|
(`docker compose exec web php scripts/container/e2e-user.php`); fehlt etwas davon, werden
|
||||||
sie mit einer Warnung übersprungen. Details in [tests/e2e/README.md](tests/e2e/README.md).
|
sie mit einer Warnung übersprungen. Details in [tests/e2e/README.md](tests/e2e/README.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -14,10 +14,10 @@ mkdir -p "$BELEGE" "$LOGO" 2>/dev/null || true
|
||||||
# Installation endet, deren Dateien nicht mehr gefunden werden.
|
# Installation endet, deren Dateien nicht mehr gefunden werden.
|
||||||
# Idempotent: Nach dem Umzug sind die Quellverzeichnisse leer.
|
# Idempotent: Nach dem Umzug sind die Quellverzeichnisse leer.
|
||||||
|
|
||||||
# Die eigentliche Übernahme liegt in scripts/uploads-uebernahme.sh – dieses
|
# Die eigentliche Übernahme liegt in scripts/intern/uploads-uebernahme.sh –
|
||||||
# Verzeichnis ist als Volume gemountet, der Entrypoint dagegen steckt im Image.
|
# dieses Verzeichnis ist als Volume gemountet, der Entrypoint dagegen steckt
|
||||||
# So wirkt eine Korrektur am Umzug auch ohne Rebuild.
|
# im Image. So wirkt eine Korrektur am Umzug auch ohne Rebuild.
|
||||||
UEBERNAHME=/var/www/html/scripts/uploads-uebernahme.sh
|
UEBERNAHME=/var/www/html/scripts/intern/uploads-uebernahme.sh
|
||||||
|
|
||||||
# Logo aus dem alten Web-Root (Stand vor Fix #116). Übergeben wird direkt der
|
# Logo aus dem alten Web-Root (Stand vor Fix #116). Übergeben wird direkt der
|
||||||
# logo-Ordner – alles darin ist Logo, deshalb steht data/logo an beiden Zielstellen.
|
# logo-Ordner – alles darin ist Logo, deshalb steht data/logo an beiden Zielstellen.
|
||||||
|
|
@ -35,6 +35,6 @@ sh "$UEBERNAHME" "$LEGACY" "$BELEGE" "$LOGO" || true
|
||||||
chown -R www-data:www-data "$BELEGE" "$LOGO" 2>/dev/null || true
|
chown -R www-data:www-data "$BELEGE" "$LOGO" 2>/dev/null || true
|
||||||
|
|
||||||
# Datenbank-Migrationen automatisch einspielen
|
# Datenbank-Migrationen automatisch einspielen
|
||||||
php /var/www/html/scripts/migrate.php
|
php /var/www/html/scripts/intern/migrate.php
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|
|
||||||
|
|
@ -281,4 +281,4 @@ UNIQUE KEY auf `(year, month)`.
|
||||||
|
|
||||||
## Migrationen
|
## Migrationen
|
||||||
|
|
||||||
Schemaänderungen kommen ausschließlich als nummerierte SQL-Dateien in `migrations/` und werden vom Script `scripts/migrate.php` beim Container-Start automatisch eingespielt. Die Tabelle `schema_migrations` protokolliert, welche Dateien bereits angewendet wurden.
|
Schemaänderungen kommen ausschließlich als nummerierte SQL-Dateien in `migrations/` und werden vom Script `scripts/intern/migrate.php` beim Container-Start automatisch eingespielt. Die Tabelle `schema_migrations` protokolliert, welche Dateien bereits angewendet wurden.
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ LLM_MODEL=gpt-4o-mini
|
||||||
|
|
||||||
## Nextcloud-Import einrichten
|
## Nextcloud-Import einrichten
|
||||||
|
|
||||||
Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werden. Das CLI-Skript `scripts/nextcloud-import.php` liest alle unterstützten Dateien (PDF, JPEG, PNG, TIFF, XML) aus dem konfigurierten Ordner, legt sie als Belege an und verschiebt sie anschließend in einen Erledigte-Ordner.
|
Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werden. Das CLI-Skript `scripts/container/nextcloud-import.php` liest alle unterstützten Dateien (PDF, JPEG, PNG, TIFF, XML) aus dem konfigurierten Ordner, legt sie als Belege an und verschiebt sie anschließend in einen Erledigte-Ordner.
|
||||||
|
|
||||||
### Zugangsdaten konfigurieren
|
### Zugangsdaten konfigurieren
|
||||||
|
|
||||||
|
|
@ -73,7 +73,7 @@ Hinweis: Ein Nextcloud-App-Passwort verwenden (Nextcloud → Einstellungen → S
|
||||||
### Manueller Aufruf
|
### Manueller Aufruf
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/nextcloud-import.php
|
docker compose exec web php scripts/container/nextcloud-import.php
|
||||||
```
|
```
|
||||||
|
|
||||||
### Automatisch per Cron
|
### Automatisch per Cron
|
||||||
|
|
@ -82,7 +82,7 @@ Cron-Eintrag auf dem Host anlegen (`crontab -e`):
|
||||||
|
|
||||||
```cron
|
```cron
|
||||||
*/15 * * * * docker compose -f /opt/Steuerkram/docker-compose.yml exec -T web \
|
*/15 * * * * docker compose -f /opt/Steuerkram/docker-compose.yml exec -T web \
|
||||||
php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
php scripts/container/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||||||
```
|
```
|
||||||
|
|
||||||
> Das `-T`-Flag ist bei Cron zwingend erforderlich – ohne TTY schlägt `docker compose exec` sonst still fehl.
|
> Das `-T`-Flag ist bei Cron zwingend erforderlich – ohne TTY schlägt `docker compose exec` sonst still fehl.
|
||||||
|
|
@ -96,11 +96,11 @@ sudo usermod -aG docker $USER
|
||||||
|
|
||||||
### Verbindung analysieren
|
### Verbindung analysieren
|
||||||
|
|
||||||
Meldet der Import „PROPFIND fehlgeschlagen" oder findet er keine Dateien, grenzt `scripts/analyse_nextcloud.sh` die Ursache ein. Das Skript wird auf dem Host aufgerufen (nicht im Container) und arbeitet rein lesend – es importiert, verschiebt und löscht nichts. Das Passwort wird nie im Klartext ausgegeben.
|
Meldet der Import „PROPFIND fehlgeschlagen" oder findet er keine Dateien, grenzt `scripts/analyse-nextcloud.sh` die Ursache ein. Das Skript wird auf dem Host aufgerufen (nicht im Container) und arbeitet rein lesend – es importiert, verschiebt und löscht nichts. Das Passwort wird nie im Klartext ausgegeben.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./scripts/analyse_nextcloud.sh # Konfiguration, DNS, Verbindungsversuch
|
./scripts/analyse-nextcloud.sh # Konfiguration, DNS, Verbindungsversuch
|
||||||
./scripts/analyse_nextcloud.sh --verbose # zusätzlich ein Auszug der Server-Antwort
|
./scripts/analyse-nextcloud.sh --verbose # zusätzlich ein Auszug der Server-Antwort
|
||||||
```
|
```
|
||||||
|
|
||||||
Ausgegeben werden die hinterlegte Konfiguration, die Namensauflösung samt IP-Pinning des SSRF-Schutzes, ein PROPFIND auf den Import-Ordner, der Inhalt des Ordners (inkl. Dateien, die wegen ihres Typs übersprungen würden) und die Erreichbarkeit des Erledigte-Ordners. Schlägt der Verbindungsversuch fehl, folgen Gegenproben ohne IP-Pinning sowie je Adressfamilie einzeln – daran ist ablesbar, ob Zugangsdaten, Ordnerpfad oder die Netzwerkverbindung (z.B. fehlende IPv6-Konnektivität) die Ursache sind. Exit-Code 0 bedeutet, dass die Verbindung steht.
|
Ausgegeben werden die hinterlegte Konfiguration, die Namensauflösung samt IP-Pinning des SSRF-Schutzes, ein PROPFIND auf den Import-Ordner, der Inhalt des Ordners (inkl. Dateien, die wegen ihres Typs übersprungen würden) und die Erreichbarkeit des Erledigte-Ordners. Schlägt der Verbindungsversuch fehl, folgen Gegenproben ohne IP-Pinning sowie je Adressfamilie einzeln – daran ist ablesbar, ob Zugangsdaten, Ordnerpfad oder die Netzwerkverbindung (z.B. fehlende IPv6-Konnektivität) die Ursache sind. Exit-Code 0 bedeutet, dass die Verbindung steht.
|
||||||
|
|
@ -109,11 +109,11 @@ Ausgegeben werden die hinterlegte Konfiguration, die Namensauflösung samt IP-Pi
|
||||||
|
|
||||||
## Benutzer-Passwort zurücksetzen
|
## Benutzer-Passwort zurücksetzen
|
||||||
|
|
||||||
Das Skript `scripts/reset-password.php` setzt das Passwort eines vorhandenen Benutzers auf einen neuen Wert. Es nimmt den Benutzernamen und das neue Passwort als Parameter entgegen, erzeugt einen bcrypt-Hash und aktualisiert den Eintrag in der Datenbank. Wird der Benutzer nicht gefunden, gibt es eine Fehlermeldung und ändert nichts.
|
Das Skript `scripts/container/reset-password.php` setzt das Passwort eines vorhandenen Benutzers auf einen neuen Wert. Es nimmt den Benutzernamen und das neue Passwort als Parameter entgegen, erzeugt einen bcrypt-Hash und aktualisiert den Eintrag in der Datenbank. Wird der Benutzer nicht gefunden, gibt es eine Fehlermeldung und ändert nichts.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/reset-password.php <username> <neues_passwort>
|
docker compose exec web php scripts/container/reset-password.php <username> <neues_passwort>
|
||||||
|
|
||||||
# Beispiel:
|
# Beispiel:
|
||||||
docker compose exec web php scripts/reset-password.php Meinuser geheim123
|
docker compose exec web php scripts/container/reset-password.php Meinuser geheim123
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ Das Script erledigt in dieser Reihenfolge:
|
||||||
4. **Image-Rebuild** – Das Docker-Image wird neu gebaut, wenn `Dockerfile`, `composer.json`, `composer.lock`, `php/`, `apache/` oder `docker-entrypoint.sh` geändert wurden
|
4. **Image-Rebuild** – Das Docker-Image wird neu gebaut, wenn `Dockerfile`, `composer.json`, `composer.lock`, `php/`, `apache/` oder `docker-entrypoint.sh` geändert wurden
|
||||||
5. **Container-Neustart** – `docker compose down --remove-orphans` + `up -d`
|
5. **Container-Neustart** – `docker compose down --remove-orphans` + `up -d`
|
||||||
6. **Healthcheck** – Wartet bis die Datenbank `healthy` meldet (max. 120 s)
|
6. **Healthcheck** – Wartet bis die Datenbank `healthy` meldet (max. 120 s)
|
||||||
7. **Migrationen** – `scripts/migrate.php` wird explizit ausgeführt (idempotent)
|
7. **Migrationen** – `scripts/intern/migrate.php` wird explizit ausgeführt (idempotent)
|
||||||
8. **Tests als Gate** – PHP-Suite und `tests/e2e/run.sh` werden ausgeführt; schlägt eine der beiden fehl, endet `update.sh` mit Exit-Code 1
|
8. **Tests als Gate** – PHP-Suite und `tests/e2e/run.sh` werden ausgeführt; schlägt eine der beiden fehl, endet `update.sh` mit Exit-Code 1
|
||||||
|
|
||||||
### Tests als Gate
|
### Tests als Gate
|
||||||
|
|
@ -91,7 +91,7 @@ zum manuellen Zurückspielen.
|
||||||
|
|
||||||
### Migrationen
|
### Migrationen
|
||||||
|
|
||||||
Datenbankmigrationen werden von `scripts/migrate.php` verwaltet. Das Script prüft, welche Migrations-Dateien noch nicht angewendet wurden, und führt sie der Reihe nach aus. Es wird sowohl vom Container-Entrypoint als auch von `update.sh` aufgerufen.
|
Datenbankmigrationen werden von `scripts/intern/migrate.php` verwaltet. Das Script prüft, welche Migrations-Dateien noch nicht angewendet wurden, und führt sie der Reihe nach aus. Es wird sowohl vom Container-Entrypoint als auch von `update.sh` aufgerufen.
|
||||||
|
|
||||||
```
|
```
|
||||||
[migrate] Starte Migrations-Prüfung...
|
[migrate] Starte Migrations-Prüfung...
|
||||||
|
|
@ -102,7 +102,7 @@ Datenbankmigrationen werden von `scripts/migrate.php` verwaltet. Das Script prü
|
||||||
Migrationen können auch manuell ausgelöst werden:
|
Migrationen können auch manuell ausgelöst werden:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/migrate.php
|
docker compose exec web php scripts/intern/migrate.php
|
||||||
```
|
```
|
||||||
|
|
||||||
### Diagnose bei Fehlern
|
### Diagnose bei Fehlern
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
# Das Passwort wird nie im Klartext ausgegeben.
|
# Das Passwort wird nie im Klartext ausgegeben.
|
||||||
#
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./analyse_nextcloud.sh [--verbose]
|
# ./analyse-nextcloud.sh [--verbose]
|
||||||
#
|
#
|
||||||
# Exit-Code: 0 = Verbindung steht, 1 = Konfigurations- oder Verbindungsfehler
|
# Exit-Code: 0 = Verbindung steht, 1 = Konfigurations- oder Verbindungsfehler
|
||||||
# ════════════════════════════════════════════════════════════════════════════
|
# ════════════════════════════════════════════════════════════════════════════
|
||||||
|
|
@ -12,11 +12,11 @@ declare(strict_types=1);
|
||||||
* echte Buchführungsdaten bleiben unangetastet.
|
* echte Buchführungsdaten bleiben unangetastet.
|
||||||
*
|
*
|
||||||
* Verwendung:
|
* Verwendung:
|
||||||
* docker compose exec web php scripts/e2e-cleanup.php # nur anzeigen
|
* docker compose exec web php scripts/container/e2e-cleanup.php # nur anzeigen
|
||||||
* docker compose exec web php scripts/e2e-cleanup.php --force # wirklich löschen
|
* docker compose exec web php scripts/container/e2e-cleanup.php --force # wirklich löschen
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$projectRoot = dirname(__DIR__);
|
$projectRoot = dirname(__DIR__, 2);
|
||||||
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
||||||
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -14,14 +14,14 @@ declare(strict_types=1);
|
||||||
* und Status zurückgesetzt (aktiv, keine Fehlversuche, nicht gesperrt).
|
* und Status zurückgesetzt (aktiv, keine Fehlversuche, nicht gesperrt).
|
||||||
*
|
*
|
||||||
* Verwendung:
|
* Verwendung:
|
||||||
* docker compose exec web php scripts/e2e-user.php
|
* docker compose exec web php scripts/container/e2e-user.php
|
||||||
* docker compose exec web php scripts/e2e-user.php <username> <passwort>
|
* docker compose exec web php scripts/container/e2e-user.php <username> <passwort>
|
||||||
* docker compose exec web php scripts/e2e-user.php --delete
|
* docker compose exec web php scripts/container/e2e-user.php --delete
|
||||||
*
|
*
|
||||||
* Die Defaults entsprechen tests/e2e/helpers/env.js.
|
* Die Defaults entsprechen tests/e2e/helpers/env.js.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$projectRoot = dirname(__DIR__);
|
$projectRoot = dirname(__DIR__, 2);
|
||||||
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
||||||
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
@ -7,14 +7,14 @@
|
||||||
* werden übersprungen. Nach Ausführung kann es gefahrlos erneut aufgerufen werden.
|
* werden übersprungen. Nach Ausführung kann es gefahrlos erneut aufgerufen werden.
|
||||||
*
|
*
|
||||||
* Aufruf:
|
* Aufruf:
|
||||||
* docker compose exec web php scripts/encrypt_bank_secrets.php
|
* docker compose exec web php scripts/container/encrypt-bank-secrets.php
|
||||||
*
|
*
|
||||||
* Voraussetzung: APP_KEY in .env gesetzt (64-stellige Hex-Zeichenkette).
|
* Voraussetzung: APP_KEY in .env gesetzt (64-stellige Hex-Zeichenkette).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
require __DIR__ . '/../vendor/autoload.php';
|
require __DIR__ . '/../../vendor/autoload.php';
|
||||||
|
|
||||||
use Steuerkram\Config;
|
use Steuerkram\Config;
|
||||||
use Steuerkram\Database;
|
use Steuerkram\Database;
|
||||||
|
|
@ -9,16 +9,16 @@
|
||||||
* Voraussetzung: ki_vorschlag_aktiv = 1 in den Einstellungen, Ollama erreichbar.
|
* Voraussetzung: ki_vorschlag_aktiv = 1 in den Einstellungen, Ollama erreichbar.
|
||||||
*
|
*
|
||||||
* Aufruf:
|
* Aufruf:
|
||||||
* docker compose exec web php scripts/ki-batch.php
|
* docker compose exec web php scripts/container/ki-batch.php
|
||||||
*
|
*
|
||||||
* Für optionalen eigenen Cronjob (manuelle Uploads ohne Nextcloud):
|
* Für optionalen eigenen Cronjob (manuelle Uploads ohne Nextcloud):
|
||||||
* *\/5 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
* *\/5 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
||||||
* php scripts/ki-batch.php >> /var/log/steuerkram-ki.log 2>&1
|
* php scripts/container/ki-batch.php >> /var/log/steuerkram-ki.log 2>&1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
chdir(dirname(__DIR__));
|
chdir(dirname(__DIR__, 2));
|
||||||
|
|
||||||
// DB-Zugangsdaten aus .env laden (für CLI-Kontext ohne Apache-Umgebung)
|
// DB-Zugangsdaten aus .env laden (für CLI-Kontext ohne Apache-Umgebung)
|
||||||
if (file_exists('.env')) {
|
if (file_exists('.env')) {
|
||||||
|
|
@ -11,16 +11,16 @@
|
||||||
* Konfiguration: Einstellungen → Nextcloud-Belegimport in der Steuerkram-UI.
|
* Konfiguration: Einstellungen → Nextcloud-Belegimport in der Steuerkram-UI.
|
||||||
*
|
*
|
||||||
* Aufruf:
|
* Aufruf:
|
||||||
* docker compose exec web php scripts/nextcloud-import.php
|
* docker compose exec web php scripts/container/nextcloud-import.php
|
||||||
*
|
*
|
||||||
* Für Cronjob (auf dem Host):
|
* Für Cronjob (auf dem Host):
|
||||||
* *\/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
* *\/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
||||||
* php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
* php scripts/container/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
chdir(dirname(__DIR__));
|
chdir(dirname(__DIR__, 2));
|
||||||
|
|
||||||
// DB-Zugangsdaten aus .env laden (für CLI-Kontext ohne Apache-Umgebung)
|
// DB-Zugangsdaten aus .env laden (für CLI-Kontext ohne Apache-Umgebung)
|
||||||
if (file_exists('.env')) {
|
if (file_exists('.env')) {
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Passwort eines Benutzers zurücksetzen.
|
* Passwort eines Benutzers zurücksetzen.
|
||||||
* Aufruf: php scripts/reset-password.php <username> <neues_passwort>
|
* Aufruf: php scripts/container/reset-password.php <username> <neues_passwort>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ($argc !== 3) {
|
if ($argc !== 3) {
|
||||||
echo 'Verwendung: php scripts/reset-password.php <username> <neues_passwort>' . PHP_EOL;
|
echo 'Verwendung: php scripts/container/reset-password.php <username> <neues_passwort>' . PHP_EOL;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
# Steuerkram Test-Runner mit automatischer Issue-Erstellung
|
# Steuerkram Test-Runner mit automatischer Issue-Erstellung
|
||||||
#
|
#
|
||||||
# Verwendung (im Container):
|
# Verwendung (im Container):
|
||||||
# docker compose exec -u www-data web ./scripts/run-tests.sh [ISSUE_NUMMER]
|
# docker compose exec -u www-data web ./scripts/container/run-tests.sh [ISSUE_NUMMER]
|
||||||
#
|
#
|
||||||
# Parameter:
|
# Parameter:
|
||||||
# ISSUE_NUMMER (optional) Nummer des aktuell bearbeiteten Issues,
|
# ISSUE_NUMMER (optional) Nummer des aktuell bearbeiteten Issues,
|
||||||
|
|
@ -19,7 +19,7 @@
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
PROJECT_DIR="$(dirname "$(dirname "$SCRIPT_DIR")")"
|
||||||
CURRENT_ISSUE="${1:-}"
|
CURRENT_ISSUE="${1:-}"
|
||||||
REPO="fds2610/Steuerkram"
|
REPO="fds2610/Steuerkram"
|
||||||
API_BASE="https://codeberg.org/api/v1"
|
API_BASE="https://codeberg.org/api/v1"
|
||||||
|
|
@ -13,10 +13,10 @@ declare(strict_types=1);
|
||||||
* - 3 Ausgangsrechnungen (Januar, Februar, März 2026)
|
* - 3 Ausgangsrechnungen (Januar, Februar, März 2026)
|
||||||
*
|
*
|
||||||
* Verwendung:
|
* Verwendung:
|
||||||
* php scripts/seed-testdata.php
|
* php scripts/container/seed-testdata.php
|
||||||
*/
|
*/
|
||||||
|
|
||||||
$projectRoot = dirname(__DIR__);
|
$projectRoot = dirname(__DIR__, 2);
|
||||||
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
if (!file_exists($projectRoot . '/vendor/autoload.php')) {
|
||||||
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
fwrite(STDERR, "Fehler: vendor/autoload.php nicht gefunden. Bitte 'composer install' ausführen.\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
12
scripts/e2e.sh
Executable file
12
scripts/e2e.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Dünner Host-Wrapper für die E2E-Testsuite.
|
||||||
|
# Delegiert an tests/e2e/run.sh.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/e2e.sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
|
||||||
|
exec "$SCRIPT_DIR/../tests/e2e/run.sh" "$@"
|
||||||
|
|
@ -9,7 +9,7 @@ $host = getenv('DB_HOST') ?: 'db';
|
||||||
$dbName = getenv('DB_NAME') ?: 'steuerkram';
|
$dbName = getenv('DB_NAME') ?: 'steuerkram';
|
||||||
$dbUser = getenv('DB_USER') ?: 'steuerkram';
|
$dbUser = getenv('DB_USER') ?: 'steuerkram';
|
||||||
$dbPass = getenv('DB_PASS') ?: 'steuerkram';
|
$dbPass = getenv('DB_PASS') ?: 'steuerkram';
|
||||||
$migrDir = __DIR__ . '/../migrations';
|
$migrDir = __DIR__ . '/../../migrations';
|
||||||
|
|
||||||
function mlog(string $msg): void {
|
function mlog(string $msg): void {
|
||||||
echo '[migrate] ' . $msg . PHP_EOL;
|
echo '[migrate] ' . $msg . PHP_EOL;
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
# Übernimmt den Altbestand aus dem gemeinsamen uploads-Verzeichnis in die
|
# Übernimmt den Altbestand aus dem gemeinsamen uploads-Verzeichnis in die
|
||||||
# getrennten Datenverzeichnisse data/belege und data/logo.
|
# getrennten Datenverzeichnisse data/belege und data/logo.
|
||||||
#
|
#
|
||||||
# scripts/uploads-uebernahme.sh <uploads-verzeichnis> <belege-verzeichnis> <logo-verzeichnis>
|
# scripts/intern/uploads-uebernahme.sh <uploads-verzeichnis> <belege-verzeichnis> <logo-verzeichnis>
|
||||||
#
|
#
|
||||||
# Aufrufer sind docker-entrypoint.sh (bei jedem Container-Start) und
|
# Nie manuell aufrufen. Aufrufer sind docker-entrypoint.sh (bei jedem
|
||||||
# scripts/migrate-datenverzeichnis.sh (manueller Umzug). Die Logik liegt bewusst
|
# Container-Start) und scripts/migrate-datenverzeichnis.sh (manueller Umzug).
|
||||||
# hier und nicht doppelt in beiden Skripten.
|
# Die Logik liegt bewusst hier und nicht doppelt in beiden Skripten.
|
||||||
#
|
#
|
||||||
# Idempotent: Ist der Altbestand übernommen, findet ein zweiter Lauf nichts mehr.
|
# Idempotent: Ist der Altbestand übernommen, findet ein zweiter Lauf nichts mehr.
|
||||||
# Exit-Code 0 = nichts zu tun oder vollständig übernommen, 1 = Reste verblieben.
|
# Exit-Code 0 = nichts zu tun oder vollständig übernommen, 1 = Reste verblieben.
|
||||||
|
|
@ -51,7 +51,7 @@ docker run --rm \
|
||||||
mkdir -p /neu/belege /neu/logo
|
mkdir -p /neu/belege /neu/logo
|
||||||
|
|
||||||
# Gemeinsame Übernahme-Logik – dieselbe, die auch beim Container-Start läuft.
|
# Gemeinsame Übernahme-Logik – dieselbe, die auch beim Container-Start läuft.
|
||||||
sh /skripte/uploads-uebernahme.sh /alt /neu/belege /neu/logo || true
|
sh /skripte/intern/uploads-uebernahme.sh /alt /neu/belege /neu/logo || true
|
||||||
|
|
||||||
chown -R 33:33 /neu/belege /neu/logo
|
chown -R 33:33 /neu/belege /neu/logo
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,67 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
# VERALTET – nur noch für historische Stände relevant.
|
|
||||||
# Das damalige Ziel ./uploads/ gibt es nicht mehr; Belege liegen inzwischen in
|
|
||||||
# ./data/belege/, das Logo in ./data/logo/. Für den Umzug aus ./uploads/ in die
|
|
||||||
# heutige Struktur ist scripts/migrate-datenverzeichnis.sh zuständig.
|
|
||||||
#
|
|
||||||
# Einmalige Migration: Uploads vom named Docker Volume in ./uploads/ (Bind Mount)
|
|
||||||
# Vor dem ersten "docker compose up" mit dem neuen docker-compose.yml ausführen.
|
|
||||||
#
|
|
||||||
# Das Script ist idempotent: bereits vorhandene Dateien in ./uploads/ werden
|
|
||||||
# nicht überschrieben. Es ist sicher, es mehrfach auszuführen.
|
|
||||||
#
|
|
||||||
# Usage: ./scripts/migrate-uploads-to-bindmount.sh
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
||||||
TARGET_DIR="$PROJECT_DIR/uploads"
|
|
||||||
VOLUME_NAME="steuerkram_uploads"
|
|
||||||
|
|
||||||
echo "=== Uploads-Migration: named Volume → Bind Mount ==="
|
|
||||||
echo "Zielverzeichnis: $TARGET_DIR"
|
|
||||||
echo ""
|
|
||||||
|
|
||||||
# Prüfen ob das named Volume existiert
|
|
||||||
if ! docker volume ls --format '{{.Name}}' | grep -qx "$VOLUME_NAME"; then
|
|
||||||
echo "Named Volume '$VOLUME_NAME' nicht gefunden – nichts zu migrieren."
|
|
||||||
echo "Zielverzeichnis wird angelegt (falls nicht vorhanden)."
|
|
||||||
mkdir -p "$TARGET_DIR"
|
|
||||||
echo "Fertig."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Anzahl Dateien im Volume ermitteln
|
|
||||||
FILE_COUNT=$(docker run --rm \
|
|
||||||
-v "$VOLUME_NAME:/src" \
|
|
||||||
alpine \
|
|
||||||
find /src -type f | wc -l)
|
|
||||||
|
|
||||||
echo "Dateien im named Volume: $FILE_COUNT"
|
|
||||||
|
|
||||||
if [ "$FILE_COUNT" -eq 0 ]; then
|
|
||||||
echo "Volume ist leer – nichts zu kopieren."
|
|
||||||
mkdir -p "$TARGET_DIR"
|
|
||||||
echo "Fertig."
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
mkdir -p "$TARGET_DIR"
|
|
||||||
|
|
||||||
echo "Kopiere Dateien ins Bind-Mount-Verzeichnis..."
|
|
||||||
docker run --rm \
|
|
||||||
-v "$VOLUME_NAME:/src" \
|
|
||||||
-v "$TARGET_DIR:/dst" \
|
|
||||||
alpine \
|
|
||||||
sh -c 'cp -r /src/. /dst/'
|
|
||||||
|
|
||||||
COPIED=$(find "$TARGET_DIR" -type f | wc -l)
|
|
||||||
echo ""
|
|
||||||
echo "Migration abgeschlossen: $COPIED Dateien in $TARGET_DIR"
|
|
||||||
echo ""
|
|
||||||
echo "Nächste Schritte:"
|
|
||||||
echo " docker compose up -d"
|
|
||||||
echo ""
|
|
||||||
echo "Das named Volume '$VOLUME_NAME' kann danach gelöscht werden:"
|
|
||||||
echo " docker volume rm $VOLUME_NAME"
|
|
||||||
|
|
@ -134,7 +134,7 @@ echo " OK"
|
||||||
|
|
||||||
# --- 3. Migrationen ---
|
# --- 3. Migrationen ---
|
||||||
echo "[3/3] Migrationen prüfen und einspielen..."
|
echo "[3/3] Migrationen prüfen und einspielen..."
|
||||||
MIGRATE_OUT=$($COMPOSE exec -T web php scripts/migrate.php 2>&1)
|
MIGRATE_OUT=$($COMPOSE exec -T web php scripts/intern/migrate.php 2>&1)
|
||||||
echo "$MIGRATE_OUT" | sed 's/^/ /'
|
echo "$MIGRATE_OUT" | sed 's/^/ /'
|
||||||
if echo "$MIGRATE_OUT" | grep -q "FEHLER"; then
|
if echo "$MIGRATE_OUT" | grep -q "FEHLER"; then
|
||||||
echo ""
|
echo ""
|
||||||
|
|
|
||||||
12
scripts/test.sh
Executable file
12
scripts/test.sh
Executable file
|
|
@ -0,0 +1,12 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Dünner Host-Wrapper für die PHP-Testsuite.
|
||||||
|
# Delegiert an tests/run.php; -u www-data ist zwingend, siehe CLAUDE.md.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./scripts/test.sh
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
|
||||||
|
|
||||||
|
exec docker compose -f "$SCRIPT_DIR/../docker-compose.yml" --project-directory "$SCRIPT_DIR/.." exec -u www-data web php tests/run.php "$@"
|
||||||
|
|
@ -347,7 +347,7 @@ ok "Autoloader aktualisiert"
|
||||||
# nochmals explizit aus um sicherzustellen, dass alle eingespielt sind
|
# nochmals explizit aus um sicherzustellen, dass alle eingespielt sind
|
||||||
# und um den Status im Log zu sehen.
|
# und um den Status im Log zu sehen.
|
||||||
info "Führe Migrationen aus (idempotent)..."
|
info "Führe Migrationen aus (idempotent)..."
|
||||||
MIGRATE_OUTPUT=$(docker compose exec -T web php /var/www/html/scripts/migrate.php 2>&1) || {
|
MIGRATE_OUTPUT=$(docker compose exec -T web php /var/www/html/scripts/intern/migrate.php 2>&1) || {
|
||||||
fail "Migrationen fehlgeschlagen"
|
fail "Migrationen fehlgeschlagen"
|
||||||
echo "$MIGRATE_OUTPUT" | while read -r line; do info "$line"; done
|
echo "$MIGRATE_OUTPUT" | while read -r line; do info "$line"; done
|
||||||
UPDATE_FAILED=true
|
UPDATE_FAILED=true
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="form-hint">
|
<div class="form-hint">
|
||||||
Import manuell starten:
|
Import manuell starten:
|
||||||
<code>docker compose exec web php scripts/nextcloud-import.php</code>
|
<code>docker compose exec web php scripts/container/nextcloud-import.php</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test 75: Analyse-Skript für die Nextcloud-Verbindung (scripts/analyse_nextcloud.sh).
|
* Test 75: Analyse-Skript für die Nextcloud-Verbindung (scripts/analyse-nextcloud.sh).
|
||||||
*
|
*
|
||||||
* Das Skript ist ein Diagnosewerkzeug für den Produktivbetrieb. Es muss
|
* Das Skript ist ein Diagnosewerkzeug für den Produktivbetrieb. Es muss
|
||||||
* ausführbar und syntaktisch gültig sein und darf ausschließlich lesen –
|
* ausführbar und syntaktisch gültig sein und darf ausschließlich lesen –
|
||||||
|
|
@ -16,10 +16,10 @@ class AnalyseNextcloudSkriptTest extends TestCase
|
||||||
|
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$path = dirname(__DIR__) . '/scripts/analyse_nextcloud.sh';
|
$path = dirname(__DIR__) . '/scripts/analyse-nextcloud.sh';
|
||||||
|
|
||||||
$this->assert(file_exists($path), 'scripts/analyse_nextcloud.sh existiert');
|
$this->assert(file_exists($path), 'scripts/analyse-nextcloud.sh existiert');
|
||||||
$this->assert(is_executable($path), 'scripts/analyse_nextcloud.sh ist ausführbar');
|
$this->assert(is_executable($path), 'scripts/analyse-nextcloud.sh ist ausführbar');
|
||||||
|
|
||||||
exec('bash -n ' . escapeshellarg($path) . ' 2>&1', $output, $exitCode);
|
exec('bash -n ' . escapeshellarg($path) . ' 2>&1', $output, $exitCode);
|
||||||
$this->assertEquals(0, $exitCode, 'bash-Syntax ist gültig (' . implode(' ', $output) . ')');
|
$this->assertEquals(0, $exitCode, 'bash-Syntax ist gültig (' . implode(' ', $output) . ')');
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ declare(strict_types=1);
|
||||||
* unterdrückt wurden, meldete die Migration trotzdem Erfolg. Ergebnis: eine
|
* unterdrückt wurden, meldete die Migration trotzdem Erfolg. Ergebnis: eine
|
||||||
* Installation, in der die Belege nicht mehr auffindbar waren.
|
* Installation, in der die Belege nicht mehr auffindbar waren.
|
||||||
*
|
*
|
||||||
* Der Test führt scripts/uploads-uebernahme.sh real aus und prüft, dass es
|
* Der Test führt scripts/intern/uploads-uebernahme.sh real aus und prüft, dass es
|
||||||
* zusammenführt statt zu verschachteln und keine vorhandene Zieldatei überschreibt.
|
* zusammenführt statt zu verschachteln und keine vorhandene Zieldatei überschreibt.
|
||||||
*/
|
*/
|
||||||
class DatenverzeichnisUebernahmeTest extends TestCase
|
class DatenverzeichnisUebernahmeTest extends TestCase
|
||||||
|
|
@ -20,9 +20,9 @@ class DatenverzeichnisUebernahmeTest extends TestCase
|
||||||
|
|
||||||
public function run(): void
|
public function run(): void
|
||||||
{
|
{
|
||||||
$skript = dirname(__DIR__) . '/scripts/uploads-uebernahme.sh';
|
$skript = dirname(__DIR__) . '/scripts/intern/uploads-uebernahme.sh';
|
||||||
|
|
||||||
$this->assert(file_exists($skript), 'scripts/uploads-uebernahme.sh existiert');
|
$this->assert(file_exists($skript), 'scripts/intern/uploads-uebernahme.sh existiert');
|
||||||
exec('sh -n ' . escapeshellarg($skript) . ' 2>&1', $syntax, $syntaxExit);
|
exec('sh -n ' . escapeshellarg($skript) . ' 2>&1', $syntax, $syntaxExit);
|
||||||
$this->assertEquals(0, $syntaxExit, 'sh-Syntax ist gültig (' . implode(' ', $syntax) . ')');
|
$this->assertEquals(0, $syntaxExit, 'sh-Syntax ist gültig (' . implode(' ', $syntax) . ')');
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ class DatenverzeichnisUebernahmeTest extends TestCase
|
||||||
$migration = dirname(__DIR__) . '/scripts/migrate-datenverzeichnis.sh';
|
$migration = dirname(__DIR__) . '/scripts/migrate-datenverzeichnis.sh';
|
||||||
$this->assert(
|
$this->assert(
|
||||||
str_contains((string)file_get_contents($migration), 'uploads-uebernahme.sh'),
|
str_contains((string)file_get_contents($migration), 'uploads-uebernahme.sh'),
|
||||||
'migrate-datenverzeichnis.sh verwendet scripts/uploads-uebernahme.sh'
|
'migrate-datenverzeichnis.sh verwendet scripts/intern/uploads-uebernahme.sh'
|
||||||
);
|
);
|
||||||
|
|
||||||
// ── Funktionaler Lauf: Ziel enthält bereits ein Jahresverzeichnis ──────
|
// ── Funktionaler Lauf: Ziel enthält bereits ein Jahresverzeichnis ──────
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ aufgetretenen Fehler:
|
||||||
2. **Testnutzer existiert** (einmalig, idempotent wiederholbar):
|
2. **Testnutzer existiert** (einmalig, idempotent wiederholbar):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/e2e-user.php
|
docker compose exec web php scripts/container/e2e-user.php
|
||||||
```
|
```
|
||||||
|
|
||||||
Legt `e2e` / `e2e-test-Pass123!` an bzw. setzt Passwort und Sperrstatus
|
Legt `e2e` / `e2e-test-Pass123!` an bzw. setzt Passwort und Sperrstatus
|
||||||
|
|
@ -77,8 +77,8 @@ Die Tests laufen gegen eine Instanz mit **echten Arbeitsdaten**. Deshalb gilt:
|
||||||
Reste nach einem abgebrochenen Lauf entfernen:
|
Reste nach einem abgebrochenen Lauf entfernen:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker compose exec web php scripts/e2e-cleanup.php # nur anzeigen
|
docker compose exec web php scripts/container/e2e-cleanup.php # nur anzeigen
|
||||||
docker compose exec web php scripts/e2e-cleanup.php --force # löschen
|
docker compose exec web php scripts/container/e2e-cleanup.php --force # löschen
|
||||||
```
|
```
|
||||||
|
|
||||||
### Nummernkreise
|
### Nummernkreise
|
||||||
|
|
@ -96,7 +96,7 @@ finalisiert wurde), bleibt der Zähler stehen — eine Nummer wird nie zweimal
|
||||||
vergeben. In dem Fall entsteht wie bisher eine Lücke im Nummernkreis.
|
vergeben. In dem Fall entsteht wie bisher eine Lücke im Nummernkreis.
|
||||||
|
|
||||||
Bricht ein Lauf mittendrin ab, bleiben Testdatensätze liegen;
|
Bricht ein Lauf mittendrin ab, bleiben Testdatensätze liegen;
|
||||||
`scripts/e2e-cleanup.php --force` räumt sie nachträglich ab und arbeitet dabei
|
`scripts/container/e2e-cleanup.php --force` räumt sie nachträglich ab und arbeitet dabei
|
||||||
absteigend, damit möglichst viele Nummern zurückwandern.
|
absteigend, damit möglichst viele Nummern zurückwandern.
|
||||||
|
|
||||||
## Aufbau
|
## Aufbau
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ TestCase::setQuiet($jsonMode);
|
||||||
|
|
||||||
// PHP-Warnungen/-Notices einzelner Tests (z. B. absichtlich provozierte
|
// PHP-Warnungen/-Notices einzelner Tests (z. B. absichtlich provozierte
|
||||||
// Fehlerfälle) dürfen die JSON-Ausgabe auf STDOUT nicht verunreinigen –
|
// Fehlerfälle) dürfen die JSON-Ausgabe auf STDOUT nicht verunreinigen –
|
||||||
// scripts/run-tests.sh wertet sie sonst nicht mehr auswertbar aus.
|
// scripts/container/run-tests.sh wertet sie sonst nicht mehr auswertbar aus.
|
||||||
if ($jsonMode) {
|
if ($jsonMode) {
|
||||||
ini_set('display_errors', 'stderr');
|
ini_set('display_errors', 'stderr');
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue