Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,23 @@ jobs:
../bashunit -a contains 'Foo.php:11:Instantiated class Ds\Vector not found.' "$OUTPUT"
../bashunit -a contains 'Bar.php:15:Call to an undefined method Ds\Pair<string, int>::copy().' "$OUTPUT"
../bashunit -a not_contains 'Ds\Seq' "$OUTPUT"
- script: |
echo "<?php echo 'Hello 1';" > test.php
XDEBUG_HANDLER_DEBUG=1 bin/phpstan analyse test.php 2>&1 | tee -a output.txt
e2e/bashunit -a file_contains output.txt "Process restarting"
coverage: "pcov"
- script: |
echo "<?php echo 'Hello 2';" > test.php
XDEBUG_HANDLER_DEBUG=1 bin/phpstan analyse test.php 2>&1 | tee -a output.txt
e2e/bashunit -a file_contains output.txt "Process restarting"
coverage: "pcov"
ini-values: "pcov.enabled=1"
- script: |
echo "<?php echo 'Hello 3';" > test.php
XDEBUG_HANDLER_DEBUG=1 bin/phpstan analyse test.php 2>&1 | tee -a output.txt
e2e/bashunit -a file_not_contains output.txt "Process restarting"
coverage: "pcov"
ini-values: "pcov.enabled=0"

steps:
- name: Harden the runner (Audit all outbound calls)
Expand All @@ -2041,7 +2058,8 @@ jobs:
- name: "Install PHP"
uses: "shivammathur/setup-php@eb7c497e18156a6bbabfef1d3a82760b9eda3962" # 2.40.0
with:
coverage: "none"
coverage: ${{ matrix.coverage || 'none' }}
ini-values: ${{ matrix.ini-values || '' }}
php-version: "8.2"
tools: ${{ matrix.tools }}
extensions: ${{ matrix.extensions }}
Expand Down
10 changes: 5 additions & 5 deletions src/Command/CommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
namespace PHPStan\Command;

use Composer\Semver\Semver;
use Composer\XdebugHandler\XdebugHandler;
use Nette\DI\Helpers;
use Nette\DI\InvalidConfigurationException;
use Nette\DI\ServiceCreationException;
Expand Down Expand Up @@ -32,6 +31,7 @@
use PHPStan\Internal\DirectoryCreator;
use PHPStan\Internal\DirectoryCreatorException;
use PHPStan\Process\ForkedChildCrashReporter;
use PHPStan\Process\ProcessRestarter;
use PHPStan\ShouldNotHappenException;
use ReflectionClass;
use Symfony\Component\Console\Input\InputInterface;
Expand Down Expand Up @@ -104,22 +104,22 @@ public static function begin(
$errorOutput = new SymfonyOutput($symfonyErrorOutput, new SymfonyStyle(new ErrorsConsoleStyle($input, $symfonyErrorOutput)));

if (!$allowXdebug) {
$xdebug = new XdebugHandler('phpstan');
$xdebug = new ProcessRestarter('phpstan');
$xdebug->setPersistent();
$xdebug->check();
unset($xdebug);
}

if ($allowXdebug) {
if (!XdebugHandler::isXdebugActive()) {
if (!ProcessRestarter::isXdebugActive()) {
$errorOutput->getStyle()->note('You are running with "--xdebug" enabled, but the Xdebug PHP extension is not active. The process will not halt at breakpoints.');
} else {
$errorOutput->getStyle()->note("You are running with \"--xdebug\" enabled, and the Xdebug PHP extension is active.\nThe process will halt at breakpoints, but PHPStan will run much slower.\nUse this only if you are debugging PHPStan itself or your custom extensions.");
}
} elseif (XdebugHandler::isXdebugActive()) {
} elseif (ProcessRestarter::isXdebugActive()) {
$errorOutput->getStyle()->note('The Xdebug PHP extension is active, but "--xdebug" is not used. This may slow down performance and the process will not halt at breakpoints.');
} elseif ($debugEnabled) {
$v = XdebugHandler::getSkippedVersion();
$v = ProcessRestarter::getSkippedVersion();
if ($v !== '') {
$errorOutput->getStyle()->note(
"The Xdebug PHP extension is active, but \"--xdebug\" is not used.\n" .
Expand Down
56 changes: 56 additions & 0 deletions src/Process/ProcessRestarter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php declare(strict_types = 1);

namespace PHPStan\Process;

use Composer\XdebugHandler\XdebugHandler;
use Override;
use function count;
use function extension_loaded;
use function file_get_contents;
use function file_put_contents;
use function ini_get;
use function preg_replace;
use const PHP_EOL;

// see https://github.com/composer/xdebug-handler/issues/174
final class ProcessRestarter extends XdebugHandler
{

/** @var array<string> */
private array $extensions = [];

#[Override]
protected function requiresRestart(bool $default): bool
{
// pcov has a perf impact similar to xdebug, so we want to disable it
if (extension_loaded('pcov') && ini_get('pcov.enabled') === '1') {
$this->extensions[] = 'pcov';
}

// tideways hooks deep in the php engine, so it can segfault when running phpstan with turbo.
if (extension_loaded('tideways')) {
$this->extensions[] = 'tideways';
}

return $default || count($this->extensions) > 0;
}

#[Override]
protected function restart(array $command): void
{
if (count($this->extensions) > 0) {
$content = file_get_contents((string) $this->tmpIni);

if ($content !== false) {
foreach ($this->extensions as $extension) {
$regex = '/^\s*((?:zend_)?extension\s*=.*' . $extension . '.*)$/mi';
$content = preg_replace($regex, ';$1', $content) . PHP_EOL;
}
file_put_contents((string) $this->tmpIni, $content);
}
}

parent::restart($command);
}

}
Loading