From af46e1829d2432e2ac6ad3221a1e674c8e6a26c0 Mon Sep 17 00:00:00 2001 From: Thorsten Bus Date: Mon, 30 Mar 2026 13:45:42 +0200 Subject: [PATCH] feat: switch propresenter/parser to remote VCS, add local dev toggle script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace path repository with VCS pointing to git.stadtmission-butzbach.de/public/propresenter-php.git. Add use_local_pp_lib.sh to toggle between remote and local checkout. Fix test fixture paths after repo restructure (ref/ → doc/reference_samples/). --- AGENTS.md | 6 +- composer.json | 11 ++- composer.lock | 15 ++-- tests/Feature/ProFileExportTest.php | 4 +- tests/Feature/ProFileImportTest.php | 2 +- use_local_pp_lib.sh | 114 ++++++++++++++++++++++++++++ 6 files changed, 136 insertions(+), 16 deletions(-) create mode 100755 use_local_pp_lib.sh diff --git a/AGENTS.md b/AGENTS.md index 101a845..d4e316d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -20,7 +20,7 @@ ## General - There should be Button in the Top Bar, to refresh the Data from the CTS API and a timestamp with the latest refresh. - LoggedIn User should be visible in the Top Bar - every action should be immediately persistent, no separate "save" button required, unless explicitly described. -- ProPresenter `.pro` file parser/generator is implemented as a separate composer package (`propresenter/parser`) linked via path repository +- ProPresenter `.pro` file parser/generator is implemented as a separate composer package (`propresenter/parser`) from `https://git.stadtmission-butzbach.de/public/propresenter-php.git` (use `./use_local_pp_lib.sh` to switch to a local checkout for development) ## The Plan @@ -109,6 +109,8 @@ ## Repository Structure The parser is linked via `composer.json` path repository: `"url": "../propresenter-work/php"`. +> **Note:** The parser package (`propresenter/parser`) is installed from the remote VCS repository by default. Use `./use_local_pp_lib.sh ` to switch to a local checkout for development, and `./use_local_pp_lib.sh --remote` to switch back. + ## Build, Test, Lint Commands ### cts-work (Laravel App) @@ -161,6 +163,8 @@ # Single test file ./vendor/bin/phpunit tests/ProFileReaderTest.php ``` +> **Note:** The parser package (`propresenter/parser`) is installed from the remote VCS repository by default. Use `./use_local_pp_lib.sh ` to switch to a local checkout for development, and `./use_local_pp_lib.sh --remote` to switch back. + ## Architecture ``` diff --git a/composer.json b/composer.json index 6e42c35..49cad12 100644 --- a/composer.json +++ b/composer.json @@ -3,12 +3,15 @@ "name": "laravel/laravel", "type": "project", "description": "The skeleton application for the Laravel framework.", - "keywords": ["laravel", "framework"], + "keywords": [ + "laravel", + "framework" + ], "license": "MIT", "repositories": [ { - "type": "path", - "url": "../propresenter/php" + "type": "vcs", + "url": "https://git.stadtmission-butzbach.de/public/propresenter-php.git" } ], "require": { @@ -21,7 +24,7 @@ "laravel/sanctum": "^4.0", "laravel/socialite": "^5.24", "laravel/tinker": "^2.10.1", - "propresenter/parser": "@dev", + "propresenter/parser": "dev-master", "spatie/pdf-to-image": "^1.2", "tightenco/ziggy": "^2.0" }, diff --git a/composer.lock b/composer.lock index 088b016..d65d370 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "746ee5a4cf131b6b821d1abae2818edf", + "content-hash": "9dbae3f5dca103e9a9aab8a5291791dd", "packages": [ { "name": "5pm-hdh/churchtools-api", @@ -3816,10 +3816,10 @@ { "name": "propresenter/parser", "version": "dev-master", - "dist": { - "type": "path", - "url": "../propresenter/php", - "reference": "43b6fa020bc05e5e9b58254ebcfbfb811f920ccf" + "source": { + "type": "git", + "url": "https://git.stadtmission-butzbach.de/public/propresenter-php.git", + "reference": "22ba4aff7d29683297c0397e1bbc3699dc35ac03" }, "require": { "google/protobuf": "^4.0", @@ -3828,6 +3828,7 @@ "require-dev": { "phpunit/phpunit": "^11.0" }, + "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -3837,9 +3838,7 @@ } }, "description": "ProPresenter song file parser", - "transport-options": { - "relative": true - } + "time": "2026-03-30T11:26:29+00:00" }, { "name": "psr/clock", diff --git a/tests/Feature/ProFileExportTest.php b/tests/Feature/ProFileExportTest.php index f5058e2..74348cb 100644 --- a/tests/Feature/ProFileExportTest.php +++ b/tests/Feature/ProFileExportTest.php @@ -72,7 +72,7 @@ public function test_download_pro_roundtrip_import_export(): void { $user = User::factory()->create(); - $sourcePath = base_path('../propresenter/ref/Test.pro'); + $sourcePath = base_path('../propresenter/doc/reference_samples/Test.pro'); $file = new \Illuminate\Http\UploadedFile($sourcePath, 'Test.pro', 'application/octet-stream', null, true); $importResponse = $this->actingAs($user)->postJson(route('api.songs.import-pro'), ['file' => $file]); @@ -93,7 +93,7 @@ public function test_download_pro_roundtrip_preserves_content(): void $user = User::factory()->create(); // 1. Import the reference .pro file - $sourcePath = base_path('../propresenter/ref/Test.pro'); + $sourcePath = base_path('../propresenter/doc/reference_samples/Test.pro'); $file = new \Illuminate\Http\UploadedFile($sourcePath, 'Test.pro', 'application/octet-stream', null, true); $importResponse = $this->actingAs($user)->postJson(route('api.songs.import-pro'), ['file' => $file]); diff --git a/tests/Feature/ProFileImportTest.php b/tests/Feature/ProFileImportTest.php index 309c062..0da0db6 100644 --- a/tests/Feature/ProFileImportTest.php +++ b/tests/Feature/ProFileImportTest.php @@ -14,7 +14,7 @@ final class ProFileImportTest extends TestCase private function test_pro_file(): UploadedFile { - $sourcePath = base_path('../propresenter/ref/Test.pro'); + $sourcePath = base_path('../propresenter/doc/reference_samples/Test.pro'); return new UploadedFile($sourcePath, 'Test.pro', 'application/octet-stream', null, true); } diff --git a/use_local_pp_lib.sh b/use_local_pp_lib.sh new file mode 100755 index 0000000..28522bd --- /dev/null +++ b/use_local_pp_lib.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env bash +# +# Toggle propresenter/parser between remote VCS and local path repository. +# +# Usage: +# ./use_local_pp_lib.sh — Switch to local checkout (symlinked) +# ./use_local_pp_lib.sh --remote — Switch back to remote VCS +# +# Examples: +# ./use_local_pp_lib.sh ../propresenter +# ./use_local_pp_lib.sh /absolute/path/to/propresenter-php +# ./use_local_pp_lib.sh --remote +# +set -euo pipefail + +COMPOSER_FILE="composer.json" + +if [[ ! -f "$COMPOSER_FILE" ]]; then + echo "Error: $COMPOSER_FILE nicht gefunden. Bitte im Projektverzeichnis ausfuehren." >&2 + exit 1 +fi + +if [[ $# -lt 1 ]]; then + echo "Usage: $0 | --remote" >&2 + echo "" >&2 + echo " Pfad zum lokalen propresenter-php Checkout" >&2 + echo " --remote Zurueck zum Remote-Repository wechseln" >&2 + exit 1 +fi + +switch_to_remote() { + echo "Wechsle zu Remote-VCS Repository..." + + php -r ' + $json = json_decode(file_get_contents("composer.json"), true); + $json["repositories"] = array_values(array_filter($json["repositories"], function($r) { + return ($r["type"] ?? "") !== "path"; + })); + file_put_contents("composer.json", json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"); + ' + + if [[ -L "vendor/propresenter/parser" ]] || [[ -d "vendor/propresenter/parser" ]]; then + rm -rf vendor/propresenter/parser + fi + + composer update propresenter/parser + echo "" + echo "propresenter/parser wird jetzt vom Remote-Repository geladen." +} + +switch_to_local() { + local LOCAL_PATH="$1" + + if [[ "$LOCAL_PATH" != /* ]]; then + LOCAL_PATH="$(cd "$(dirname "$LOCAL_PATH")" && pwd)/$(basename "$LOCAL_PATH")" + fi + + if [[ ! -f "$LOCAL_PATH/composer.json" ]]; then + echo "Error: Keine composer.json in $LOCAL_PATH gefunden." >&2 + echo "Bitte den Pfad zum propresenter-php Root-Verzeichnis angeben." >&2 + exit 1 + fi + + local PKG_NAME + PKG_NAME=$(php -r "echo json_decode(file_get_contents('$LOCAL_PATH/composer.json'), true)['name'] ?? '';") + if [[ "$PKG_NAME" != "propresenter/parser" ]]; then + echo "Error: Package in $LOCAL_PATH ist '$PKG_NAME', erwartet 'propresenter/parser'." >&2 + exit 1 + fi + + local REL_PATH + REL_PATH=$(python3 -c "import os; print(os.path.relpath('$LOCAL_PATH', '$(pwd)'))") + + echo "Wechsle zu lokalem Checkout: $REL_PATH" + + php -r ' + $relPath = $argv[1]; + $json = json_decode(file_get_contents("composer.json"), true); + $json["repositories"] = array_values(array_filter($json["repositories"], function($r) { + return ($r["type"] ?? "") !== "path"; + })); + array_unshift($json["repositories"], [ + "type" => "path", + "url" => $relPath, + "options" => ["symlink" => true], + ]); + + file_put_contents("composer.json", json_encode($json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n"); + ' -- "$REL_PATH" + + if [[ -L "vendor/propresenter/parser" ]] || [[ -d "vendor/propresenter/parser" ]]; then + rm -rf vendor/propresenter/parser + fi + + composer update propresenter/parser + echo "" + echo "propresenter/parser ist jetzt mit $REL_PATH verlinkt (Symlink)." + echo "Aenderungen in $REL_PATH sind sofort verfuegbar." +} + +case "$1" in + --remote|-r) + switch_to_remote + ;; + --help|-h) + echo "Usage: $0 | --remote" + echo "" + echo " Pfad zum lokalen propresenter-php Checkout" + echo " --remote Zurueck zum Remote-Repository wechseln" + ;; + *) + switch_to_local "$1" + ;; +esac