diff --git a/.github/workflows/behat.yml b/.github/workflows/behat.yml index 4adf4e0..b97c062 100644 --- a/.github/workflows/behat.yml +++ b/.github/workflows/behat.yml @@ -26,3 +26,24 @@ jobs: - name: Run behat run: vendor/bin/behat -f pretty --colors + + xdebug-persistent-occ: + runs-on: ubuntu-latest + + steps: + - name: Checkout app + uses: actions/checkout@v4 + + - name: Set up PHP with Xdebug and APCu + uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + coverage: xdebug + extensions: apcu + + - name: Set up dependencies + run: composer install + + - name: Run Behat after persistent Xdebug restart + run: | + XDEBUG_HANDLER_DEBUG=2 vendor/bin/behat features/test.feature --name "Occ command keeps PHP configuration after persistent Xdebug restart" -f pretty --colors diff --git a/features/bootstrap/console.php b/features/bootstrap/console.php index 60e588d..9b09bb2 100644 --- a/features/bootstrap/console.php +++ b/features/bootstrap/console.php @@ -6,7 +6,12 @@ * the occ commands execution. */ -if (in_array('invalid-command', $argv)) { +if (in_array('php-config', $argv, true)) { + echo 'scanned=' . (php_ini_scanned_files() !== false ? '1' : '0') . PHP_EOL; + exit; +} + +if (in_array('invalid-command', $argv, true)) { echo "Invalid command\n"; exit(1); } diff --git a/features/test.feature b/features/test.feature index ea21f48..438eb7e 100644 --- a/features/test.feature +++ b/features/test.feature @@ -339,3 +339,10 @@ Feature: Test this extension """ And sending "POST" to "/" Then the response body should match the regular expression "^%PDF" + + Scenario: Occ command keeps PHP configuration after persistent Xdebug restart + When run the command "php-config" with result code 0 + Then the output of the last command should contain the following text: + """ + scanned=1 + """ diff --git a/src/NextcloudApiContext.php b/src/NextcloudApiContext.php index e2dd98a..bf68b20 100644 --- a/src/NextcloudApiContext.php +++ b/src/NextcloudApiContext.php @@ -10,6 +10,7 @@ use Behat\Hook\BeforeSuite; use Behat\Step\Given; use Behat\Testwork\Hook\Scope\BeforeSuiteScope; +use Composer\XdebugHandler\XdebugHandler; use DOMDocument; use Exception; use GuzzleHttp\Client; @@ -598,21 +599,42 @@ public static function runCommand(string $command): array { throw new \Exception('Could not retrieve owner information for UID ' . $fileOwnerUid); } $baseCommand = 'php ' . $console . ' ' . $command; - $environmentPrefix = !empty(self::$environments) - ? http_build_query(self::$environments, '', ' ') - : ''; + $commandEnvironment = self::$environments; + $restartSettings = XdebugHandler::getRestartSettings(); + if ($restartSettings !== null) { + $commandEnvironment['PHP_INI_SCAN_DIR'] = $restartSettings['scanDir']; + $commandEnvironment['PHPRC'] = $restartSettings['phprc']; + $commandEnvironment['XDEBUG_MODE'] = 'off'; + } + $environmentPrefix = self::buildEnvironmentPrefix($commandEnvironment); if (posix_getuid() !== $owner['uid']) { - $fullCommand = 'runuser -u ' . $owner['name'] . ' -- ' + $fullCommand = 'runuser -u ' . escapeshellarg($owner['name']) . ' -- ' . ($environmentPrefix !== '' ? 'env ' . $environmentPrefix . ' ' : '') . $baseCommand; } else { - $fullCommand = ($environmentPrefix !== '' ? $environmentPrefix . ' ' : '') . $baseCommand; + $fullCommand = ($environmentPrefix !== '' ? 'env ' . $environmentPrefix . ' ' : '') . $baseCommand; } $fullCommand .= ' 2>&1'; return self::runBashCommand($fullCommand); } + /** + * @param array $environment + */ + private static function buildEnvironmentPrefix(array $environment): string { + $options = []; + $assignments = []; + foreach ($environment as $name => $value) { + if ($value === false) { + $options[] = '-u ' . escapeshellarg($name); + continue; + } + $assignments[] = $name . '=' . escapeshellarg($value); + } + return implode(' ', [...$options, ...$assignments]); + } + public static function findParentDirContainingFile(string $filename): string { $dir = getcwd(); if (is_bool($dir)) {