Skip to content
Snippets Groups Projects
Commit 49629d02 authored by David Prévot's avatar David Prévot
Browse files

New upstream version 2.0.4

parents 33870852 0c1a3925
No related branches found
No related tags found
No related merge requests found
## [Unreleased]
## [2.0.4] - 2022-01-04
* Fixed: allow calling `isXdebugActive` before class instantiation.
## [2.0.3] - 2021-12-08
* Added: support, type annotations and refactoring for stricter PHPStan analysis.
......@@ -94,7 +97,8 @@
* Break: the following class was renamed:
- `Composer\XdebugHandler` -> `Composer\XdebugHandler\XdebugHandler`
[Unreleased]: https://github.com/composer/xdebug-handler/compare/2.0.3...HEAD
[Unreleased]: https://github.com/composer/xdebug-handler/compare/2.0.4...HEAD
[2.0.4]: https://github.com/composer/xdebug-handler/compare/2.0.3...2.0.4
[2.0.3]: https://github.com/composer/xdebug-handler/compare/2.0.2...2.0.3
[2.0.2]: https://github.com/composer/xdebug-handler/compare/2.0.1...2.0.2
[2.0.1]: https://github.com/composer/xdebug-handler/compare/2.0.0...2.0.1
......
......@@ -42,6 +42,12 @@ class XdebugHandler
/** @var bool */
private static $xdebugActive;
/** @var string|null */
private static $xdebugMode;
/** @var string|null */
private static $xdebugVersion;
/** @var bool */
private $cli;
......@@ -54,12 +60,6 @@ class XdebugHandler
/** @var string */
private $envOriginalInis;
/** @var string|null */
private $loaded;
/** @var string|null */
private $mode;
/** @var bool */
private $persistent;
......@@ -89,13 +89,7 @@ class XdebugHandler
$this->envAllowXdebug = self::$name.self::SUFFIX_ALLOW;
$this->envOriginalInis = self::$name.self::SUFFIX_INIS;
if (extension_loaded('xdebug')) {
$version = phpversion('xdebug');
$this->loaded = $version !== false ? $version : 'unknown';
$this->mode = $this->getXdebugMode($this->loaded);
}
self::$xdebugActive = $this->loaded !== null && $this->mode !== 'off';
self::setXdebugDetails();
self::$inRestart = false;
if ($this->cli = PHP_SAPI === 'cli') {
......@@ -153,7 +147,7 @@ class XdebugHandler
*/
public function check()
{
$this->notify(Status::CHECK, $this->loaded.'|'.$this->mode);
$this->notify(Status::CHECK, self::$xdebugVersion.'|'.self::$xdebugMode);
$envArgs = explode('|', (string) getenv($this->envAllowXdebug));
if (!((bool) $envArgs[0]) && $this->requiresRestart(self::$xdebugActive)) {
......@@ -174,7 +168,7 @@ class XdebugHandler
Process::setEnv($this->envAllowXdebug);
self::$inRestart = true;
if ($this->loaded === null) {
if (self::$xdebugVersion === null) {
// Skipped version is only set if Xdebug is not loaded
self::$skipped = $envArgs[1];
}
......@@ -271,6 +265,7 @@ class XdebugHandler
*/
public static function isXdebugActive()
{
self::setXdebugDetails();
return self::$xdebugActive;
}
......@@ -492,7 +487,7 @@ class XdebugHandler
// Flag restarted process and save values for it to use
$envArgs = array(
self::RESTART_ID,
$this->loaded,
self::$xdebugVersion,
(int) $scannedInis,
false === $scanDir ? '*' : $scanDir,
false === $phprc ? '*' : $phprc,
......@@ -700,38 +695,50 @@ class XdebugHandler
}
/**
* Returns the Xdebug mode if available
*
* @param string $version
* Sets static properties $xdebugActive, $xdebugVersion and $xdebugMode
*
* @return string|null
* @return void
*/
private function getXdebugMode($version)
private static function setXdebugDetails()
{
if (version_compare($version, '3.1', '>=')) {
if (self::$xdebugActive !== null) {
return;
}
self::$xdebugActive = false;
if (!extension_loaded('xdebug')) {
return;
}
$version = phpversion('xdebug');
self::$xdebugVersion = $version !== false ? $version : 'unknown';
if (version_compare(self::$xdebugVersion, '3.1', '>=')) {
$modes = xdebug_info('mode');
return count($modes) === 0 ? 'off' : implode(',', $modes);
self::$xdebugMode = count($modes) === 0 ? 'off' : implode(',', $modes);
self::$xdebugActive = self::$xdebugMode !== 'off';
return;
}
// See if xdebug.mode is supported in this version
$iniMode = ini_get('xdebug.mode');
if ($iniMode === false) {
return null;
return;
}
// Environment value wins but cannot be empty
$envMode = (string) getenv('XDEBUG_MODE');
if ($envMode !== '') {
$mode = $envMode;
self::$xdebugMode = $envMode;
} else {
$mode = $iniMode !== '' ? $iniMode : 'off';
self::$xdebugMode = $iniMode !== '' ? $iniMode : 'off';
}
// An empty comma-separated list is treated as mode 'off'
if (Preg::isMatch('/^,+$/', str_replace(' ', '', $mode))) {
$mode = 'off';
if (Preg::isMatch('/^,+$/', str_replace(' ', '', self::$xdebugMode))) {
self::$xdebugMode = 'off';
}
return $mode;
self::$xdebugActive = self::$xdebugMode !== 'off';
}
}
......@@ -11,11 +11,11 @@
namespace Composer\XdebugHandler\Tests;
use Composer\XdebugHandler\Tests\Helpers\BaseTestCase;
use Composer\XdebugHandler\Tests\Helpers\LoggerFactory;
use Composer\XdebugHandler\XdebugHandler;
use PHPUnit\Framework\TestCase;
class ClassTest extends BaseTestCase
class ClassTest extends TestCase
{
/**
* @return void
......@@ -37,32 +37,20 @@ class ClassTest extends BaseTestCase
}
/**
* @dataProvider setterProvider *
* @param string $setter
* @param \Psr\Log\AbstractLogger|string|null $value
*
* @return void
*/
public function testSettersAreFluent($setter, $value)
public function testSettersAreFluent()
{
$xdebug = new XdebugHandler('myapp');
$params = null !== $value ? array($value) : array();
$result = BaseTestCase::safeCall($xdebug, $setter, $params, $this);
self::assertInstanceOf(get_class($xdebug), $result);
}
$result = $xdebug->setLogger(LoggerFactory::createLogger());
self::assertInstanceOf(get_class($xdebug), $result, 'setLogger');
/**
* @return array<string, mixed[]>
*/
public function setterProvider()
{
// $setter, $value
return array(
'setLogger' => array('setLogger', LoggerFactory::createLogger()),
'setMainScript' => array('setMainScript', '--'),
'setPersistent' => array('setPersistent', null),
);
$result = $xdebug->setMainScript('--');
self::assertInstanceOf(get_class($xdebug), $result, 'setMainScript');
$result = $xdebug->setPersistent();
self::assertInstanceOf(get_class($xdebug), $result, 'setPersistent');
}
/**
......
......@@ -142,7 +142,7 @@ abstract class BaseTestCase extends TestCase
self::assertSame(true, isset($_SERVER[CoreMock::ORIGINAL_INIS]));
// Skipped version must only be reported if it was unloaded in the restart
if (!$xdebug->parentLoaded) {
if ($xdebug->parentXdebugVersion === null) {
// Mocked successful restart without Xdebug
$version = '';
} elseif ($xdebug instanceof FailMock) {
......
......@@ -35,8 +35,8 @@ class CoreMock extends XdebugHandler
/** @var bool */
public $restarted;
/** @var bool */
public $parentLoaded;
/** @var string|null */
public $parentXdebugVersion;
/** @var null|static */
protected $childProcess;
......@@ -80,7 +80,7 @@ class CoreMock extends XdebugHandler
// properties on the parent and child
$parentProcess->restarted = true;
$xdebug->restarted = true;
$xdebug->parentLoaded = $parentProcess->parentLoaded;
$xdebug->parentXdebugVersion = $parentProcess->parentXdebugVersion;
// Make the child available
$parentProcess->childProcess = $xdebug;
......@@ -109,15 +109,15 @@ class CoreMock extends XdebugHandler
parent::__construct('mock');
$this->refClass = new \ReflectionClass('Composer\XdebugHandler\XdebugHandler');
$this->parentLoaded = $loaded ? static::TEST_VERSION : null;
$this->parentXdebugVersion = $loaded ? static::TEST_VERSION : null;
// Set private loaded
$prop = $this->refClass->getProperty('loaded');
// Set private static xdebugVersion
$prop = $this->refClass->getProperty('xdebugVersion');
$prop->setAccessible(true);
$prop->setValue($this, $this->parentLoaded);
$prop->setValue($this, $this->parentXdebugVersion);
// Set private mode
$prop = $this->refClass->getProperty('mode');
// Set private static xdebugMode
$prop = $this->refClass->getProperty('xdebugMode');
$prop->setAccessible(true);
$prop->setValue($this, $mode);
......@@ -131,11 +131,6 @@ class CoreMock extends XdebugHandler
$prop->setAccessible(true);
$prop->setValue($this, null);
// Ensure static private inRestart is unset
$prop = $this->refClass->getProperty('inRestart');
$prop->setAccessible(true);
$prop->setValue($this, null);
$this->restarted = false;
}
......
......@@ -86,7 +86,7 @@ class SettingsTest extends BaseTestCase
putenv(CoreMock::ORIGINAL_INIS);
unset($_SERVER[CoreMock::ORIGINAL_INIS]);
// Mock not loaded ($inRestart and $skipped statics are unset)
// Mock not loaded (static $skipped is unset in mock constructor)
$loaded = false;
CoreMock::createAndCheck($loaded);
......
<?php
/**
* Provides flexibilty for using either simple-phpunit or phpunit
*/
$vendorBin = __DIR__.'/../vendor/bin';
// See if we using simple-phpunit
$path = realpath($vendorBin.'/simple-phpunit');
if (!file_exists($vendorBin.'/phpunit') && $path !== false) {
passthru(escapeshellarg($path).' install');
if ($path !== false) {
// simple-phpunit will update the .phpunit symlink/junction
$phpunit = escapeshellarg(PHP_BINARY).' '.escapeshellarg($path);
passthru($phpunit.' install');
$autoloader = $vendorBin.'/.phpunit/phpunit/vendor/autoload.php';
if (file_exists($autoloader)) {
require $autoloader;
if (!file_exists($autoloader)) {
echo 'Cannot run PHPStan: simple-phpunit did not install PHPUnit as expected'.PHP_EOL;
exit(1);
}
include $autoloader;
return;
}
if (realpath($vendorBin.'/phpunit') === false) {
echo 'Cannot run PHPStan: PHPUnit has not been installed'.PHP_EOL;
exit(1);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment