From e2b91df9f042e1596e31e3ec03663cd1ea301801 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 06:09:38 +0000 Subject: [PATCH 1/9] Initial plan From f911adb219ffb6726f432760ea2a5af5d1bf8518 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 06:36:39 +0000 Subject: [PATCH 2/9] feat: add buildPath() method to Updater class and fix double-slash in createBackup() Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/5f2df1e7-e17a-4242-b4c3-91a831b9048d --- .phpunit.result.cache | 1 + Makefile | 3 + index.php | 59 +- lib/Updater.php | 59 +- phpunit.xml | 15 + tests/unit/UpdaterTest.php | 99 ++ vendor-bin/tests/composer.json | 3 +- vendor-bin/tests/composer.lock | 2204 ++++++++++++++++++++++++++++---- 8 files changed, 2165 insertions(+), 278 deletions(-) create mode 100644 .phpunit.result.cache create mode 100644 phpunit.xml create mode 100644 tests/unit/UpdaterTest.php diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 00000000..0392fda4 --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":2,"defects":[],"times":{"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithSimpleSuffix":0.003,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithLeadingSlash":0,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithMultipleLeadingSlashes":0,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathResultHasNoDoubleSlash":0.001,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathPreservesRelativePathStructure":0,"NC\\Updater\\Tests\\UpdaterTest::testConstructorThrowsOnEmptyBaseDir":0.001,"NC\\Updater\\Tests\\UpdaterTest::testConstructorThrowsOnInvalidBaseDir":0}} \ No newline at end of file diff --git a/Makefile b/Makefile index 273f7e7c..6ec4b3e6 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ test/vendor: test: updater.phar test/vendor cd tests && ../vendor/bin/behat +test-unit: test/vendor + vendor-bin/tests/vendor/bin/phpunit + test-cli: updater.phar test/vendor cd tests && ../vendor/bin/behat features/cli.feature diff --git a/index.php b/index.php index 277bfa7e..4a776fbd 100644 --- a/index.php +++ b/index.php @@ -81,7 +81,7 @@ public function __construct( throw new \Exception('Could not read data directory from config.php.'); } - $versionFileName = $this->nextcloudDir . '/version.php'; + $versionFileName = $this->buildPath('version.php'); if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -111,6 +111,17 @@ public function __construct( $this->buildTime = $buildTime; } + /** + * Builds an absolute path by joining the Nextcloud root directory with the provided relative path. + * Handles leading and trailing slashes to prevent double-slash issues. + * + * @param string $suffix Relative path to append (with or without leading slash) + * @return string The absolute path + */ + public function buildPath(string $suffix): string { + return rtrim($this->nextcloudDir, '/') . '/' . ltrim($suffix, '/'); + } + /** * @return array{array, string} */ @@ -121,7 +132,7 @@ private function readConfigFile(): array { throw new \Exception('Configuration not found in ' . $dir); } } else { - $configFileName = $this->nextcloudDir . '/config/config.php'; + $configFileName = $this->buildPath('config/config.php'); } if (!file_exists($configFileName)) { @@ -335,8 +346,8 @@ private function getAppDirectories(): array { throw new \Exception('Invalid configuration in apps_paths configuration key'); } - if (str_starts_with($appsPath['path'], $this->nextcloudDir . '/')) { - $relativePath = substr($appsPath['path'], strlen($this->nextcloudDir . '/')); + if (str_starts_with($appsPath['path'], $this->buildPath(''))) { + $relativePath = substr($appsPath['path'], strlen($this->buildPath(''))); if ($relativePath !== 'apps') { $expected[] = $relativePath; } @@ -436,13 +447,13 @@ public function checkWritePermissions(): void { } // Special handling for included default theme - foreach ($this->getRecursiveDirectoryIterator($this->nextcloudDir . '/themes/example', $excludedElements) as $fileInfo) { + foreach ($this->getRecursiveDirectoryIterator($this->buildPath('themes/example'), $excludedElements) as $fileInfo) { if (!$fileInfo->isWritable()) { $notWritablePaths[] = $fileInfo->getFilename(); } } - $themesReadmeFileInfo = new \SplFileInfo($this->nextcloudDir . '/themes/README'); + $themesReadmeFileInfo = new \SplFileInfo($this->buildPath('themes/README')); if (!$themesReadmeFileInfo->isWritable()) { $notWritablePaths[] = $themesReadmeFileInfo->getFilename(); } @@ -502,14 +513,14 @@ public function createBackup(): void { } foreach ($this->getRecursiveDirectoryIterator($this->nextcloudDir, $excludedElements) as $absolutePath => $fileInfo) { - $relativePath = explode($this->nextcloudDir, $absolutePath)[1]; + $relativePath = ltrim(substr($absolutePath, strlen($this->nextcloudDir)), '/'); $relativeDirectory = dirname($relativePath); // Create folder if it doesn't exist - if (!file_exists($backupFolderLocation . '/' . $relativeDirectory)) { - $state = mkdir($backupFolderLocation . '/' . $relativeDirectory, 0750, true); + if (!file_exists($backupFolderLocation . $relativeDirectory)) { + $state = mkdir($backupFolderLocation . $relativeDirectory, 0750, true); if ($state === false) { - throw new \Exception('Could not create folder: ' . $backupFolderLocation . '/' . $relativeDirectory); + throw new \Exception('Could not create folder: ' . $backupFolderLocation . $relativeDirectory); } } @@ -949,7 +960,7 @@ public function extractDownload(): void { // Ensure that the downloaded version is not lower $downloadedVersion = $this->getVersionByVersionFile(dirname($downloadedFilePath) . '/nextcloud/version.php'); - $currentVersion = $this->getVersionByVersionFile($this->nextcloudDir . '/version.php'); + $currentVersion = $this->getVersionByVersionFile($this->buildPath('version.php')); if (version_compare($downloadedVersion, $currentVersion, '<')) { throw new \Exception('Downloaded version is lower than installed version'); } @@ -977,7 +988,7 @@ public function replaceEntryPoints(): void { $content = "silentLog('[info] replace ' . $file); - $parentDir = dirname($this->nextcloudDir . '/' . $file); + $parentDir = dirname($this->buildPath($file)); if (!file_exists($parentDir)) { $r = mkdir($parentDir); if (!$r) { @@ -985,7 +996,7 @@ public function replaceEntryPoints(): void { } } - $state = file_put_contents($this->nextcloudDir . '/' . $file, $content); + $state = file_put_contents($this->buildPath($file), $content); if ($state === false) { throw new \Exception("Can't replace entry point: " . $file); } @@ -1028,7 +1039,7 @@ private function recursiveDelete(string $folder): void { public function deleteOldFiles(): void { $this->silentLog('[info] deleteOldFiles()'); - $shippedAppsFile = $this->nextcloudDir . '/core/shipped.json'; + $shippedAppsFile = $this->buildPath('core/shipped.json'); $shippedAppsFileContent = file_get_contents($shippedAppsFile); if ($shippedAppsFileContent === false) { throw new \Exception('core/shipped.json is not available'); @@ -1056,10 +1067,10 @@ public function deleteOldFiles(): void { $shippedApps = array_merge($shippedApps, $newShippedApps); /** @var string $app */ foreach ($shippedApps as $app) { - $this->recursiveDelete($this->nextcloudDir . '/apps/' . $app); + $this->recursiveDelete($this->buildPath('apps/' . $app)); } - $configSampleFile = $this->nextcloudDir . '/config/config.sample.php'; + $configSampleFile = $this->buildPath('config/config.sample.php'); if (file_exists($configSampleFile)) { $this->silentLog('[info] config sample exists'); @@ -1070,7 +1081,7 @@ public function deleteOldFiles(): void { } } - $themesReadme = $this->nextcloudDir . '/themes/README'; + $themesReadme = $this->buildPath('themes/README'); if (file_exists($themesReadme)) { $this->silentLog('[info] themes README exists'); @@ -1081,7 +1092,7 @@ public function deleteOldFiles(): void { } } - $this->recursiveDelete($this->nextcloudDir . '/themes/example/'); + $this->recursiveDelete($this->buildPath('themes/example/')); // Delete the rest $excludedElements = [ @@ -1131,20 +1142,20 @@ private function moveWithExclusions(string $dataLocation, array $excludedElement $fileName = explode($dataLocation, $path)[1]; if ($fileInfo->isFile()) { - if (!file_exists($this->nextcloudDir . '/' . dirname($fileName))) { - $state = mkdir($this->nextcloudDir . '/' . dirname($fileName), 0755, true); + if (!file_exists($this->buildPath(dirname($fileName)))) { + $state = mkdir($this->buildPath(dirname($fileName)), 0755, true); if ($state === false) { - throw new \Exception('Could not mkdir ' . $this->nextcloudDir . '/' . dirname($fileName)); + throw new \Exception('Could not mkdir ' . $this->buildPath(dirname($fileName))); } } - $state = @rename($path, $this->nextcloudDir . '/' . $fileName); + $state = @rename($path, $this->buildPath($fileName)); if ($state === false) { throw new \Exception( sprintf( 'Could not rename %s to %s', $path, - $this->nextcloudDir . '/' . $fileName + $this->buildPath($fileName) ) ); } @@ -1217,7 +1228,7 @@ public function finalize(): void { $user_ini_additional_lines = implode(PHP_EOL, $user_ini_additional_lines); } - $result = file_put_contents($this->nextcloudDir . '/.user.ini', PHP_EOL . '; Additional settings from config.php:' . PHP_EOL . $user_ini_additional_lines . PHP_EOL, FILE_APPEND); + $result = file_put_contents($this->buildPath('.user.ini'), PHP_EOL . '; Additional settings from config.php:' . PHP_EOL . $user_ini_additional_lines . PHP_EOL, FILE_APPEND); if ($result === false) { throw new \Exception('Could not append to .user.ini'); } diff --git a/lib/Updater.php b/lib/Updater.php index 9a915277..540d0392 100644 --- a/lib/Updater.php +++ b/lib/Updater.php @@ -65,7 +65,7 @@ public function __construct( throw new \Exception('Could not read data directory from config.php.'); } - $versionFileName = $this->nextcloudDir . '/version.php'; + $versionFileName = $this->buildPath('version.php'); if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -95,6 +95,17 @@ public function __construct( $this->buildTime = $buildTime; } + /** + * Builds an absolute path by joining the Nextcloud root directory with the provided relative path. + * Handles leading and trailing slashes to prevent double-slash issues. + * + * @param string $suffix Relative path to append (with or without leading slash) + * @return string The absolute path + */ + public function buildPath(string $suffix): string { + return rtrim($this->nextcloudDir, '/') . '/' . ltrim($suffix, '/'); + } + /** * @return array{array, string} */ @@ -105,7 +116,7 @@ private function readConfigFile(): array { throw new \Exception('Configuration not found in ' . $dir); } } else { - $configFileName = $this->nextcloudDir . '/config/config.php'; + $configFileName = $this->buildPath('config/config.php'); } if (!file_exists($configFileName)) { @@ -319,8 +330,8 @@ private function getAppDirectories(): array { throw new \Exception('Invalid configuration in apps_paths configuration key'); } - if (str_starts_with($appsPath['path'], $this->nextcloudDir . '/')) { - $relativePath = substr($appsPath['path'], strlen($this->nextcloudDir . '/')); + if (str_starts_with($appsPath['path'], $this->buildPath(''))) { + $relativePath = substr($appsPath['path'], strlen($this->buildPath(''))); if ($relativePath !== 'apps') { $expected[] = $relativePath; } @@ -420,13 +431,13 @@ public function checkWritePermissions(): void { } // Special handling for included default theme - foreach ($this->getRecursiveDirectoryIterator($this->nextcloudDir . '/themes/example', $excludedElements) as $fileInfo) { + foreach ($this->getRecursiveDirectoryIterator($this->buildPath('themes/example'), $excludedElements) as $fileInfo) { if (!$fileInfo->isWritable()) { $notWritablePaths[] = $fileInfo->getFilename(); } } - $themesReadmeFileInfo = new \SplFileInfo($this->nextcloudDir . '/themes/README'); + $themesReadmeFileInfo = new \SplFileInfo($this->buildPath('themes/README')); if (!$themesReadmeFileInfo->isWritable()) { $notWritablePaths[] = $themesReadmeFileInfo->getFilename(); } @@ -486,14 +497,14 @@ public function createBackup(): void { } foreach ($this->getRecursiveDirectoryIterator($this->nextcloudDir, $excludedElements) as $absolutePath => $fileInfo) { - $relativePath = explode($this->nextcloudDir, $absolutePath)[1]; + $relativePath = ltrim(substr($absolutePath, strlen($this->nextcloudDir)), '/'); $relativeDirectory = dirname($relativePath); // Create folder if it doesn't exist - if (!file_exists($backupFolderLocation . '/' . $relativeDirectory)) { - $state = mkdir($backupFolderLocation . '/' . $relativeDirectory, 0750, true); + if (!file_exists($backupFolderLocation . $relativeDirectory)) { + $state = mkdir($backupFolderLocation . $relativeDirectory, 0750, true); if ($state === false) { - throw new \Exception('Could not create folder: ' . $backupFolderLocation . '/' . $relativeDirectory); + throw new \Exception('Could not create folder: ' . $backupFolderLocation . $relativeDirectory); } } @@ -933,7 +944,7 @@ public function extractDownload(): void { // Ensure that the downloaded version is not lower $downloadedVersion = $this->getVersionByVersionFile(dirname($downloadedFilePath) . '/nextcloud/version.php'); - $currentVersion = $this->getVersionByVersionFile($this->nextcloudDir . '/version.php'); + $currentVersion = $this->getVersionByVersionFile($this->buildPath('version.php')); if (version_compare($downloadedVersion, $currentVersion, '<')) { throw new \Exception('Downloaded version is lower than installed version'); } @@ -961,7 +972,7 @@ public function replaceEntryPoints(): void { $content = "silentLog('[info] replace ' . $file); - $parentDir = dirname($this->nextcloudDir . '/' . $file); + $parentDir = dirname($this->buildPath($file)); if (!file_exists($parentDir)) { $r = mkdir($parentDir); if (!$r) { @@ -969,7 +980,7 @@ public function replaceEntryPoints(): void { } } - $state = file_put_contents($this->nextcloudDir . '/' . $file, $content); + $state = file_put_contents($this->buildPath($file), $content); if ($state === false) { throw new \Exception("Can't replace entry point: " . $file); } @@ -1012,7 +1023,7 @@ private function recursiveDelete(string $folder): void { public function deleteOldFiles(): void { $this->silentLog('[info] deleteOldFiles()'); - $shippedAppsFile = $this->nextcloudDir . '/core/shipped.json'; + $shippedAppsFile = $this->buildPath('core/shipped.json'); $shippedAppsFileContent = file_get_contents($shippedAppsFile); if ($shippedAppsFileContent === false) { throw new \Exception('core/shipped.json is not available'); @@ -1040,10 +1051,10 @@ public function deleteOldFiles(): void { $shippedApps = array_merge($shippedApps, $newShippedApps); /** @var string $app */ foreach ($shippedApps as $app) { - $this->recursiveDelete($this->nextcloudDir . '/apps/' . $app); + $this->recursiveDelete($this->buildPath('apps/' . $app)); } - $configSampleFile = $this->nextcloudDir . '/config/config.sample.php'; + $configSampleFile = $this->buildPath('config/config.sample.php'); if (file_exists($configSampleFile)) { $this->silentLog('[info] config sample exists'); @@ -1054,7 +1065,7 @@ public function deleteOldFiles(): void { } } - $themesReadme = $this->nextcloudDir . '/themes/README'; + $themesReadme = $this->buildPath('themes/README'); if (file_exists($themesReadme)) { $this->silentLog('[info] themes README exists'); @@ -1065,7 +1076,7 @@ public function deleteOldFiles(): void { } } - $this->recursiveDelete($this->nextcloudDir . '/themes/example/'); + $this->recursiveDelete($this->buildPath('themes/example/')); // Delete the rest $excludedElements = [ @@ -1115,20 +1126,20 @@ private function moveWithExclusions(string $dataLocation, array $excludedElement $fileName = explode($dataLocation, $path)[1]; if ($fileInfo->isFile()) { - if (!file_exists($this->nextcloudDir . '/' . dirname($fileName))) { - $state = mkdir($this->nextcloudDir . '/' . dirname($fileName), 0755, true); + if (!file_exists($this->buildPath(dirname($fileName)))) { + $state = mkdir($this->buildPath(dirname($fileName)), 0755, true); if ($state === false) { - throw new \Exception('Could not mkdir ' . $this->nextcloudDir . '/' . dirname($fileName)); + throw new \Exception('Could not mkdir ' . $this->buildPath(dirname($fileName))); } } - $state = @rename($path, $this->nextcloudDir . '/' . $fileName); + $state = @rename($path, $this->buildPath($fileName)); if ($state === false) { throw new \Exception( sprintf( 'Could not rename %s to %s', $path, - $this->nextcloudDir . '/' . $fileName + $this->buildPath($fileName) ) ); } @@ -1201,7 +1212,7 @@ public function finalize(): void { $user_ini_additional_lines = implode(PHP_EOL, $user_ini_additional_lines); } - $result = file_put_contents($this->nextcloudDir . '/.user.ini', PHP_EOL . '; Additional settings from config.php:' . PHP_EOL . $user_ini_additional_lines . PHP_EOL, FILE_APPEND); + $result = file_put_contents($this->buildPath('.user.ini'), PHP_EOL . '; Additional settings from config.php:' . PHP_EOL . $user_ini_additional_lines . PHP_EOL, FILE_APPEND); if ($result === false) { throw new \Exception('Could not append to .user.ini'); } diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 00000000..5860dd1e --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,15 @@ + + + + + + tests/unit + + + diff --git a/tests/unit/UpdaterTest.php b/tests/unit/UpdaterTest.php new file mode 100644 index 00000000..422ef7c1 --- /dev/null +++ b/tests/unit/UpdaterTest.php @@ -0,0 +1,99 @@ +tempDir = sys_get_temp_dir() . '/nextcloud-updater-test-' . uniqid(); + $this->configDir = sys_get_temp_dir() . '/nextcloud-config-test-' . uniqid(); + + mkdir($this->tempDir . '/updater', 0755, true); + mkdir($this->configDir, 0755, true); + + // Write a minimal config.php with required keys + file_put_contents($this->configDir . '/config.php', ' "/tmp/nc-test-data",' . + '"version" => "30.0.0.1",' . + '"instanceid" => "testid",' . + '];'); + + putenv('NEXTCLOUD_CONFIG_DIR=' . $this->configDir); + } + + protected function tearDown(): void { + putenv('NEXTCLOUD_CONFIG_DIR='); + + // Clean up temp directories + if ($this->configDir !== '') { + @unlink($this->configDir . '/config.php'); + @rmdir($this->configDir); + } + if ($this->tempDir !== '') { + @rmdir($this->tempDir . '/updater'); + @rmdir($this->tempDir); + } + } + + private function makeUpdater(): Updater { + return new Updater($this->tempDir . '/updater'); + } + + public function testBuildPathWithSimpleSuffix(): void { + $updater = $this->makeUpdater(); + $this->assertSame($this->tempDir . '/config/config.php', $updater->buildPath('config/config.php')); + } + + public function testBuildPathWithLeadingSlash(): void { + $updater = $this->makeUpdater(); + // A suffix with a leading slash should produce the same result as without + $this->assertSame( + $updater->buildPath('config/config.php'), + $updater->buildPath('/config/config.php') + ); + } + + public function testBuildPathWithMultipleLeadingSlashes(): void { + $updater = $this->makeUpdater(); + // Multiple leading slashes should be stripped + $this->assertSame( + $updater->buildPath('config/config.php'), + $updater->buildPath('///config/config.php') + ); + } + + public function testBuildPathResultHasNoDoubleSlash(): void { + $updater = $this->makeUpdater(); + $result = $updater->buildPath('/some/path'); + $this->assertStringNotContainsString('//', $result); + } + + public function testBuildPathPreservesRelativePathStructure(): void { + $updater = $this->makeUpdater(); + $this->assertSame($this->tempDir . '/apps/myapp', $updater->buildPath('apps/myapp')); + } + + public function testConstructorThrowsOnEmptyBaseDir(): void { + putenv('NEXTCLOUD_CONFIG_DIR='); + $this->expectException(\Exception::class); + new Updater(''); + } + + public function testConstructorThrowsOnInvalidBaseDir(): void { + $this->expectException(\Exception::class); + // Use a path whose parent doesn't exist + new Updater('/nonexistent/path/that/does/not/exist/updater'); + } +} diff --git a/vendor-bin/tests/composer.json b/vendor-bin/tests/composer.json index 0050b328..425d35ff 100644 --- a/vendor-bin/tests/composer.json +++ b/vendor-bin/tests/composer.json @@ -1,6 +1,7 @@ { "require-dev": { - "behat/behat": "^3.19" + "behat/behat": "^3.19", + "phpunit/phpunit": "^11.0" }, "config": { "platform": { diff --git a/vendor-bin/tests/composer.lock b/vendor-bin/tests/composer.lock index 81b94f54..416c9ec5 100644 --- a/vendor-bin/tests/composer.lock +++ b/vendor-bin/tests/composer.lock @@ -4,21 +4,21 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ced7b79292f4d9a457935f83117e5777", + "content-hash": "a05d65ac53a73baa0d16683259e5b785", "packages": [], "packages-dev": [ { "name": "behat/behat", - "version": "v3.27.0", + "version": "v3.29.0", "source": { "type": "git", "url": "https://github.com/Behat/Behat.git", - "reference": "3282ad774358e4eaf533855e9a1f48559894d1b5" + "reference": "51bdf81639a14645c5d2c06926f4aa37d204921b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/3282ad774358e4eaf533855e9a1f48559894d1b5", - "reference": "3282ad774358e4eaf533855e9a1f48559894d1b5", + "url": "https://api.github.com/repos/Behat/Behat/zipball/51bdf81639a14645c5d2c06926f4aa37d204921b", + "reference": "51bdf81639a14645c5d2c06926f4aa37d204921b", "shasum": "" }, "require": { @@ -37,8 +37,8 @@ "symfony/yaml": "^5.4 || ^6.4 || ^7.0" }, "require-dev": { - "friendsofphp/php-cs-fixer": "^3.68", "opis/json-schema": "^2.5", + "php-cs-fixer/shim": "^3.89", "phpstan/phpstan": "^2.0", "phpunit/phpunit": "^9.6", "rector/rector": "2.1.7", @@ -54,11 +54,6 @@ "bin/behat" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, "autoload": { "psr-4": { "Behat\\Hook\\": "src/Behat/Hook/", @@ -98,22 +93,36 @@ ], "support": { "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.27.0" + "source": "https://github.com/Behat/Behat/tree/v3.29.0" }, - "time": "2025-11-23T12:12:41+00:00" + "funding": [ + { + "url": "https://github.com/acoulton", + "type": "github" + }, + { + "url": "https://github.com/carlos-granados", + "type": "github" + }, + { + "url": "https://github.com/stof", + "type": "github" + } + ], + "time": "2025-12-11T09:51:30+00:00" }, { "name": "behat/gherkin", - "version": "v4.15.0", + "version": "v4.16.1", "source": { "type": "git", "url": "https://github.com/Behat/Gherkin.git", - "reference": "05a7459283e8e6af0d46ec25b8bb5960ca3cfa7b" + "reference": "e26037937dfd48528746764dd870bc5d0836665f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Gherkin/zipball/05a7459283e8e6af0d46ec25b8bb5960ca3cfa7b", - "reference": "05a7459283e8e6af0d46ec25b8bb5960ca3cfa7b", + "url": "https://api.github.com/repos/Behat/Gherkin/zipball/e26037937dfd48528746764dd870bc5d0836665f", + "reference": "e26037937dfd48528746764dd870bc5d0836665f", "shasum": "" }, "require": { @@ -121,7 +130,7 @@ "php": ">=8.1 <8.6" }, "require-dev": { - "cucumber/gherkin-monorepo": "dev-gherkin-v36.0.0", + "cucumber/gherkin-monorepo": "dev-gherkin-v37.0.0", "friendsofphp/php-cs-fixer": "^3.77", "mikey179/vfsstream": "^1.6", "phpstan/extension-installer": "^1", @@ -167,9 +176,23 @@ ], "support": { "issues": "https://github.com/Behat/Gherkin/issues", - "source": "https://github.com/Behat/Gherkin/tree/v4.15.0" + "source": "https://github.com/Behat/Gherkin/tree/v4.16.1" }, - "time": "2025-11-05T15:34:04+00:00" + "funding": [ + { + "url": "https://github.com/acoulton", + "type": "github" + }, + { + "url": "https://github.com/carlos-granados", + "type": "github" + }, + { + "url": "https://github.com/stof", + "type": "github" + } + ], + "time": "2025-12-08T16:12:58+00:00" }, { "name": "composer/pcre", @@ -223,136 +246,1762 @@ "homepage": "http://seld.be" } ], - "description": "PCRE wrapping library that offers type-safe preg_* replacements.", - "keywords": [ - "PCRE", - "preg", - "regex", - "regular expression" - ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.5", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.1", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.3.1" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.46" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-12-24T07:01:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" + } + ], + "time": "2026-02-02T13:52:54+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.55", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.12", + "phpunit/php-file-iterator": "^5.1.1", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.3", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.2", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/recursion-context": "^6.0.3", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-02-18T12:37:06+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-19T07:56:08+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:26:40+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-05-21T11:55:47+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:12:51+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.2" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-11-12T16:29:46+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "composer/xdebug-handler", - "version": "3.0.5", + "name": "sebastian/object-reflector", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", - "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "composer/pcre": "^1 || ^2 || ^3", - "php": "^7.2.5 || ^8.0", - "psr/log": "^1 || ^2 || ^3" + "php": ">=8.2" }, "require-dev": { - "phpstan/phpstan": "^1.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" + "phpunit/phpunit": "^11.0" }, "type": "library", - "autoload": { - "psr-4": { - "Composer\\XdebugHandler\\": "src" + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" } ], - "description": "Restarts a process without Xdebug.", - "keywords": [ - "Xdebug", - "performance" - ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "irc": "ircs://irc.libera.chat:6697/composer", - "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-05-06T16:37:16+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "nikic/php-parser", - "version": "v5.6.2", + "name": "sebastian/recursion-context", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "3a454ca033b9e06b63282ce19562e892747449bb" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3a454ca033b9e06b63282ce19562e892747449bb", - "reference": "3a454ca033b9e06b63282ce19562e892747449bb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" + "php": ">=8.2" }, "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^11.3" }, - "bin": [ - "bin/php-parse" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -360,185 +2009,232 @@ ], "authors": [ { - "name": "Nikita Popov" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.2" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" }, - "time": "2025-10-21T19:32:17+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-13T04:42:22+00:00" }, { - "name": "psr/container", - "version": "2.0.2", + "name": "sebastian/type", + "version": "5.1.3", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", "shasum": "" }, "require": { - "php": ">=7.4.0" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "5.1-dev" } }, "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" }, - "time": "2021-11-05T16:47:00+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" + } + ], + "time": "2025-08-09T06:55:48+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "5.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "psr/log", - "version": "3.0.2", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=8.0.0" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, + "type": "library", "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } + "classmap": [ + "lib/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "A static analysis tool to detect side effects in PHP code", "keywords": [ - "log", - "psr", - "psr-3" + "static analysis" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, - "time": "2024-09-11T13:17:53+00:00" + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" }, { "name": "symfony/config", - "version": "v7.4.0", + "version": "v7.4.7", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "f76c74e93bce2b9285f2dad7fbd06fa8182a7a41" + "reference": "6c17162555bfb58957a55bb0e43e00035b6ae3d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/f76c74e93bce2b9285f2dad7fbd06fa8182a7a41", - "reference": "f76c74e93bce2b9285f2dad7fbd06fa8182a7a41", + "url": "https://api.github.com/repos/symfony/config/zipball/6c17162555bfb58957a55bb0e43e00035b6ae3d5", + "reference": "6c17162555bfb58957a55bb0e43e00035b6ae3d5", "shasum": "" }, "require": { @@ -584,7 +2280,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.0" + "source": "https://github.com/symfony/config/tree/v7.4.7" }, "funding": [ { @@ -604,20 +2300,20 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-03-06T10:41:14+00:00" }, { "name": "symfony/console", - "version": "v7.4.0", + "version": "v7.4.7", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8" + "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8", - "reference": "0bc0f45254b99c58d45a8fbf9fb955d46cbd1bb8", + "url": "https://api.github.com/repos/symfony/console/zipball/e1e6770440fb9c9b0cf725f81d1361ad1835329d", + "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d", "shasum": "" }, "require": { @@ -682,7 +2378,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.0" + "source": "https://github.com/symfony/console/tree/v7.4.7" }, "funding": [ { @@ -702,20 +2398,20 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-03-06T14:06:20+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.0", + "version": "v7.4.7", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "3972ca7bbd649467b21a54870721b9e9f3652f9b" + "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/3972ca7bbd649467b21a54870721b9e9f3652f9b", - "reference": "3972ca7bbd649467b21a54870721b9e9f3652f9b", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", + "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", "shasum": "" }, "require": { @@ -766,7 +2462,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.0" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.7" }, "funding": [ { @@ -786,7 +2482,7 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-03-03T07:48:48+00:00" }, { "name": "symfony/deprecation-contracts", @@ -857,16 +2553,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.0", + "version": "v7.4.4", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d" + "reference": "dc2c0eba1af673e736bb851d747d266108aea746" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9dddcddff1ef974ad87b3708e4b442dc38b2261d", - "reference": "9dddcddff1ef974ad87b3708e4b442dc38b2261d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dc2c0eba1af673e736bb851d747d266108aea746", + "reference": "dc2c0eba1af673e736bb851d747d266108aea746", "shasum": "" }, "require": { @@ -918,7 +2614,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.4" }, "funding": [ { @@ -938,7 +2634,7 @@ "type": "tidelift" } ], - "time": "2025-10-28T09:38:46+00:00" + "time": "2026-01-05T11:45:34+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -1018,16 +2714,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "d551b38811096d0be9c4691d406991b47c0c630a" + "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/d551b38811096d0be9c4691d406991b47c0c630a", - "reference": "d551b38811096d0be9c4691d406991b47c0c630a", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3ebc794fa5315e59fd122561623c2e2e4280538e", + "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e", "shasum": "" }, "require": { @@ -1064,7 +2760,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.0" + "source": "https://github.com/symfony/filesystem/tree/v7.4.6" }, "funding": [ { @@ -1084,7 +2780,7 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-02-25T16:50:00+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1510,16 +3206,16 @@ }, { "name": "symfony/string", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003" + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d50e862cb0a0e0886f73ca1f31b865efbb795003", - "reference": "d50e862cb0a0e0886f73ca1f31b865efbb795003", + "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", + "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", "shasum": "" }, "require": { @@ -1577,7 +3273,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.0" + "source": "https://github.com/symfony/string/tree/v7.4.6" }, "funding": [ { @@ -1597,20 +3293,20 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-02-09T09:33:46+00:00" }, { "name": "symfony/translation", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68" + "reference": "1888cf064399868af3784b9e043240f1d89d25ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/2d01ca0da3f092f91eeedb46f24aa30d2fca8f68", - "reference": "2d01ca0da3f092f91eeedb46f24aa30d2fca8f68", + "url": "https://api.github.com/repos/symfony/translation/zipball/1888cf064399868af3784b9e043240f1d89d25ce", + "reference": "1888cf064399868af3784b9e043240f1d89d25ce", "shasum": "" }, "require": { @@ -1677,7 +3373,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.4.0" + "source": "https://github.com/symfony/translation/tree/v7.4.6" }, "funding": [ { @@ -1697,7 +3393,7 @@ "type": "tidelift" } ], - "time": "2025-11-27T13:27:24+00:00" + "time": "2026-02-17T07:53:42+00:00" }, { "name": "symfony/translation-contracts", @@ -1864,16 +3560,16 @@ }, { "name": "symfony/yaml", - "version": "v7.4.0", + "version": "v7.4.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810" + "reference": "58751048de17bae71c5aa0d13cb19d79bca26391" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6c84a4b55aee4cd02034d1c528e83f69ddf63810", - "reference": "6c84a4b55aee4cd02034d1c528e83f69ddf63810", + "url": "https://api.github.com/repos/symfony/yaml/zipball/58751048de17bae71c5aa0d13cb19d79bca26391", + "reference": "58751048de17bae71c5aa0d13cb19d79bca26391", "shasum": "" }, "require": { @@ -1916,7 +3612,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.0" + "source": "https://github.com/symfony/yaml/tree/v7.4.6" }, "funding": [ { @@ -1936,7 +3632,57 @@ "type": "tidelift" } ], - "time": "2025-11-16T10:14:42+00:00" + "time": "2026-02-09T09:33:46+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], @@ -1949,5 +3695,5 @@ "platform-overrides": { "php": "8.2" }, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } From bba59b1ee357c6a561b973a6f0b7423d6bd6924a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 06:45:27 +0000 Subject: [PATCH 3/9] refactor: move phpunit to dedicated vendor-bin/phpunit following nextcloud/privacy pattern Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/5f2df1e7-e17a-4242-b4c3-91a831b9048d --- .gitignore | 1 + .phpunit.result.cache | 1 - Makefile | 7 +- composer.json | 3 +- phpunit.xml | 2 +- vendor-bin/phpunit/composer.json | 10 + vendor-bin/phpunit/composer.lock | 1803 ++++++++++++++++++++++++++++ vendor-bin/tests/composer.json | 3 +- vendor-bin/tests/composer.lock | 1919 ++---------------------------- 9 files changed, 1921 insertions(+), 1828 deletions(-) delete mode 100644 .phpunit.result.cache create mode 100644 vendor-bin/phpunit/composer.json create mode 100644 vendor-bin/phpunit/composer.lock diff --git a/.gitignore b/.gitignore index 75a13176..4eacecc9 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ /vendor/symfony/service-contracts/Test /vendor-bin/**/vendor .php-cs-fixer.cache +.phpunit.result.cache diff --git a/.phpunit.result.cache b/.phpunit.result.cache deleted file mode 100644 index 0392fda4..00000000 --- a/.phpunit.result.cache +++ /dev/null @@ -1 +0,0 @@ -{"version":2,"defects":[],"times":{"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithSimpleSuffix":0.003,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithLeadingSlash":0,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathWithMultipleLeadingSlashes":0,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathResultHasNoDoubleSlash":0.001,"NC\\Updater\\Tests\\UpdaterTest::testBuildPathPreservesRelativePathStructure":0,"NC\\Updater\\Tests\\UpdaterTest::testConstructorThrowsOnEmptyBaseDir":0.001,"NC\\Updater\\Tests\\UpdaterTest::testConstructorThrowsOnInvalidBaseDir":0}} \ No newline at end of file diff --git a/Makefile b/Makefile index 6ec4b3e6..2a6503c7 100644 --- a/Makefile +++ b/Makefile @@ -21,11 +21,14 @@ index.php: lib/UpdateException.php lib/LogException.php lib/Updater.php index.we test/vendor: composer bin tests install +vendor/bin/phpunit: + composer bin phpunit install + test: updater.phar test/vendor cd tests && ../vendor/bin/behat -test-unit: test/vendor - vendor-bin/tests/vendor/bin/phpunit +test-unit: vendor/bin/phpunit + composer run test:unit test-cli: updater.phar test/vendor cd tests && ../vendor/bin/behat features/cli.feature diff --git a/composer.json b/composer.json index d05b7108..85dba635 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,8 @@ "psalm": "psalm --threads=$(nproc)", "psalm:ci": "psalm --threads=1", "psalm:fix": "- --issues=InvalidReturnType,InvalidNullableReturnType,MissingParamType,InvalidFalsableReturnType", - "rector": "rector && composer run cs:fix" + "rector": "rector && composer run cs:fix", + "test:unit": "phpunit -c phpunit.xml" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8" diff --git a/phpunit.xml b/phpunit.xml index 5860dd1e..8e2a09a2 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later --> diff --git a/vendor-bin/phpunit/composer.json b/vendor-bin/phpunit/composer.json new file mode 100644 index 00000000..d0c6fafa --- /dev/null +++ b/vendor-bin/phpunit/composer.json @@ -0,0 +1,10 @@ +{ + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "config": { + "platform": { + "php": "8.2" + } + } +} diff --git a/vendor-bin/phpunit/composer.lock b/vendor-bin/phpunit/composer.lock new file mode 100644 index 00000000..d63f5698 --- /dev/null +++ b/vendor-bin/phpunit/composer.lock @@ -0,0 +1,1803 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "2d32e5d858a15b0462bdf724a01645a5", + "packages": [], + "packages-dev": [ + { + "name": "myclabs/deep-copy", + "version": "1.13.4", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v5.7.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + }, + "time": "2025-12-06T11:56:16+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.12", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", + "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.7.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.1", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.3.1" + }, + "require-dev": { + "phpunit/phpunit": "^11.5.46" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-12-24T07:01:01+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", + "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", + "type": "tidelift" + } + ], + "time": "2026-02-02T13:52:54+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.5.55", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", + "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.12", + "phpunit/php-file-iterator": "^5.1.1", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.3", + "sebastian/comparator": "^6.3.3", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.1", + "sebastian/exporter": "^6.3.2", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/recursion-context": "^6.0.3", + "sebastian/type": "^5.1.3", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-02-18T12:37:06+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-03-19T07:56:08+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:45:54+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.3.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:26:40+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", + "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" + } + ], + "time": "2025-05-21T11:55:47+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.3.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", + "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:12:51+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-13T04:42:22+00:00" + }, + { + "name": "sebastian/type", + "version": "5.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" + } + ], + "time": "2025-08-09T06:55:48+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T05:16:32+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": false, + "prefer-lowest": false, + "platform": {}, + "platform-dev": {}, + "platform-overrides": { + "php": "8.2" + }, + "plugin-api-version": "2.9.0" +} diff --git a/vendor-bin/tests/composer.json b/vendor-bin/tests/composer.json index 425d35ff..0050b328 100644 --- a/vendor-bin/tests/composer.json +++ b/vendor-bin/tests/composer.json @@ -1,7 +1,6 @@ { "require-dev": { - "behat/behat": "^3.19", - "phpunit/phpunit": "^11.0" + "behat/behat": "^3.19" }, "config": { "platform": { diff --git a/vendor-bin/tests/composer.lock b/vendor-bin/tests/composer.lock index 416c9ec5..f9101e69 100644 --- a/vendor-bin/tests/composer.lock +++ b/vendor-bin/tests/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": "a05d65ac53a73baa0d16683259e5b785", + "content-hash": "ced7b79292f4d9a457935f83117e5777", "packages": [], "packages-dev": [ { @@ -340,1612 +340,42 @@ "time": "2024-05-06T16:37:16+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.13.4", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3 <3.2.2" - }, - "require-dev": { - "doctrine/collections": "^1.6.8", - "doctrine/common": "^2.13.3 || ^3.2.2", - "phpspec/prophecy": "^1.10", - "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" - }, - "type": "library", - "autoload": { - "files": [ - "src/DeepCopy/deep_copy.php" - ], - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" - }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2025-08-01T08:46:24+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v5.7.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" - }, - "time": "2025-12-06T11:56:16+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "54750ef60c58e43759730615a392c31c80e23176" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", - "reference": "54750ef60c58e43759730615a392c31c80e23176", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "support": { - "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.4" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2024-03-03T12:33:53+00:00" - }, - { - "name": "phar-io/version", - "version": "3.2.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "support": { - "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.2.1" - }, - "time": "2022-02-21T01:04:05+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "11.0.12", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2c1ed04922802c15e1de5d7447b4856de949cf56", - "reference": "2c1ed04922802c15e1de5d7447b4856de949cf56", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^5.7.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.1.0", - "phpunit/php-text-template": "^4.0.1", - "sebastian/code-unit-reverse-lookup": "^4.0.1", - "sebastian/complexity": "^4.0.1", - "sebastian/environment": "^7.2.1", - "sebastian/lines-of-code": "^3.0.1", - "sebastian/version": "^5.0.2", - "theseer/tokenizer": "^1.3.1" - }, - "require-dev": { - "phpunit/phpunit": "^11.5.46" - }, - "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.12" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", - "type": "tidelift" - } - ], - "time": "2025-12-24T07:01:01+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "5.1.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/2f3a64888c814fc235386b7387dd5b5ed92ad903", - "reference": "2f3a64888c814fc235386b7387dd5b5ed92ad903", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/php-file-iterator", - "type": "tidelift" - } - ], - "time": "2026-02-02T13:52:54+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", - "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:07:44+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:08:43+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "7.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:09:35+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "11.5.55", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/adc7262fccc12de2b30f12a8aa0b33775d814f00", - "reference": "adc7262fccc12de2b30f12a8aa0b33775d814f00", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.4", - "phar-io/manifest": "^2.0.4", - "phar-io/version": "^3.2.1", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.12", - "phpunit/php-file-iterator": "^5.1.1", - "phpunit/php-invoker": "^5.0.1", - "phpunit/php-text-template": "^4.0.1", - "phpunit/php-timer": "^7.0.1", - "sebastian/cli-parser": "^3.0.2", - "sebastian/code-unit": "^3.0.3", - "sebastian/comparator": "^6.3.3", - "sebastian/diff": "^6.0.2", - "sebastian/environment": "^7.2.1", - "sebastian/exporter": "^6.3.2", - "sebastian/global-state": "^7.0.2", - "sebastian/object-enumerator": "^6.0.1", - "sebastian/recursion-context": "^6.0.3", - "sebastian/type": "^5.1.3", - "sebastian/version": "^5.0.2", - "staabm/side-effects-detector": "^1.0.5" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "11.5-dev" - } - }, - "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.55" - }, - "funding": [ - { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" - } - ], - "time": "2026-02-18T12:37:06+00:00" - }, - { - "name": "psr/container", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", - "shasum": "" - }, - "require": { - "php": ">=7.4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/2.0.2" - }, - "time": "2021-11-05T16:47:00+00:00" - }, - { - "name": "psr/event-dispatcher", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", - "shasum": "" - }, - "require": { - "php": ">=7.2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" - }, - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "psr/log", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Log\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "support": { - "source": "https://github.com/php-fig/log/tree/3.0.2" - }, - "time": "2024-09-11T13:17:53+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", - "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:41:36+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "3.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "reference": "54391c61e4af8078e5b276ab082b6d3c54c9ad64", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2025-03-19T07:56:08+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", - "reference": "183a9b2632194febd219bb9246eee421dad8d45e", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:45:54+00:00" - }, - { - "name": "sebastian/comparator", - "version": "6.3.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", - "reference": "2c95e1e86cb8dd41beb8d502057d1081ccc8eca9", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.4" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.3" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", - "type": "tidelift" - } - ], - "time": "2026-01-24T09:26:40+00:00" - }, - { - "name": "sebastian/complexity", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", - "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:49:50+00:00" - }, - { - "name": "sebastian/diff", - "version": "6.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", - "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:53:05+00:00" - }, - { - "name": "sebastian/environment", - "version": "7.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/a5c75038693ad2e8d4b6c15ba2403532647830c4", - "reference": "a5c75038693ad2e8d4b6c15ba2403532647830c4", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.2.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", - "type": "tidelift" - } - ], - "time": "2025-05-21T11:55:47+00:00" - }, - { - "name": "sebastian/exporter", - "version": "6.3.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/70a298763b40b213ec087c51c739efcaa90bcd74", - "reference": "70a298763b40b213ec087c51c739efcaa90bcd74", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", - "type": "tidelift" - } - ], - "time": "2025-09-24T06:12:51+00:00" - }, - { - "name": "sebastian/global-state", - "version": "7.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", - "reference": "3be331570a721f9a4b5917f4209773de17f747d7", - "shasum": "" - }, - "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "7.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:57:36+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T04:58:38+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "6.0.1", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", - "reference": "f5b498e631a74204185071eb41f33f38d64608aa", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "6.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } + "bin": [ + "bin/php-parse" ], - "time": "2024-07-03T05:00:13+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "4.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1953,275 +383,172 @@ ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "name": "Nikita Popov" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-07-03T05:01:32+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.3", + "name": "psr/container", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc" + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc", - "reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\Container\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3" + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", - "type": "tidelift" - } - ], - "time": "2025-08-13T04:42:22+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { - "name": "sebastian/type", - "version": "5.1.3", + "name": "psr/event-dispatcher", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/f77d2d4e78738c98d9a68d2596fe5e8fa380f449", - "reference": "f77d2d4e78738c98d9a68d2596fe5e8fa380f449", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.3" + "php": ">=7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.1.3" + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/sebastian/type", - "type": "tidelift" - } - ], - "time": "2025-08-09T06:55:48+00:00" + "time": "2019-01-08T18:20:26+00:00" }, { - "name": "sebastian/version", - "version": "5.0.2", + "name": "psr/log", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", - "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "3.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\Log\\": "src" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" } ], - "time": "2024-10-09T05:16:32+00:00" - }, - { - "name": "staabm/side-effects-detector", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "lib/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A static analysis tool to detect side effects in PHP code", + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", "keywords": [ - "static analysis" + "log", + "psr", + "psr-3" ], "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "funding": [ - { - "url": "https://github.com/staabm", - "type": "github" - } - ], - "time": "2024-10-20T05:08:20+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "symfony/config", @@ -3633,56 +1960,6 @@ } ], "time": "2026-02-09T09:33:46+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", - "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "support": { - "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.3.1" - }, - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], From 150f1925b8bff36c1e45ad04f62dccbf7d2a3e7a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 06:53:47 +0000 Subject: [PATCH 4/9] plan: fix moveWithExclusions explode and add #711 regression tests Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/f6fad36e-0af0-4aee-b04b-3faae41f45f3 --- .github/workflows/phpunit.yml | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 .github/workflows/phpunit.yml diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 00000000..db50b9b8 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,66 @@ +# SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors +# SPDX-License-Identifier: MIT + +name: PHPUnit + +on: + pull_request: + push: + branches: + - main + - master + - stable* + +permissions: + contents: read + +concurrency: + group: phpunit-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + phpunit: + runs-on: ubuntu-latest + strategy: + matrix: + php-versions: ["8.2", "8.3", "8.4"] + + name: PHPUnit PHP ${{ matrix.php-versions }} + + steps: + - name: Checkout + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + with: + persist-credentials: false + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@ec406be512d7077f68eed36e63f4d91bc006edc4 # v2.35.4 + with: + php-version: ${{ matrix.php-versions }} + extensions: ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, posix, session, simplexml, xmlreader, xmlwriter, zip, zlib + coverage: none + ini-file: development + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Install dependencies + run: | + composer i + composer bin phpunit install + + - name: PHPUnit + run: composer run test:unit + + summary: + permissions: + contents: none + runs-on: ubuntu-latest-low + needs: phpunit + + if: always() + + name: phpunit-summary + + steps: + - name: Summary status + run: if ${{ needs.phpunit.result != 'success' && needs.phpunit.result != 'skipped' }}; then exit 1; fi From dc688b2b097ffaa4f596e943d3626d5b65e6016a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 06:55:07 +0000 Subject: [PATCH 5/9] fix: replace explode() with substr() in moveWithExclusions(); add issue #711 regression tests Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/f6fad36e-0af0-4aee-b04b-3faae41f45f3 --- index.php | 2 +- lib/Updater.php | 2 +- tests/unit/UpdaterTest.php | 121 +++++++++++++++++++++++++++++++++---- 3 files changed, 111 insertions(+), 14 deletions(-) diff --git a/index.php b/index.php index 4a776fbd..fe86f322 100644 --- a/index.php +++ b/index.php @@ -1139,7 +1139,7 @@ private function moveWithExclusions(string $dataLocation, array $excludedElement } - $fileName = explode($dataLocation, $path)[1]; + $fileName = substr($path, strlen($dataLocation)); if ($fileInfo->isFile()) { if (!file_exists($this->buildPath(dirname($fileName)))) { diff --git a/lib/Updater.php b/lib/Updater.php index 540d0392..edbe65a3 100644 --- a/lib/Updater.php +++ b/lib/Updater.php @@ -1123,7 +1123,7 @@ private function moveWithExclusions(string $dataLocation, array $excludedElement } - $fileName = explode($dataLocation, $path)[1]; + $fileName = substr($path, strlen($dataLocation)); if ($fileInfo->isFile()) { if (!file_exists($this->buildPath(dirname($fileName)))) { diff --git a/tests/unit/UpdaterTest.php b/tests/unit/UpdaterTest.php index 422ef7c1..ed80365b 100644 --- a/tests/unit/UpdaterTest.php +++ b/tests/unit/UpdaterTest.php @@ -14,18 +14,21 @@ class UpdaterTest extends TestCase { private string $tempDir = ''; + private string $dataDir = ''; private string $configDir = ''; protected function setUp(): void { $this->tempDir = sys_get_temp_dir() . '/nextcloud-updater-test-' . uniqid(); + $this->dataDir = sys_get_temp_dir() . '/nextcloud-updater-data-' . uniqid(); $this->configDir = sys_get_temp_dir() . '/nextcloud-config-test-' . uniqid(); mkdir($this->tempDir . '/updater', 0755, true); + mkdir($this->dataDir, 0755, true); mkdir($this->configDir, 0755, true); // Write a minimal config.php with required keys file_put_contents($this->configDir . '/config.php', ' "/tmp/nc-test-data",' . + '"datadirectory" => "' . $this->dataDir . '",' . '"version" => "30.0.0.1",' . '"instanceid" => "testid",' . '];'); @@ -36,21 +39,37 @@ protected function setUp(): void { protected function tearDown(): void { putenv('NEXTCLOUD_CONFIG_DIR='); - // Clean up temp directories - if ($this->configDir !== '') { - @unlink($this->configDir . '/config.php'); - @rmdir($this->configDir); + $this->removeDirectory($this->configDir); + $this->removeDirectory($this->dataDir); + $this->removeDirectory($this->tempDir); + } + + private function removeDirectory(string $dir): void { + if ($dir === '' || !is_dir($dir)) { + return; } - if ($this->tempDir !== '') { - @rmdir($this->tempDir . '/updater'); - @rmdir($this->tempDir); + $items = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($dir, \FilesystemIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + foreach ($items as $item) { + if ($item->isDir()) { + rmdir($item->getRealPath()); + } else { + unlink($item->getRealPath()); + } } + rmdir($dir); } private function makeUpdater(): Updater { return new Updater($this->tempDir . '/updater'); } + // ------------------------------------------------------------------------- + // buildPath() unit tests + // ------------------------------------------------------------------------- + public function testBuildPathWithSimpleSuffix(): void { $updater = $this->makeUpdater(); $this->assertSame($this->tempDir . '/config/config.php', $updater->buildPath('config/config.php')); @@ -58,7 +77,7 @@ public function testBuildPathWithSimpleSuffix(): void { public function testBuildPathWithLeadingSlash(): void { $updater = $this->makeUpdater(); - // A suffix with a leading slash should produce the same result as without + // A suffix with a leading slash must produce the same result as without $this->assertSame( $updater->buildPath('config/config.php'), $updater->buildPath('/config/config.php') @@ -67,7 +86,7 @@ public function testBuildPathWithLeadingSlash(): void { public function testBuildPathWithMultipleLeadingSlashes(): void { $updater = $this->makeUpdater(); - // Multiple leading slashes should be stripped + // Multiple leading slashes must all be stripped $this->assertSame( $updater->buildPath('config/config.php'), $updater->buildPath('///config/config.php') @@ -76,8 +95,7 @@ public function testBuildPathWithMultipleLeadingSlashes(): void { public function testBuildPathResultHasNoDoubleSlash(): void { $updater = $this->makeUpdater(); - $result = $updater->buildPath('/some/path'); - $this->assertStringNotContainsString('//', $result); + $this->assertStringNotContainsString('//', $updater->buildPath('/some/path')); } public function testBuildPathPreservesRelativePathStructure(): void { @@ -85,6 +103,10 @@ public function testBuildPathPreservesRelativePathStructure(): void { $this->assertSame($this->tempDir . '/apps/myapp', $updater->buildPath('apps/myapp')); } + // ------------------------------------------------------------------------- + // Constructor validation tests + // ------------------------------------------------------------------------- + public function testConstructorThrowsOnEmptyBaseDir(): void { putenv('NEXTCLOUD_CONFIG_DIR='); $this->expectException(\Exception::class); @@ -96,4 +118,79 @@ public function testConstructorThrowsOnInvalidBaseDir(): void { // Use a path whose parent doesn't exist new Updater('/nonexistent/path/that/does/not/exist/updater'); } + + // ------------------------------------------------------------------------- + // Regression tests for issue #711 + // https://github.com/nextcloud/updater/issues/711 + // + // The bug: createBackup() used explode($nextcloudDir, $absolutePath)[1] + // to extract the relative path. When the install-directory name appears + // anywhere inside the file path (e.g. Nextcloud installed at /nextcloud + // with a file called nextcloud.html), explode() splits on EVERY occurrence + // of the delimiter, returning a directory instead of the full file path. + // PHP's copy() then fails with "cannot be a directory". + // + // The fix: ltrim(substr($absolutePath, strlen($nextcloudDir)), '/') + // ------------------------------------------------------------------------- + + /** + * Pure logic regression: shows exactly why explode() was wrong and that + * the substr() replacement is correct. + */ + public function testRelativePathExtractionForIssue711(): void { + // Simulate Nextcloud installed at /nextcloud (as in the bug report) + $installDir = '/nextcloud'; + // File deep inside core/doc with the same name as the install dir + $filePath = '/nextcloud/core/doc/admin/configuration_files/external_storage/nextcloud.html'; + + // Old (buggy) approach: explode splits on ALL occurrences of $installDir. + // '/nextcloud' appears at the start AND inside '.../external_storage/nextcloud.html' + // (because '/nextcloud.html' begins with '/nextcloud'). + $oldRelativePath = explode($installDir, $filePath)[1]; + $this->assertSame( + '/core/doc/admin/configuration_files/external_storage', + $oldRelativePath, + 'The old explode() approach incorrectly returns a directory path' + ); + $this->assertStringNotContainsString('nextcloud.html', $oldRelativePath); + + // New (fixed) approach: substr() always takes exactly the right suffix. + $newRelativePath = ltrim(substr($filePath, strlen($installDir)), '/'); + $this->assertSame( + 'core/doc/admin/configuration_files/external_storage/nextcloud.html', + $newRelativePath, + 'The substr() approach correctly returns the full relative file path' + ); + } + + /** + * Integration regression: createBackup() must copy a deeply nested file + * that has the install-directory name as part of its own name, without + * throwing and without producing a double-slash in the destination path. + * + * @see https://github.com/nextcloud/updater/issues/711 + */ + public function testCreateBackupCopiesNestedFilesCorrectly(): void { + // Reproduce the directory structure from the bug report: + // core/doc/admin/configuration_files/external_storage/nextcloud.html + $nestedDir = $this->tempDir . '/core/doc/admin/configuration_files/external_storage'; + mkdir($nestedDir, 0755, true); + file_put_contents($nestedDir . '/nextcloud.html', 'nextcloud docs'); + + $updater = $this->makeUpdater(); + // Must not throw + $updater->createBackup(); + + // Find the backup dir (contains a timestamp so we use glob) + $backupPattern = $this->dataDir . '/updater-testid/backups/nextcloud-30.0.0.1-*'; + $backupDirs = glob($backupPattern, GLOB_ONLYDIR); + $this->assertCount(1, $backupDirs, 'Expected exactly one backup directory'); + + // Backup folder ends with '/' by design; build the expected file path + $backedUpFile = rtrim($backupDirs[0], '/') . '/core/doc/admin/configuration_files/external_storage/nextcloud.html'; + + $this->assertFileExists($backedUpFile, 'Backed-up file must exist at the correct nested path'); + $this->assertStringNotContainsString('//', $backedUpFile, 'Backup path must not contain double slashes'); + $this->assertSame('nextcloud docs', file_get_contents($backedUpFile)); + } } From 275e3d282873555ee74ede367cd1fac24a1859cd Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:24:27 +0000 Subject: [PATCH 6/9] plan: fix reuse, php-cs, and same-code-check issues Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/cf8949f9-d766-48cd-b56c-ec8643d0cbc4 --- .../.github/workflows/phpstan.yml | 35 -------- .../.github/workflows/tests.yaml | 80 ------------------- .../composer-bin-plugin/.makefile/touch.sh | 61 -------------- .../composer-bin-plugin/.phive/phars.xml | 6 -- .../bamarni/composer-bin-plugin/composer.json | 12 +-- .../src/BamarniBinPlugin.php | 1 + .../src/Command/BinCommand.php | 3 + .../Command/CouldNotCreateNamespaceDir.php | 1 + .../composer-bin-plugin/src/Config/Config.php | 1 + .../src/Input/BinInputFactory.php | 8 +- .../src/Input/InvalidBinInput.php | 1 + vendor/composer/autoload_classmap.php | 1 - vendor/composer/autoload_static.php | 1 - vendor/composer/installed.json | 22 ++--- vendor/composer/installed.php | 18 ++--- 15 files changed, 38 insertions(+), 213 deletions(-) delete mode 100644 vendor/bamarni/composer-bin-plugin/.github/workflows/phpstan.yml delete mode 100644 vendor/bamarni/composer-bin-plugin/.github/workflows/tests.yaml delete mode 100755 vendor/bamarni/composer-bin-plugin/.makefile/touch.sh delete mode 100644 vendor/bamarni/composer-bin-plugin/.phive/phars.xml diff --git a/vendor/bamarni/composer-bin-plugin/.github/workflows/phpstan.yml b/vendor/bamarni/composer-bin-plugin/.github/workflows/phpstan.yml deleted file mode 100644 index ebb57672..00000000 --- a/vendor/bamarni/composer-bin-plugin/.github/workflows/phpstan.yml +++ /dev/null @@ -1,35 +0,0 @@ -name: "Static analysis" - -on: - push: - branches: - - "main" - - "master" - pull_request: null - -jobs: - static-analysis: - runs-on: "ubuntu-latest" - name: "PHPStan on PHP ${{ matrix.php }}" - strategy: - fail-fast: false - matrix: - php: - - "8.1" - steps: - - name: "Check out repository code" - uses: "actions/checkout@v2" - - - name: "Setup PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php }}" - tools: "composer" - - - name: "Install Composer dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - - - name: "Perform static analysis" - run: "make phpstan" diff --git a/vendor/bamarni/composer-bin-plugin/.github/workflows/tests.yaml b/vendor/bamarni/composer-bin-plugin/.github/workflows/tests.yaml deleted file mode 100644 index 5bec38a4..00000000 --- a/vendor/bamarni/composer-bin-plugin/.github/workflows/tests.yaml +++ /dev/null @@ -1,80 +0,0 @@ -name: "Tests" - -on: - push: - branches: - - "main" - - "master" - pull_request: null - -jobs: - unit-tests: - runs-on: "ubuntu-latest" - name: "Unit Tests on PHP ${{ matrix.php }} and ${{ matrix.tools }}" - strategy: - fail-fast: false - matrix: - php: - - "7.2" - - "7.3" - - "7.4" - - "8.0" - - "8.1" - tools: [ "composer" ] - dependency-versions: [ "highest" ] - include: - - php: "7.2" - tools: "composer:v2.0" - dependency-versions: "lowest" - - steps: - - name: "Check out repository code" - uses: "actions/checkout@v2" - - - name: "Setup PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php }}" - tools: "${{ matrix.tools }}" - - - name: "Install Composer dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "${{ matrix.dependency-versions }}" - - - name: "Validate composer.json" - run: "composer validate --strict --no-check-lock" - - - name: "Run tests" - run: "vendor/bin/phpunit --group default" - - e2e-tests: - runs-on: "ubuntu-latest" - name: "E2E Tests on PHP ${{ matrix.php }}" - strategy: - fail-fast: false - matrix: - php: - - "8.1" - - steps: - - name: "Check out repository code" - uses: "actions/checkout@v2" - - - name: "Setup PHP" - uses: "shivammathur/setup-php@v2" - with: - php-version: "${{ matrix.php }}" - tools: "composer" - - - name: "Correct bin plugin version for e2e scenarios (PR-only)" - if: github.event_name == 'pull_request' - run: find e2e -maxdepth 1 -mindepth 1 -type d -exec bash -c "cd {} && composer require --dev bamarni/composer-bin-plugin:dev-${GITHUB_SHA} --no-update" \; - - - name: "Install Composer dependencies" - uses: "ramsey/composer-install@v2" - with: - dependency-versions: "highest" - - - name: "Run tests" - run: "vendor/bin/phpunit --group e2e" diff --git a/vendor/bamarni/composer-bin-plugin/.makefile/touch.sh b/vendor/bamarni/composer-bin-plugin/.makefile/touch.sh deleted file mode 100755 index 5c0a7759..00000000 --- a/vendor/bamarni/composer-bin-plugin/.makefile/touch.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/env bash -# -# Takes a given string, e.g. 'bin/console' or 'docker-compose exec php bin/console' -# and split it by words. For each words, if the target is a file, it is touched. -# -# This allows to implement a similar rule to: -# -# ```Makefile -# bin/php-cs-fixer: vendor -# touch $@ -# ``` -# -# Indeed when the rule `bin/php-cs-fixer` is replaced with a docker-compose -# equivalent, it will not play out as nicely. -# -# Arguments: -# $1 - {string} Command potentially containing a file -# - -set -Eeuo pipefail; - - -readonly ERROR_COLOR="\e[41m"; -readonly NO_COLOR="\e[0m"; - - -if [ $# -ne 1 ]; then - printf "${ERROR_COLOR}Illegal number of parameters.${NO_COLOR}\n"; - - exit 1; -fi - - -readonly FILES="$1"; - - -####################################### -# Touch the given file path if the target is a file and do not create the file -# if does not exist. -# -# Globals: -# None -# -# Arguments: -# $1 - {string} File path -# -# Returns: -# None -####################################### -touch_file() { - local file="$1"; - - if [ -e ${file} ]; then - touch -c ${file}; - fi -} - -for file in ${FILES} -do - touch_file ${file}; -done diff --git a/vendor/bamarni/composer-bin-plugin/.phive/phars.xml b/vendor/bamarni/composer-bin-plugin/.phive/phars.xml deleted file mode 100644 index 335086e3..00000000 --- a/vendor/bamarni/composer-bin-plugin/.phive/phars.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/vendor/bamarni/composer-bin-plugin/composer.json b/vendor/bamarni/composer-bin-plugin/composer.json index 5b3809ba..4b76ff1b 100644 --- a/vendor/bamarni/composer-bin-plugin/composer.json +++ b/vendor/bamarni/composer-bin-plugin/composer.json @@ -17,11 +17,11 @@ }, "require-dev": { "ext-json": "*", - "composer/composer": "^2.0", + "composer/composer": "^2.2.26", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", + "phpstan/phpstan": "^1.8 || ^2.0", + "phpstan/phpstan-phpunit": "^1.1 || ^2.0", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.0", "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" @@ -38,9 +38,9 @@ }, "config": { "allow-plugins": { - "phpstan/extension-installer": true, "ergebnis/composer-normalize": true, - "infection/extension-installer": true + "infection/extension-installer": true, + "phpstan/extension-installer": true }, "sort-packages": true }, diff --git a/vendor/bamarni/composer-bin-plugin/src/BamarniBinPlugin.php b/vendor/bamarni/composer-bin-plugin/src/BamarniBinPlugin.php index 1d21c93b..19e36e0a 100644 --- a/vendor/bamarni/composer-bin-plugin/src/BamarniBinPlugin.php +++ b/vendor/bamarni/composer-bin-plugin/src/BamarniBinPlugin.php @@ -24,6 +24,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Throwable; + use function count; use function in_array; use function sprintf; diff --git a/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php b/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php index 9edb4c3e..69c4aa99 100644 --- a/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php +++ b/vendor/bamarni/composer-bin-plugin/src/Command/BinCommand.php @@ -19,6 +19,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Throwable; + use function chdir; use function count; use function file_exists; @@ -30,6 +31,7 @@ use function mkdir; use function putenv; use function sprintf; + use const GLOB_ONLYDIR; /** @@ -96,6 +98,7 @@ public function isProxyCommand(): bool public function execute(InputInterface $input, OutputInterface $output): int { // Switch to requireComposer() once Composer 2.3 is set as the minimum + // @phpstan-ignore function.alreadyNarrowedType $composer = method_exists($this, 'requireComposer') ? $this->requireComposer() : $this->getComposer(); diff --git a/vendor/bamarni/composer-bin-plugin/src/Command/CouldNotCreateNamespaceDir.php b/vendor/bamarni/composer-bin-plugin/src/Command/CouldNotCreateNamespaceDir.php index 33145078..8985a7cd 100644 --- a/vendor/bamarni/composer-bin-plugin/src/Command/CouldNotCreateNamespaceDir.php +++ b/vendor/bamarni/composer-bin-plugin/src/Command/CouldNotCreateNamespaceDir.php @@ -5,6 +5,7 @@ namespace Bamarni\Composer\Bin\Command; use RuntimeException; + use function sprintf; final class CouldNotCreateNamespaceDir extends RuntimeException diff --git a/vendor/bamarni/composer-bin-plugin/src/Config/Config.php b/vendor/bamarni/composer-bin-plugin/src/Config/Config.php index fa62b3a1..629ab868 100644 --- a/vendor/bamarni/composer-bin-plugin/src/Config/Config.php +++ b/vendor/bamarni/composer-bin-plugin/src/Config/Config.php @@ -5,6 +5,7 @@ namespace Bamarni\Composer\Bin\Config; use Composer\Composer; + use function array_key_exists; use function array_merge; use function function_exists; diff --git a/vendor/bamarni/composer-bin-plugin/src/Input/BinInputFactory.php b/vendor/bamarni/composer-bin-plugin/src/Input/BinInputFactory.php index dab96f68..105afae9 100644 --- a/vendor/bamarni/composer-bin-plugin/src/Input/BinInputFactory.php +++ b/vendor/bamarni/composer-bin-plugin/src/Input/BinInputFactory.php @@ -6,6 +6,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\StringInput; + use function array_filter; use function array_map; use function implode; @@ -61,7 +62,7 @@ public static function createInput( public static function createNamespaceInput(InputInterface $previousInput): InputInterface { $matchResult = preg_match( - '/^(.+?\s?)(--(?: .+)?)?$/', + '/^([^\s]+)(.*?\s?)(--(?: .+)?)?$/', $previousInput->__toString(), $matches ); @@ -74,9 +75,10 @@ public static function createNamespaceInput(InputInterface $previousInput): Inpu array_map( 'trim', [ - $matches[1], '--working-dir=.', - $matches[2] ?? '', + $matches[1], + $matches[2], + $matches[3] ?? '', ] ) ); diff --git a/vendor/bamarni/composer-bin-plugin/src/Input/InvalidBinInput.php b/vendor/bamarni/composer-bin-plugin/src/Input/InvalidBinInput.php index 2418d9c8..7f44ff5e 100644 --- a/vendor/bamarni/composer-bin-plugin/src/Input/InvalidBinInput.php +++ b/vendor/bamarni/composer-bin-plugin/src/Input/InvalidBinInput.php @@ -6,6 +6,7 @@ use RuntimeException; use Symfony\Component\Console\Input\InputInterface; + use function sprintf; final class InvalidBinInput extends RuntimeException diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php index 00778138..3ae12af1 100644 --- a/vendor/composer/autoload_classmap.php +++ b/vendor/composer/autoload_classmap.php @@ -25,7 +25,6 @@ 'NC\\Updater\\UpdateCommand' => $baseDir . '/lib/UpdateCommand.php', 'NC\\Updater\\UpdateException' => $baseDir . '/lib/UpdateException.php', 'NC\\Updater\\Updater' => $baseDir . '/lib/Updater.php', - 'NC\\Updater\\Version' => $baseDir . '/lib/Version.php', 'Normalizer' => $vendorDir . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 'Psr\\Container\\ContainerExceptionInterface' => $vendorDir . '/psr/container/src/ContainerExceptionInterface.php', 'Psr\\Container\\ContainerInterface' => $vendorDir . '/psr/container/src/ContainerInterface.php', diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php index 173bf8d5..fe175374 100644 --- a/vendor/composer/autoload_static.php +++ b/vendor/composer/autoload_static.php @@ -103,7 +103,6 @@ class ComposerStaticInitcbbead1010db4afef500f7adc2b6cac3 'NC\\Updater\\UpdateCommand' => __DIR__ . '/../..' . '/lib/UpdateCommand.php', 'NC\\Updater\\UpdateException' => __DIR__ . '/../..' . '/lib/UpdateException.php', 'NC\\Updater\\Updater' => __DIR__ . '/../..' . '/lib/Updater.php', - 'NC\\Updater\\Version' => __DIR__ . '/../..' . '/lib/Version.php', 'Normalizer' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/Resources/stubs/Normalizer.php', 'Psr\\Container\\ContainerExceptionInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerExceptionInterface.php', 'Psr\\Container\\ContainerInterface' => __DIR__ . '/..' . '/psr/container/src/ContainerInterface.php', diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index 55853f22..d44e57cc 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "bamarni/composer-bin-plugin", - "version": "1.8.2", - "version_normalized": "1.8.2.0", + "version": "1.9.1", + "version_normalized": "1.9.1.0", "source": { "type": "git", "url": "https://github.com/bamarni/composer-bin-plugin.git", - "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880" + "reference": "641d0663f5ac270b1aeec4337b7856f76204df47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", - "reference": "92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880", + "url": "https://api.github.com/repos/bamarni/composer-bin-plugin/zipball/641d0663f5ac270b1aeec4337b7856f76204df47", + "reference": "641d0663f5ac270b1aeec4337b7856f76204df47", "shasum": "" }, "require": { @@ -20,17 +20,17 @@ "php": "^7.2.5 || ^8.0" }, "require-dev": { - "composer/composer": "^2.0", + "composer/composer": "^2.2.26", "ext-json": "*", "phpstan/extension-installer": "^1.1", - "phpstan/phpstan": "^1.8", - "phpstan/phpstan-phpunit": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", + "phpstan/phpstan": "^1.8 || ^2.0", + "phpstan/phpstan-phpunit": "^1.1 || ^2.0", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.0", "symfony/console": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", "symfony/finder": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0", "symfony/process": "^2.8.52 || ^3.4.35 || ^4.4 || ^5.0 || ^6.0" }, - "time": "2022-10-31T08:38:03+00:00", + "time": "2026-02-04T10:18:12+00:00", "type": "composer-plugin", "extra": { "class": "Bamarni\\Composer\\Bin\\BamarniBinPlugin" @@ -56,7 +56,7 @@ ], "support": { "issues": "https://github.com/bamarni/composer-bin-plugin/issues", - "source": "https://github.com/bamarni/composer-bin-plugin/tree/1.8.2" + "source": "https://github.com/bamarni/composer-bin-plugin/tree/1.9.1" }, "install-path": "../bamarni/composer-bin-plugin" }, diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index a121f657..0e1e0fbc 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => '__root__', - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '0deb35c1f4fd23fea55c03db40f07c72603adc43', + 'pretty_version' => 'dev-copilot/add-string-concat-method', + 'version' => 'dev-copilot/add-string-concat-method', + 'reference' => 'dc688b2b097ffaa4f596e943d3626d5b65e6016a', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,18 +11,18 @@ ), 'versions' => array( '__root__' => array( - 'pretty_version' => 'dev-master', - 'version' => 'dev-master', - 'reference' => '0deb35c1f4fd23fea55c03db40f07c72603adc43', + 'pretty_version' => 'dev-copilot/add-string-concat-method', + 'version' => 'dev-copilot/add-string-concat-method', + 'reference' => 'dc688b2b097ffaa4f596e943d3626d5b65e6016a', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'bamarni/composer-bin-plugin' => array( - 'pretty_version' => '1.8.2', - 'version' => '1.8.2.0', - 'reference' => '92fd7b1e6e9cdae19b0d57369d8ad31a37b6a880', + 'pretty_version' => '1.9.1', + 'version' => '1.9.1.0', + 'reference' => '641d0663f5ac270b1aeec4337b7856f76204df47', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../bamarni/composer-bin-plugin', 'aliases' => array(), From 700e960070c5b8ae0a2ab238b73a32debd98991a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 25 Mar 2026 08:25:52 +0000 Subject: [PATCH 7/9] fix: REUSE compliance (vendor-bin/phpunit), php-cs concatenation style Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/cf8949f9-d766-48cd-b56c-ec8643d0cbc4 --- REUSE.toml | 2 +- tests/unit/UpdaterTest.php | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/REUSE.toml b/REUSE.toml index ccd18bd4..6a863295 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -24,7 +24,7 @@ SPDX-FileCopyrightText = "2020 Nextcloud GmbH and Nextcloud contributors" SPDX-License-Identifier = "MIT" [[annotations]] -path = ["vendor-bin/box/**", "vendor-bin/psalm/**", "vendor-bin/rector/**"] +path = ["vendor-bin/box/**", "vendor-bin/phpunit/**", "vendor-bin/psalm/**", "vendor-bin/rector/**"] precedence = "aggregate" SPDX-FileCopyrightText = "2023 Nextcloud GmbH and Nextcloud contributors" SPDX-License-Identifier = "AGPL-3.0-or-later" diff --git a/tests/unit/UpdaterTest.php b/tests/unit/UpdaterTest.php index ed80365b..9b9736fd 100644 --- a/tests/unit/UpdaterTest.php +++ b/tests/unit/UpdaterTest.php @@ -27,11 +27,11 @@ protected function setUp(): void { mkdir($this->configDir, 0755, true); // Write a minimal config.php with required keys - file_put_contents($this->configDir . '/config.php', ' "' . $this->dataDir . '",' . - '"version" => "30.0.0.1",' . - '"instanceid" => "testid",' . - '];'); + file_put_contents($this->configDir . '/config.php', ' "' . $this->dataDir . '",' + . '"version" => "30.0.0.1",' + . '"instanceid" => "testid",' + . '];'); putenv('NEXTCLOUD_CONFIG_DIR=' . $this->configDir); } From 851f344fad579276efb35eef23b70f76d7ce71e9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 07:11:07 +0000 Subject: [PATCH 8/9] merge: resolve conflicts with origin/master; keep opcache_invalidate + buildPath() Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/a9abb800-8545-4e95-a29f-29e8dbd26cdf Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> --- README.md | 75 +++++++++--- index.php | 109 +++++++++++++---- index.web.php | 10 +- lib/UpdateCommand.php | 18 ++- lib/Updater.php | 99 +++++++++++---- tests/features/bootstrap/FeatureContext.php | 51 +++++++- tests/features/cli.feature | 30 +++++ updater.phar | Bin 1322999 -> 1325351 bytes vendor-bin/tests/composer.lock | 128 ++++++++++---------- 9 files changed, 387 insertions(+), 133 deletions(-) diff --git a/README.md b/README.md index c518e93c..4c23de2e 100644 --- a/README.md +++ b/README.md @@ -192,29 +192,47 @@ Described here are both relevant aspects of the Updater itself as well as surrou ### Updater components -For each mode the Updater supports - Web and command line - a dedicated artifact is generated. However, all common operations are located in shared code. Since the code is not shared in all cases at runtime, it's important to understand where various changes should go during development so that they end up in the appropriate places at build or check-in time. +For each mode the Updater supports - Web and command line - a dedicated artifact is generated. However, all common operations are located +in shared code. Since the code is not shared in all cases at runtime, it's important to understand where various changes should go during +development so that they end up in the appropriate places at build or check-in time. Changes should be made to the following places in the `updater` repo: * Shared aspects of the Updater: - - `/Makefile` - - `make updater.phar` - - `make index.php` - `/lib/LogException.php` - - `/lib/RecursiveDirectoryIteratorWithoutDate.php` - `/lib/UpdateException.php` - `/lib/Updater.php` <-- core of the Updater functionality for both Web and CLI modes is implemented here * Aspects specific to the Web Updater: - `/index.web.php` - - `/Makefile` - - `make index.php` * Aspects specific to the CLI Updater: - `/updater.php` - `/buildVersionFile.php` - `/lib/CommandApplication.php` - `/lib/UpdateCommand.php` - - `/Makefile` - - `make updater.phar` + +#### Build system (`/Makefile`) + +The Makefile contains targets for both modes. The relevant targets are: + +* `make updater.phar` — builds the CLI Updater artifact +* `make index.php` — builds the Web Updater artifact +* `make check-same-code-base` — verifies that `index.php` contains the same shared library code as the individual files in `/lib/` <-- checked by CI + +**How `index.php` is built:** The Web Updater runs as a single self-contained PHP file. `make index.php` produces it by *concatenating* `index.web.php` +with the shared library files (`UpdateException.php`, `LogException.php`, `Updater.php`), stripping `namespace`/`use` statements and duplicate PHP +opening tags via `awk`/`grep`. This means that after changing any shared `/lib/*.php` file or `index.web.php`, you must re-run `make index.php` and +check in the resulting `/index.php`. + +**How `updater.phar` is built:** `make updater.phar` generates a transient `/lib/Version.php` (via `buildVersionFile.php`), runs `composer dump-autoload`, +then uses [box](https://github.com/box-project/box) (configured in `/box.json`) to package `/updater.php`, `/lib/*.php`, and `/vendor/*.php` into the +phar. The transient `Version.php` is deleted after the build. After changing any CLI-specific or shared file, you must re-run `make updater.phar` and +check in the resulting `/updater.phar`. + +#### Build configuration files + +* `/box.json` — Configures which files are packaged into `updater.phar` (the `lib/` directory, vendor PHP files, with `updater.php` as the main entry point) +* `/composer.json` / `/composer.lock` — Manage PHP dependencies; the CLI Updater bootstraps via `vendor/autoload.php` +* `/vendor/` — Checked in to the repo (used at runtime by the CLI Updater and during the phar build) #### Server components @@ -239,15 +257,35 @@ Keep in mind that for the update/upgrade process there are some additional compo - Handles database upgrade migrations - Handles app updates (i.e. for compatibility with a new major version of Server) -### Dependences needed for building +### Dependencies needed for building #### box Install box: https://github.com/box-project/box/blob/main/doc/installation.md#composer +#### Composer + +A working `composer` install is required both for dependency management and for building. See "Testing" below for version requirements. + #### Tests -If you want to run the tests locally, you'll need to run them in an environment that has Nextcloud's required PHP modules installed. The various test scenarios are all available via the `make test*` (see Makefile for specifics). +If you want to run the tests locally, you'll need to run them in an environment that has Nextcloud's required PHP modules installed. +Tests use [Behat](https://docs.behat.org/) (a BDD framework); feature files live under `tests/features/`. Test data (gitignored) is +generated under `tests/data/`. + +The available test targets are: + +| Target | Description | +|---|---| +| `make test` | Runs all Behat feature tests | +| `make test-cli` | Runs only the CLI updater tests (`features/cli.feature`) | +| `make test-stable26` | Tests update path for stable26 | +| `make test-stable27` | Tests update path for stable27 | +| `make test-stable28` | Tests update path for stable28 | +| `make test-master` | Tests update path for master | +| `make test-user.ini` | Tests `.user.ini` handling (`features/user.ini.feature`) | +| `make check-same-code-base` | Verifies `/index.php` is in sync with `/lib/*.php` + `/index.web.php` | +| `make build-and-local-test` | Builds the phar then runs a local updater smoke test | ### Build artifacts / What to check in @@ -269,16 +307,23 @@ Plus whatever has been changed in the implementation in: #### Transient -Used during the build process but not checked in: +Used during the build process but not checked in (gitignored): * Specific to the CLI Updater: - - `/lib/Version.php` + - `/lib/Version.php` — auto-generated by `buildVersionFile.php`, deleted after `make updater.phar` completes ### Testing -#### Check same code base test keeps failing +#### `check-same-code-base` test keeps failing + +This test (`make check-same-code-base`) runs `tests/checkSameCodeBase.php`, which verifies that the contents of each shared library file in `/lib/` +(excluding CLI-only files `CommandApplication.php` and `UpdateCommand.php`) are present verbatim inside the built `/index.php`. If it fails, it +usually means: -If it keeps failing on your PR, confirm your local version of `composer` is the same version in-use in the workflow runner. You can check the details of the test run and find the version currently being used (and therefore required locally) under "Setup Tools". (Hint: distro versions are typically too outdated. Remove that version and see https://getcomposer.org/download/ to install your own version). +1. **You changed a file in `/lib/` but didn't rebuild `index.php`.** Run `make index.php` and commit the result. +2. **Your local `composer` version differs from CI.** Confirm your local version of `composer` is the same version in-use in the workflow runner. + You can check the details of the test run and find the version currently being used (and therefore required locally) under "Setup Tools". (Hint: + distro versions are typically too outdated. Remove that version and see https://getcomposer.org/download/ to install your own version). #### CI diff --git a/index.php b/index.php index fe86f322..44259871 100644 --- a/index.php +++ b/index.php @@ -82,6 +82,11 @@ public function __construct( } $versionFileName = $this->buildPath('version.php'); + // Invalidate version.php OPcache entry to assure file_exists() returns + // false after files were removed while opcache.enable_file_override is set. + if (function_exists('opcache_invalidate')) { + opcache_invalidate($versionFileName, true); + } if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -585,28 +590,64 @@ private function getUpdateServerResponse(): array { $updateURL = $updaterServer . '?version=' . str_replace('.', 'x', $this->getConfigOptionMandatoryString('version')) . 'xxx' . $releaseChannel . 'xx' . urlencode($this->buildTime) . 'x' . PHP_MAJOR_VERSION . 'x' . PHP_MINOR_VERSION . 'x' . PHP_RELEASE_VERSION; $this->silentLog('[info] updateURL: ' . $updateURL); + $maxRetries = 2; + + for ($attempt = 1; $attempt <= $maxRetries; $attempt++) { + try { + return $this->fetchUpdateServerResponse($updateURL); + } catch (\Exception $e) { + $lastException = $e; + $this->silentLog('[warn] attempt ' . $attempt . '/' . $maxRetries . ' failed: ' . $e->getMessage()); + if ($attempt < $maxRetries) { + sleep(1); + } + } + } + + throw $lastException; + } + + /** + * @throws \Exception + */ + private function fetchUpdateServerResponse(string $updateURL): array { // Download update response $curl = $this->getCurl($updateURL); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($curl, CURLOPT_TIMEOUT, 30); /** @var false|string $response */ $response = curl_exec($curl); + if ($response === false) { - throw new \Exception('Could not do request to updater server: ' . curl_error($curl)); + $curlError = curl_error($curl); + curl_close($curl); + throw new \Exception('Could not do request to updater server: ' . $curlError); } + $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); + if ($httpCode !== 200 && $httpCode !== 204) { + $this->silentLog('[warn] update server returned HTTP ' . $httpCode); + throw new \Exception('Update server returned unexpected HTTP status ' . $httpCode); + } + // Response can be empty when no update is available if ($response === '') { return []; } libxml_use_internal_errors(true); - $xml = simplexml_load_string($response); - if ($xml === false) { - $content = strlen($response) > 200 ? substr($response, 0, 200) . '…' : $response; - $errors = implode("\n", array_map(fn ($error) => $error->message, libxml_get_errors())); - throw new \Exception('Could not parse updater server XML response: ' . $content . "\nErrors:\n" . $errors); + try { + $xml = simplexml_load_string($response); + if ($xml === false) { + $content = strlen($response) > 200 ? substr($response, 0, 200) . '…' : $response; + $errors = implode("\n", array_map(fn ($error) => $error->message, libxml_get_errors())); + throw new \Exception('Could not parse updater server XML response: ' . $content . "\nErrors:\n" . $errors); + } + } finally { + libxml_clear_errors(); } $response = get_object_vars($xml); @@ -626,11 +667,11 @@ private function getUpdateServerResponse(): array { * * @throws \Exception */ - public function downloadUpdate(string $url = '', ?Closure $downloadProgress = null): void { + public function downloadUpdate(string $urlOverride = '', ?Closure $downloadProgress = null): void { $this->silentLog('[info] downloadUpdate()'); $this->downloadProgress = $downloadProgress; - $downloadURLs = $url !== '' ? [$url] : $this->getDownloadURLs(); + $downloadURLs = $urlOverride !== '' ? [$urlOverride] : $this->getDownloadURLs(); $this->silentLog('[info] will try to download archive from: ' . implode(', ', $downloadURLs)); @@ -652,10 +693,10 @@ public function downloadUpdate(string $url = '', ?Closure $downloadProgress = nu } } - foreach ($downloadURLs as $url) { + foreach ($downloadURLs as $urlOverride) { $this->previousProgress = 0; - $saveLocation = $storageLocation . basename((string)$url); - if ($this->downloadArchive($url, $saveLocation)) { + $saveLocation = $storageLocation . basename((string)$urlOverride); + if ($this->downloadArchive($urlOverride, $saveLocation)) { return; } } @@ -841,7 +882,7 @@ private function getDownloadedFilePath(): string { * * @throws \Exception */ - public function verifyIntegrity(string $urlOverride = ''): void { + public function verifyIntegrity(string $urlOverride = '', string $signature = ''): void { $this->silentLog('[info] verifyIntegrity()'); if ($this->getCurrentReleaseChannel() === 'daily') { @@ -849,18 +890,13 @@ public function verifyIntegrity(string $urlOverride = ''): void { return; } - if ($urlOverride !== '') { - $this->silentLog('[info] custom download url provided, cannot verify signature'); - return; - } - - $response = $this->getUpdateServerResponse(); - if (empty($response['signature'])) { - throw new \Exception('No signature specified for defined update'); - } - - if (!is_string($response['signature'])) { - throw new \Exception('Signature specified for defined update should be a string'); + if ($signature === '') { + if ($urlOverride !== '') { + throw new \Exception( + 'Custom download url provided. You need to provide a signature with --signature or skip integrity check with --no-verify.' + ); + } + $signature = $this->getSignatureFromUpdater(); } $certificate = <<getDownloadedFilePath()), - base64_decode($response['signature']), + base64_decode($signature), $certificate, OPENSSL_ALGO_SHA512 ) === 1; @@ -907,6 +943,19 @@ public function verifyIntegrity(string $urlOverride = ''): void { $this->silentLog('[info] end of verifyIntegrity()'); } + private function getSignatureFromUpdater(): string { + $response = $this->getUpdateServerResponse(); + if (empty($response['signature'])) { + throw new \Exception('No signature specified for defined update'); + } + + if (!is_string($response['signature'])) { + throw new \Exception('Signature specified for defined update should be a string'); + } + + return $response['signature']; + } + /** * Gets the version as declared in $versionFile * @@ -1998,7 +2047,15 @@ public function isAuthenticated(): bool {

To login you need to provide the unhashed value of "updater.secret" in your config file.

If you don't know that value, you can access this updater directly via the Nextcloud admin screen or generate your own secret:

- php -r '$password = trim(shell_exec("openssl rand -base64 48"));if(strlen($password) === 64) {$hash = password_hash($password, PASSWORD_DEFAULT) . "\n"; echo "Insert as \"updater.secret\": ".$hash; echo "The plaintext value is: ".$password."\n";}else{echo "Could not execute OpenSSL.\n";};' + php -r '$password = trim(shell_exec("openssl rand -base64 48")); + if (strlen($password) === 64) { + $hash = password_hash($password, PASSWORD_DEFAULT); + echo "Insert this line in your config.php:\n\n"; + echo "'\''updater.secret'\'' => '\''" . $hash . "'\'',\n\n"; + echo "The plaintext value is: " . $password . "\n"; + } else { + echo "Could not execute OpenSSL.\n"; + }'
To login you need to provide the unhashed value of "updater.secret" in your config file.

If you don't know that value, you can access this updater directly via the Nextcloud admin screen or generate your own secret:

- php -r '$password = trim(shell_exec("openssl rand -base64 48"));if(strlen($password) === 64) {$hash = password_hash($password, PASSWORD_DEFAULT) . "\n"; echo "Insert as \"updater.secret\": ".$hash; echo "The plaintext value is: ".$password."\n";}else{echo "Could not execute OpenSSL.\n";};' + php -r '$password = trim(shell_exec("openssl rand -base64 48")); + if (strlen($password) === 64) { + $hash = password_hash($password, PASSWORD_DEFAULT); + echo "Insert this line in your config.php:\n\n"; + echo "'\''updater.secret'\'' => '\''" . $hash . "'\'',\n\n"; + echo "The plaintext value is: " . $password . "\n"; + } else { + echo "Could not execute OpenSSL.\n"; + }'
addOption('no-upgrade', null, InputOption::VALUE_NONE, "Don't automatically run occ upgrade") ->addOption('url', null, InputOption::VALUE_OPTIONAL, 'The URL of the Nextcloud release to download') ->addOption('ignore-state', null, InputOption::VALUE_NONE, 'Ignore known state from .step file, do a complete update') + ->addOption('no-verify', null, InputOption::VALUE_NONE, 'Skip integrity verification of the downloaded file') + ->addOption('signature', null, InputOption::VALUE_OPTIONAL, 'Base64 signature of the archive (use it in combination with --url option)') ; } @@ -73,7 +78,9 @@ public static function getUpdaterVersion(): string { protected function execute(InputInterface $input, OutputInterface $output): int { $this->skipBackup = (bool)$input->getOption('no-backup'); $this->skipUpgrade = (bool)$input->getOption('no-upgrade'); + $this->skipIntegrityCheck = (bool)$input->getOption('no-verify'); $this->urlOverride = (string)$input->getOption('url'); + $this->signature = (string)$input->getOption('signature'); $this->ignoreState = (bool)$input->getOption('ignore-state'); $version = static::getUpdaterVersion(); @@ -166,6 +173,11 @@ protected function execute(InputInterface $input, OutputInterface $output): int $updateString = $this->updater->checkForUpdate(); } + if ($this->skipIntegrityCheck) { + $this->updater->log('[warn] Integrity check of the downloaded file will be skipped'); + $output->writeln('Integrity check of the downloaded file will be skipped.'); + } + $output->writeln(''); $lines = explode('
', $updateString); @@ -450,7 +462,11 @@ protected function executeStep(int $step, OutputInterface $output): array { }); break; case 5: - $this->updater->verifyIntegrity($this->urlOverride); + if ($this->skipIntegrityCheck) { + $this->updater->silentLog('[info] Skipping integrity check as requested'); + break; + } + $this->updater->verifyIntegrity($this->urlOverride, $this->signature); break; case 6: $this->updater->extractDownload(); diff --git a/lib/Updater.php b/lib/Updater.php index edbe65a3..cc03054a 100644 --- a/lib/Updater.php +++ b/lib/Updater.php @@ -66,6 +66,11 @@ public function __construct( } $versionFileName = $this->buildPath('version.php'); + // Invalidate version.php OPcache entry to assure file_exists() returns + // false after files were removed while opcache.enable_file_override is set. + if (function_exists('opcache_invalidate')) { + opcache_invalidate($versionFileName, true); + } if (!file_exists($versionFileName)) { // fallback to version in config.php $version = $this->getConfigOptionString('version'); @@ -569,28 +574,64 @@ private function getUpdateServerResponse(): array { $updateURL = $updaterServer . '?version=' . str_replace('.', 'x', $this->getConfigOptionMandatoryString('version')) . 'xxx' . $releaseChannel . 'xx' . urlencode($this->buildTime) . 'x' . PHP_MAJOR_VERSION . 'x' . PHP_MINOR_VERSION . 'x' . PHP_RELEASE_VERSION; $this->silentLog('[info] updateURL: ' . $updateURL); + $maxRetries = 2; + + for ($attempt = 1; $attempt <= $maxRetries; $attempt++) { + try { + return $this->fetchUpdateServerResponse($updateURL); + } catch (\Exception $e) { + $lastException = $e; + $this->silentLog('[warn] attempt ' . $attempt . '/' . $maxRetries . ' failed: ' . $e->getMessage()); + if ($attempt < $maxRetries) { + sleep(1); + } + } + } + + throw $lastException; + } + + /** + * @throws \Exception + */ + private function fetchUpdateServerResponse(string $updateURL): array { // Download update response $curl = $this->getCurl($updateURL); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($curl, CURLOPT_TIMEOUT, 30); /** @var false|string $response */ $response = curl_exec($curl); + if ($response === false) { - throw new \Exception('Could not do request to updater server: ' . curl_error($curl)); + $curlError = curl_error($curl); + curl_close($curl); + throw new \Exception('Could not do request to updater server: ' . $curlError); } + $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); + if ($httpCode !== 200 && $httpCode !== 204) { + $this->silentLog('[warn] update server returned HTTP ' . $httpCode); + throw new \Exception('Update server returned unexpected HTTP status ' . $httpCode); + } + // Response can be empty when no update is available if ($response === '') { return []; } libxml_use_internal_errors(true); - $xml = simplexml_load_string($response); - if ($xml === false) { - $content = strlen($response) > 200 ? substr($response, 0, 200) . '…' : $response; - $errors = implode("\n", array_map(fn ($error) => $error->message, libxml_get_errors())); - throw new \Exception('Could not parse updater server XML response: ' . $content . "\nErrors:\n" . $errors); + try { + $xml = simplexml_load_string($response); + if ($xml === false) { + $content = strlen($response) > 200 ? substr($response, 0, 200) . '…' : $response; + $errors = implode("\n", array_map(fn ($error) => $error->message, libxml_get_errors())); + throw new \Exception('Could not parse updater server XML response: ' . $content . "\nErrors:\n" . $errors); + } + } finally { + libxml_clear_errors(); } $response = get_object_vars($xml); @@ -610,11 +651,11 @@ private function getUpdateServerResponse(): array { * * @throws \Exception */ - public function downloadUpdate(string $url = '', ?Closure $downloadProgress = null): void { + public function downloadUpdate(string $urlOverride = '', ?Closure $downloadProgress = null): void { $this->silentLog('[info] downloadUpdate()'); $this->downloadProgress = $downloadProgress; - $downloadURLs = $url !== '' ? [$url] : $this->getDownloadURLs(); + $downloadURLs = $urlOverride !== '' ? [$urlOverride] : $this->getDownloadURLs(); $this->silentLog('[info] will try to download archive from: ' . implode(', ', $downloadURLs)); @@ -636,10 +677,10 @@ public function downloadUpdate(string $url = '', ?Closure $downloadProgress = nu } } - foreach ($downloadURLs as $url) { + foreach ($downloadURLs as $urlOverride) { $this->previousProgress = 0; - $saveLocation = $storageLocation . basename((string)$url); - if ($this->downloadArchive($url, $saveLocation)) { + $saveLocation = $storageLocation . basename((string)$urlOverride); + if ($this->downloadArchive($urlOverride, $saveLocation)) { return; } } @@ -825,7 +866,7 @@ private function getDownloadedFilePath(): string { * * @throws \Exception */ - public function verifyIntegrity(string $urlOverride = ''): void { + public function verifyIntegrity(string $urlOverride = '', string $signature = ''): void { $this->silentLog('[info] verifyIntegrity()'); if ($this->getCurrentReleaseChannel() === 'daily') { @@ -833,18 +874,13 @@ public function verifyIntegrity(string $urlOverride = ''): void { return; } - if ($urlOverride !== '') { - $this->silentLog('[info] custom download url provided, cannot verify signature'); - return; - } - - $response = $this->getUpdateServerResponse(); - if (empty($response['signature'])) { - throw new \Exception('No signature specified for defined update'); - } - - if (!is_string($response['signature'])) { - throw new \Exception('Signature specified for defined update should be a string'); + if ($signature === '') { + if ($urlOverride !== '') { + throw new \Exception( + 'Custom download url provided. You need to provide a signature with --signature or skip integrity check with --no-verify.' + ); + } + $signature = $this->getSignatureFromUpdater(); } $certificate = <<getDownloadedFilePath()), - base64_decode($response['signature']), + base64_decode($signature), $certificate, OPENSSL_ALGO_SHA512 ) === 1; @@ -891,6 +927,19 @@ public function verifyIntegrity(string $urlOverride = ''): void { $this->silentLog('[info] end of verifyIntegrity()'); } + private function getSignatureFromUpdater(): string { + $response = $this->getUpdateServerResponse(); + if (empty($response['signature'])) { + throw new \Exception('No signature specified for defined update'); + } + + if (!is_string($response['signature'])) { + throw new \Exception('Signature specified for defined update should be a string'); + } + + return $response['signature']; + } + /** * Gets the version as declared in $versionFile * diff --git a/tests/features/bootstrap/FeatureContext.php b/tests/features/bootstrap/FeatureContext.php index 34d036de..f8560815 100644 --- a/tests/features/bootstrap/FeatureContext.php +++ b/tests/features/bootstrap/FeatureContext.php @@ -204,7 +204,7 @@ public function theCliUpdaterIsRun() { copy($this->buildDir . 'updater.phar', $this->serverDir . 'nextcloud/updater/updater'); chdir($this->serverDir . 'nextcloud/updater'); chmod($this->serverDir . 'nextcloud/updater/updater', 0755); - exec('./updater -n', $output, $returnCode); + exec('./updater -n 2>&1', $output, $returnCode); // sleep to let the opcache do it's work and invalidate the status.php sleep(5); @@ -564,4 +564,53 @@ public function thereIsAConfigForASecondaryAppsDirectoryCalled($name) { public function phpIsAtLeastInVersion($version) { $this->skipIt = in_array(version_compare($version, PHP_VERSION, '<'), [0, false], true); } + + /** + * @Given the update server returns HTTP status :statusCode + */ + public function theUpdateServerReturnsHttpStatus(int $statusCode) { + if ($this->skipIt) { + return; + } + + $this->runUpdateServer(); + + $content = 'updateServerDir . 'index.php', $content); + } + + /** + * @Given the update server returns invalid XML + */ + public function theUpdateServerReturnsInvalidXml() { + if ($this->skipIt) { + return; + } + + $this->runUpdateServer(); + + $content = '<><";'; + file_put_contents($this->updateServerDir . 'index.php', $content); + } + + /** + * @Given the update server is unreachable + */ + public function theUpdateServerIsUnreachable() { + if ($this->skipIt) { + return; + } + + // Point updater.server.url at a port with nothing listening + $configFile = $this->serverDir . 'nextcloud/config/config.php'; + $content = file_get_contents($configFile); + $content = preg_replace( + '!\$CONFIG\s*=\s*array\s*\(!', + "\$CONFIG = array(\n 'updater.server.url' => 'http://localhost:8871/',", + $content + ); + file_put_contents($configFile, $content); + + // Intentionally do NOT start any server on port 8871 + } } diff --git a/tests/features/cli.feature b/tests/features/cli.feature index 9555710c..9cd1db17 100644 --- a/tests/features/cli.feature +++ b/tests/features/cli.feature @@ -84,3 +84,33 @@ Feature: CLI updater And the installed version should be 26.0.0 And maintenance mode should be off And upgrade is not required + + Scenario: Update server returns HTTP 500 - 26.0.0 + Given the current installed version is 26.0.0 + And the update server returns HTTP status 500 + When the CLI updater is run + Then the return code should not be 0 + And the output should contain "Update server returned unexpected HTTP status 500" + And the installed version should be 26.0.0 + And maintenance mode should be off + And upgrade is not required + + Scenario: Update server returns invalid XML - 26.0.0 + Given the current installed version is 26.0.0 + And the update server returns invalid XML + When the CLI updater is run + Then the return code should not be 0 + And the output should contain "Could not parse updater server XML response" + And the installed version should be 26.0.0 + And maintenance mode should be off + And upgrade is not required + + Scenario: Update server is unreachable - 26.0.0 + Given the current installed version is 26.0.0 + And the update server is unreachable + When the CLI updater is run + Then the return code should not be 0 + And the output should contain "Could not do request to updater server" + And the installed version should be 26.0.0 + And maintenance mode should be off + And upgrade is not required diff --git a/updater.phar b/updater.phar index 52060e44b526cfce6deaa83e9b2bea2e43455314..3d00cc6925fbc6b37309e6416afd31be67b8346b 100755 GIT binary patch delta 5331 zcmbVOd2~}{7JuoMysmla-gJ3sQU7(5BF`9;j*iN@CL_B2CHWp2<%v3EO7xKSIT_jGq4Sqi_sQtPBi{bR2YiZv{>i5h=uMw;p!xDTpzGuf zK;M_o1IjDVpG~nC`HDKQ|70=4)CV@#(%=(F1se^I9c(So{VWE5i$&#od>cT?&yQig z`PBP8qTv!qfM2LzkJ)MZh{7Pja>=(5l+*m?0v-0N1*M1>hI#0RSFezl*aXqAnq$Rt ztGEcchQcbTMfx{^*s>6Y3C}pbgsj&li1tBFE^gCv;quvTu|xj#Aogt#!|b}v50JIt zAQm8w=(qrR9F0t}))G(&V(%*%W_WRMCiyqE>NDJK(Vs{hN82?S8_q}ehs=i zsYLS;Tq8)nn9eYx!8_u}_k02w;WWT(r#KF`Uq3*O`6rNzoEm)m!eMzUR5ftlsHz5f zQq>GJHW)!Zlf^LEd%ic3V>z^46yiD+Cnpz!y~&|M5CeGs z$e&?k&FoK7X+?Vk7peTN34%9E)U#K+mu#IqWm>#$;uNCYOp%|b#vE6MVgnuyMd(Bo z!`#Z-DN4{`I0a#$;L;G*1awarwt5q7b?^4F3$&!k;@S|-N4y=v1t=RSoV287iB`P( za1hDJoc2$}eC5tybUhG$59II$t?rj^)iuwMRES%GId(^c7kHFMV6Qd%GE9xGt%_87 zLu_$mG{Or^Ftp&=8$H$o43i*=qZS%ZF!s4wqO&$X7eF+HQaoft?JJ(@;u4kbxdkM8 zE8(qia!j2dj&yRdqLSmh{nG6wyP7(d+VsW9r4Ud+6t>P4ivIJv-?)m?u8_1M#dSM9 zS@Kep0wiCH!m098FMvRodNa(<;R2&HRWyV|5IUq@2#>84vclH+<&rsaF zc?{&T`(B_~3}(b6hKaO)`~&2CRD(HR)}T^BJTAPg@!05}$G1bUSqaO4Zco6?u!c6t zn((}*iA+C>7_wiazd%8~k@DejsqSRdhZXOg%lYm| zl#`>0IKW3KUfJ8Pw2<_~Tya}7-En8Ig-PWsT=q}QLd0*nsX>Q{?$zP@gbw$^7j)@m zT^YGVF6mRqkUkjV+NQ4udPa|%@EXf7q&m%+D1;P%-7>x(L)0aD=&}1*x^~dU(G480ti~|R5^den z)itS0MziA~gm<#BlVfsl+-y0xX%FS#D!-jm267d-i05mO3^Sy1{*Hc0)#Q3%pm<~_ zryzlOz5xZ9(h{2I{#JgRi$O1@jnvqXwFO|Cloyp{6rw$J;-m>(nde^ad05JTe4LTx z`76Qohxr1~qJlo4&lU6njVSB@y1EcUKT(Ju2MNs$zl~|2YgSE87pcQAvREAgB~fFz2a2%LLG;6V;@YWhQmK*jRV1}I0SfS855rtm8E(=c)sm4SmOiM+ z6UE{1SQx=DWe==wnxUm4KNoXgT3Lc!Z7sp3dbuPM_+OXc4>xToqAZja1AkvB{t&z9 zrZHv6Us_fG?~j+^2ln$a)Qc+51OEJSoPyDE{E~lDj?iXQ;8YA&ECjg^Dlndm$|Z2$ zQi=DgmAL21t8ni<>ZTW}aB7pPF;+&oi3+7iFXLD zeuvfR%d*r`kI~{3cw>)CaDbST9~7vDL+G;&2;KakiK_B8JJ?MZtj11DxX=Oi=)1#V z?iP5nlXnWPbh7QQe3f}BFkMm-e?RrXx|KVopY&RH&~?;!v$0P|3n;N(mB*~Px}xyR<<^;)CLCG^={l$%w|Pu)sN`57wH4=E|` zNF-1oBo-mywJwv{nO4>#xVlX3b_ve;f`i63PjK38Dyvh_Yx{xSK5vc`9Xa{0h-kMl zR%&r?F^-Vv^YzQ8;LHSeNmWG3xmA=@8R-T?Q~_q(*tP3KWTMakN(z zwiIAsS#!^fL`!C7HW>ixvXzo_+UmBp z#<{gE?QN-iRwl&uKQyL9volHQ#zykcMvVrH);b)t)TKP=(nhm6&>56Lwkedf9#0_e zZjASxmL{fMiJmkbvTau+@!S+f_U}rP<&f*gqh@1Cu$Hu0r5d}(fcAJpTbqH_fR@SR za@nhG-BKqK&Ky~ZJ@G4reycEK7rI=Nx=xqT)$jb338|SwH*Jx-+m7trlt$j)6h*$; zw1^ZxvW&E!(~v`tH0!Zwbo#7Di^bic7IWuNpQWSAA{ZSVkiJttF58^rL6+_hAVpiA ziffr1KTT;Vuha46{8BAVev&=@-Ind1ipd*!V5DREa&{zf>hkh-Q&>bQKUsFCd4-iG zLpOkAlJ!C^RlsmRNU}UNzpb=23sw~N?LDZs#%(?3;W`~@f=@uW7La$bd&SJ zRK(HCiiGC*cV-Pw<}M@b6I&1OqN}{yHfXijjNKGYY3u5eBnZ;VjNRQWuy^#jse~k( z(f86hY;0++oRiAys*Fw{FJ}hwZkt9&m&rUJ@cMqb`pqtiJKtsN>!ke$p53t1W}=H< z;v|7ry8oojB4)L+QR78Fu9e*lhJQ~)vs3jV2PW!*r^2Hh<=!r&bs}WC4&z@>+~*$) z>kilPuhC5sFDYcvr8vb?z`MKT?m*Gzu~_&{0XoYrbn8SeUKWx6|0$=7oR3U<(Bv)i zNEG#YSy1ql9jHExgSb9L7D|G*s!F7?+NCXOp6n5Ks75ECKfT=dX=D-m?6w(@CG6Km4HYqc1$UeCz3jV?V5M>f>+s9xZ)y|DMoS PGPly-PfUH)+^YWo;2dk$ delta 3626 zcmY*beN>cX7JmkqdFP#Bn0aU9bNHBH2Ki=&?*RmcZ;;YKMN1taU z82G4fmKmFEMN!Bdwa7VMr;WCMPn$O62j$Op{iN&(k$ z<$z<{JV28Y7j*za!20Oi}^>`bz34WYKiDs8I$a9SCj1^sL1TDAHjN#7c(0!0l z0hard2FtY6R<0iMy%0Sq@F z$rqCeN!@v~nVv{v<)Rdai~>im8sv1R!50h%4S2KL26W_{;ROBq87_$axi2BIIs9$u zX~llC5Ul&Y5|VF`(0jS{P1=+4t83BZ7L;PYn=wDnh^3AvN8U6iQ9 zbQ}Tx5YiP;3Ai%=OTChny1Y7XoIPorxIau#h_-M+qpM(avL|hk(E0J7wbW++Ej}|- zah(PXy((}v++mcx?!Qi!&UwI6DIN_K_{~8+5RnVQTAQOHq&Rv(AuW(YZV|LU$Ol{y z_TZ^6c&!5(ej!mjx02;!z&dY{aOTE68fwmx@}a#(m3XgJh|+!PF_7?%<>W9uVYGenJ9;%#FAfPpD0jvOgD(%o+Bq8f z2%HKGn-91m47>ek*aGk(XZNr*ZfZp@VZqcD9t?)9;W*=tg<}^95p&_d6&4`txvX!b zN?~Dn+8Yr88#`FCb&GCYrB2SWO)F@`{>KEKb1|(%#+?YPhYAy3ak~lgxb9gy%!|Q` z7)wZS#}_}rm5-b8%Gb?!$PtP2t|t=f{8D5!f_5Si!VlCeHfTW+LIYJm`wXi@q6+`_s`l9=>KXFL|Q(8od@1Pglnn zAg@g^Wq=oBa1c)Ngbat)x`B<37^RprpEYfvKXBS2VQqWK7OD%f(5YCpxPP9Y(`8z5 zS3<=^#D8h8UfK-=$ErAdhDYKs&|7gx$n7}HdO7~Z zec6W7bfz5xJz+;i*0M?T?&$7xc4u@nZZ|=M)9htNxc*vJen#4!EQl`;u)(#!^E#Eu z)nJvM%gEWiFQj>hgtfPUnXeydmWwu&N9s zq|Ld1*RNJn-9osoxfEHK@bH$Wc{X*>$5fAC(iLGEEfQAkY-sr9EbUK?gcMGtVkL*A zVYjuX;h;U7hLik$S{~Rr(~-{)g9%x!?|g%ONR4zV%TN5@TY{4MWvDa`yEKF5c|Mh2 zq+`;HSs_)FCwBvFzu1e;GDgu()^SpYKAGW}?HTx#noR7G+RP^*^!dz2z--3~z&(!T zfI(SxfNQca_0w7SZIIa9ur;ilO<5y7mu(Ed%)+CQC<*yzuc+X?&SmTA_G}&a*_Vwk zt!3ZU)01bH(E_t{UQZKpEbsv5n+UnCcim!5YNfr|JloLI*Kz`3Gb@OYyl2)_K5$A; z@8$^LS~m-;x@{H~)%&yTp#OFj{%*78BFl}rIiTN_i@(FJdN3>x^-J>{u)i%2zpt0_ z@LWiK2I%MKV;A)2*a}n5m=EQt#1xsMvU4ZKw1vuyO3vuqf;=%Dk z?Aq8O%(uA+^LeKT?{lLFe@G-0BeoS|yhFv9$KB#|ASsDGjp<9JH$7HtrnMzF@Yj@J zCmtzDhGZs7k^m!0F-T1*>ibF)L4U%dzwgnfmLXXkW!T9F%VNOpY8l$=%8|6navSKo z%B_HJmoHbRBtD*zmfDo*SQbrdZ+$d8UQsTmX&>o_(_9~C(wi?8(%y}w^s9{~+SX;F zu9qVd8&l)qec6W?b`ad={N5%79D)tAq8d}>s8$DY&bXRvbb@apsv^1GwtgBbF znsReDYx1$1m{)bRAy<^cL;XB2&7-=}o_V6d3vE8}SQPQ9#w9vL)- zCYT!P+uGWnGOcQKw>16H)YEJZ`K{Bl$J~jQS&+w9a{j#ljvaExDlhyc&ss1v(n5dI+ zBX=}1uPAX_giI&CnktJFucXL=M!rdvDfp3|JlUjTWNMb|4cQATOC<4P;?2Z|iJXao z3CBdqglD2+qGsaDM8m|7iI$0uiNHiZva-bR#E<1MUR4J}{9jBd-}7VBnbP;uKi)SG zI1uK1uH`^m@CWm+Wwpnt*7Ss2x-s#6^Xjp86CT~R>Ytn5-M9D5r3;J9cZH!+R+pr# I@ZrM$10U5Ph5!Hn diff --git a/vendor-bin/tests/composer.lock b/vendor-bin/tests/composer.lock index f9101e69..61c64899 100644 --- a/vendor-bin/tests/composer.lock +++ b/vendor-bin/tests/composer.lock @@ -9,28 +9,28 @@ "packages-dev": [ { "name": "behat/behat", - "version": "v3.29.0", + "version": "v3.30.0", "source": { "type": "git", "url": "https://github.com/Behat/Behat.git", - "reference": "51bdf81639a14645c5d2c06926f4aa37d204921b" + "reference": "be4af8c803a1ed589409a8a2eed01f9fb858e11d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Behat/Behat/zipball/51bdf81639a14645c5d2c06926f4aa37d204921b", - "reference": "51bdf81639a14645c5d2c06926f4aa37d204921b", + "url": "https://api.github.com/repos/Behat/Behat/zipball/be4af8c803a1ed589409a8a2eed01f9fb858e11d", + "reference": "be4af8c803a1ed589409a8a2eed01f9fb858e11d", "shasum": "" }, "require": { - "behat/gherkin": "^4.12.0", + "behat/gherkin": "^4.15.0", "composer-runtime-api": "^2.2", "composer/xdebug-handler": "^1.4 || ^2.0 || ^3.0", "ext-mbstring": "*", "nikic/php-parser": "^4.19.2 || ^5.2", - "php": ">=8.1 <8.6", + "php": ">=8.2 <8.6", "psr/container": "^1.0 || ^2.0", "symfony/config": "^5.4 || ^6.4 || ^7.0", - "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/console": "^5.4.9 || ^6.4 || ^7.0", "symfony/dependency-injection": "^5.4 || ^6.4 || ^7.0", "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", "symfony/translation": "^5.4 || ^6.4 || ^7.0", @@ -39,7 +39,7 @@ "require-dev": { "opis/json-schema": "^2.5", "php-cs-fixer/shim": "^3.89", - "phpstan/phpstan": "^2.0", + "phpstan/phpstan": "2.1.18", "phpunit/phpunit": "^9.6", "rector/rector": "2.1.7", "sebastian/diff": "^4.0", @@ -93,7 +93,7 @@ ], "support": { "issues": "https://github.com/Behat/Behat/issues", - "source": "https://github.com/Behat/Behat/tree/v3.29.0" + "source": "https://github.com/Behat/Behat/tree/v3.30.0" }, "funding": [ { @@ -109,7 +109,7 @@ "type": "github" } ], - "time": "2025-12-11T09:51:30+00:00" + "time": "2026-03-26T17:26:12+00:00" }, { "name": "behat/gherkin", @@ -552,16 +552,16 @@ }, { "name": "symfony/config", - "version": "v7.4.7", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "6c17162555bfb58957a55bb0e43e00035b6ae3d5" + "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/6c17162555bfb58957a55bb0e43e00035b6ae3d5", - "reference": "6c17162555bfb58957a55bb0e43e00035b6ae3d5", + "url": "https://api.github.com/repos/symfony/config/zipball/2d19dde43fa2ff720b9a40763ace7226594f503b", + "reference": "2d19dde43fa2ff720b9a40763ace7226594f503b", "shasum": "" }, "require": { @@ -607,7 +607,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v7.4.7" + "source": "https://github.com/symfony/config/tree/v7.4.8" }, "funding": [ { @@ -627,20 +627,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T10:41:14+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/console", - "version": "v7.4.7", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d" + "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/e1e6770440fb9c9b0cf725f81d1361ad1835329d", - "reference": "e1e6770440fb9c9b0cf725f81d1361ad1835329d", + "url": "https://api.github.com/repos/symfony/console/zipball/1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", + "reference": "1e92e39c51f95b88e3d66fa2d9f06d1fb45dd707", "shasum": "" }, "require": { @@ -705,7 +705,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.4.7" + "source": "https://github.com/symfony/console/tree/v7.4.8" }, "funding": [ { @@ -725,20 +725,20 @@ "type": "tidelift" } ], - "time": "2026-03-06T14:06:20+00:00" + "time": "2026-03-30T13:54:39+00:00" }, { "name": "symfony/dependency-injection", - "version": "v7.4.7", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db" + "reference": "f7025fd7b687c240426562f86ada06a93b1e771d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", - "reference": "0f651e58f4917fb0e2cd261ccbfe3d71e6e0f5db", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/f7025fd7b687c240426562f86ada06a93b1e771d", + "reference": "f7025fd7b687c240426562f86ada06a93b1e771d", "shasum": "" }, "require": { @@ -789,7 +789,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v7.4.7" + "source": "https://github.com/symfony/dependency-injection/tree/v7.4.8" }, "funding": [ { @@ -809,7 +809,7 @@ "type": "tidelift" } ], - "time": "2026-03-03T07:48:48+00:00" + "time": "2026-03-31T06:50:29+00:00" }, { "name": "symfony/deprecation-contracts", @@ -880,16 +880,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v7.4.4", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "dc2c0eba1af673e736bb851d747d266108aea746" + "reference": "f57b899fa736fd71121168ef268f23c206083f0a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/dc2c0eba1af673e736bb851d747d266108aea746", - "reference": "dc2c0eba1af673e736bb851d747d266108aea746", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/f57b899fa736fd71121168ef268f23c206083f0a", + "reference": "f57b899fa736fd71121168ef268f23c206083f0a", "shasum": "" }, "require": { @@ -941,7 +941,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.4" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.8" }, "funding": [ { @@ -961,7 +961,7 @@ "type": "tidelift" } ], - "time": "2026-01-05T11:45:34+00:00" + "time": "2026-03-30T13:54:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -1041,16 +1041,16 @@ }, { "name": "symfony/filesystem", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e" + "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/3ebc794fa5315e59fd122561623c2e2e4280538e", - "reference": "3ebc794fa5315e59fd122561623c2e2e4280538e", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/58b9790d12f9670b7f53a1c1738febd3108970a5", + "reference": "58b9790d12f9670b7f53a1c1738febd3108970a5", "shasum": "" }, "require": { @@ -1087,7 +1087,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.4.6" + "source": "https://github.com/symfony/filesystem/tree/v7.4.8" }, "funding": [ { @@ -1107,7 +1107,7 @@ "type": "tidelift" } ], - "time": "2026-02-25T16:50:00+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/polyfill-ctype", @@ -1533,16 +1533,16 @@ }, { "name": "symfony/string", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b" + "reference": "114ac57257d75df748eda23dd003878080b8e688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/9f209231affa85aa930a5e46e6eb03381424b30b", - "reference": "9f209231affa85aa930a5e46e6eb03381424b30b", + "url": "https://api.github.com/repos/symfony/string/zipball/114ac57257d75df748eda23dd003878080b8e688", + "reference": "114ac57257d75df748eda23dd003878080b8e688", "shasum": "" }, "require": { @@ -1600,7 +1600,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.4.6" + "source": "https://github.com/symfony/string/tree/v7.4.8" }, "funding": [ { @@ -1620,20 +1620,20 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/translation", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "1888cf064399868af3784b9e043240f1d89d25ce" + "reference": "33600f8489485425bfcddd0d983391038d3422e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/1888cf064399868af3784b9e043240f1d89d25ce", - "reference": "1888cf064399868af3784b9e043240f1d89d25ce", + "url": "https://api.github.com/repos/symfony/translation/zipball/33600f8489485425bfcddd0d983391038d3422e7", + "reference": "33600f8489485425bfcddd0d983391038d3422e7", "shasum": "" }, "require": { @@ -1700,7 +1700,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v7.4.6" + "source": "https://github.com/symfony/translation/tree/v7.4.8" }, "funding": [ { @@ -1720,7 +1720,7 @@ "type": "tidelift" } ], - "time": "2026-02-17T07:53:42+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/translation-contracts", @@ -1806,16 +1806,16 @@ }, { "name": "symfony/var-exporter", - "version": "v7.4.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "03a60f169c79a28513a78c967316fbc8bf17816f" + "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/03a60f169c79a28513a78c967316fbc8bf17816f", - "reference": "03a60f169c79a28513a78c967316fbc8bf17816f", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/398907e89a2a56fe426f7955c6fa943ec0c77225", + "reference": "398907e89a2a56fe426f7955c6fa943ec0c77225", "shasum": "" }, "require": { @@ -1863,7 +1863,7 @@ "serialize" ], "support": { - "source": "https://github.com/symfony/var-exporter/tree/v7.4.0" + "source": "https://github.com/symfony/var-exporter/tree/v7.4.8" }, "funding": [ { @@ -1883,20 +1883,20 @@ "type": "tidelift" } ], - "time": "2025-09-11T10:15:23+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/yaml", - "version": "v7.4.6", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "58751048de17bae71c5aa0d13cb19d79bca26391" + "reference": "c58fdf7b3d6c2995368264c49e4e8b05bcff2883" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/58751048de17bae71c5aa0d13cb19d79bca26391", - "reference": "58751048de17bae71c5aa0d13cb19d79bca26391", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c58fdf7b3d6c2995368264c49e4e8b05bcff2883", + "reference": "c58fdf7b3d6c2995368264c49e4e8b05bcff2883", "shasum": "" }, "require": { @@ -1939,7 +1939,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.4.6" + "source": "https://github.com/symfony/yaml/tree/v7.4.8" }, "funding": [ { @@ -1959,7 +1959,7 @@ "type": "tidelift" } ], - "time": "2026-02-09T09:33:46+00:00" + "time": "2026-03-24T13:12:05+00:00" } ], "aliases": [], From dfae2d2b5f4d7c654b6527984f5a8930c68f9bd9 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 7 May 2026 07:24:58 +0000 Subject: [PATCH 9/9] test: drop pure-logic regression test that doesn't test against Updater class Agent-Logs-Url: https://github.com/nextcloud/updater/sessions/28c7bc95-7a60-4f58-9fe9-27fc9d5f3143 Co-authored-by: skjnldsv <14975046+skjnldsv@users.noreply.github.com> --- tests/unit/UpdaterTest.php | 30 ------------------------------ vendor/composer/installed.php | 4 ++-- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/tests/unit/UpdaterTest.php b/tests/unit/UpdaterTest.php index 9b9736fd..a89a5427 100644 --- a/tests/unit/UpdaterTest.php +++ b/tests/unit/UpdaterTest.php @@ -133,36 +133,6 @@ public function testConstructorThrowsOnInvalidBaseDir(): void { // The fix: ltrim(substr($absolutePath, strlen($nextcloudDir)), '/') // ------------------------------------------------------------------------- - /** - * Pure logic regression: shows exactly why explode() was wrong and that - * the substr() replacement is correct. - */ - public function testRelativePathExtractionForIssue711(): void { - // Simulate Nextcloud installed at /nextcloud (as in the bug report) - $installDir = '/nextcloud'; - // File deep inside core/doc with the same name as the install dir - $filePath = '/nextcloud/core/doc/admin/configuration_files/external_storage/nextcloud.html'; - - // Old (buggy) approach: explode splits on ALL occurrences of $installDir. - // '/nextcloud' appears at the start AND inside '.../external_storage/nextcloud.html' - // (because '/nextcloud.html' begins with '/nextcloud'). - $oldRelativePath = explode($installDir, $filePath)[1]; - $this->assertSame( - '/core/doc/admin/configuration_files/external_storage', - $oldRelativePath, - 'The old explode() approach incorrectly returns a directory path' - ); - $this->assertStringNotContainsString('nextcloud.html', $oldRelativePath); - - // New (fixed) approach: substr() always takes exactly the right suffix. - $newRelativePath = ltrim(substr($filePath, strlen($installDir)), '/'); - $this->assertSame( - 'core/doc/admin/configuration_files/external_storage/nextcloud.html', - $newRelativePath, - 'The substr() approach correctly returns the full relative file path' - ); - } - /** * Integration regression: createBackup() must copy a deeply nested file * that has the install-directory name as part of its own name, without diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 0e1e0fbc..3217a893 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => '__root__', 'pretty_version' => 'dev-copilot/add-string-concat-method', 'version' => 'dev-copilot/add-string-concat-method', - 'reference' => 'dc688b2b097ffaa4f596e943d3626d5b65e6016a', + 'reference' => '851f344fad579276efb35eef23b70f76d7ce71e9', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,7 +13,7 @@ '__root__' => array( 'pretty_version' => 'dev-copilot/add-string-concat-method', 'version' => 'dev-copilot/add-string-concat-method', - 'reference' => 'dc688b2b097ffaa4f596e943d3626d5b65e6016a', + 'reference' => '851f344fad579276efb35eef23b70f76d7ce71e9', 'type' => 'library', 'install_path' => __DIR__ . '/../../', 'aliases' => array(),