mirror of
https://github.com/danog/psalm.git
synced 2024-11-26 20:34:47 +01:00
Add support for absolute plugin paths.
This commit is contained in:
parent
dd40987187
commit
ecb7a6c069
@ -24,12 +24,19 @@ Here are a couple of example plugins:
|
|||||||
- [FunctionCasingChecker](https://github.com/vimeo/psalm/blob/master/examples/plugins/FunctionCasingChecker.php) - checks that your functions and methods are correctly-cased
|
- [FunctionCasingChecker](https://github.com/vimeo/psalm/blob/master/examples/plugins/FunctionCasingChecker.php) - checks that your functions and methods are correctly-cased
|
||||||
|
|
||||||
To ensure your plugin runs when Psalm does, add it to your [config](configuration.md):
|
To ensure your plugin runs when Psalm does, add it to your [config](configuration.md):
|
||||||
```php
|
```xml
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin filename="src/plugins/SomePlugin.php" />
|
<plugin filename="src/plugins/SomePlugin.php" />
|
||||||
</plugins>
|
</plugins>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can also specify an absolute path to your plugin:
|
||||||
|
```xml
|
||||||
|
<plugins>
|
||||||
|
<plugin filename="/path/to/SomePlugin.php" />
|
||||||
|
</plugins>
|
||||||
|
```
|
||||||
|
|
||||||
## Type system
|
## Type system
|
||||||
|
|
||||||
Understand how Psalm handles types by [reading this guide](plugins_type_system.md).
|
Understand how Psalm handles types by [reading this guide](plugins_type_system.md).
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
|
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/5.7/phpunit.xsd"
|
||||||
bootstrap="vendor/autoload.php"
|
bootstrap="tests/bootstrap.php"
|
||||||
backupGlobals="false"
|
backupGlobals="false"
|
||||||
beStrictAboutCoversAnnotation="true"
|
beStrictAboutCoversAnnotation="true"
|
||||||
beStrictAboutOutputDuringTests="true"
|
beStrictAboutOutputDuringTests="true"
|
||||||
|
@ -792,9 +792,11 @@ class Config
|
|||||||
if (isset($config_xml->plugins->plugin)) {
|
if (isset($config_xml->plugins->plugin)) {
|
||||||
/** @var \SimpleXMLElement $plugin */
|
/** @var \SimpleXMLElement $plugin */
|
||||||
foreach ($config_xml->plugins->plugin as $plugin) {
|
foreach ($config_xml->plugins->plugin as $plugin) {
|
||||||
$plugin_file_name = $plugin['filename'];
|
$plugin_file_name = (string) $plugin['filename'];
|
||||||
|
|
||||||
$path = $config->base_dir . $plugin_file_name;
|
$path = isAbsolutePath($plugin_file_name)
|
||||||
|
? $plugin_file_name
|
||||||
|
: $config->base_dir . $plugin_file_name;
|
||||||
|
|
||||||
$config->addPluginPath($path);
|
$config->addPluginPath($path);
|
||||||
}
|
}
|
||||||
|
@ -220,3 +220,32 @@ function getPathsToCheck($f_paths)
|
|||||||
|
|
||||||
return $paths_to_check;
|
return $paths_to_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function isAbsolutePath($path)
|
||||||
|
{
|
||||||
|
// Optional wrapper(s).
|
||||||
|
$regex = '%^(?<wrappers>(?:[[:print:]]{2,}://)*)';
|
||||||
|
|
||||||
|
// Optional root prefix.
|
||||||
|
$regex .= '(?<root>(?:[[:alpha:]]:/|/)?)';
|
||||||
|
|
||||||
|
// Actual path.
|
||||||
|
$regex .= '(?<path>(?:[[:print:]]*))$%';
|
||||||
|
|
||||||
|
$parts = [];
|
||||||
|
|
||||||
|
if (!preg_match($regex, $path, $parts)) {
|
||||||
|
throw new InvalidArgumentException(sprintf('Path is not valid, "%s" given.', $path));
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('' !== $parts['root']) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
36
tests/IsAbsolutePathTest.php
Normal file
36
tests/IsAbsolutePathTest.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
namespace Psalm\Tests;
|
||||||
|
|
||||||
|
class IsAbsolutePathTest extends TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $path
|
||||||
|
* @param bool $expected
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
* @dataProvider providerForTestIsAbsolutePath
|
||||||
|
*/
|
||||||
|
public function testIsAbsolutePath($path, $expected)
|
||||||
|
{
|
||||||
|
require_once __DIR__.'/../src/command_functions.php';
|
||||||
|
|
||||||
|
self::assertSame($expected, isAbsolutePath($path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, array{0:string, 1:bool}>
|
||||||
|
*/
|
||||||
|
public function providerForTestIsAbsolutePath()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
['/path/to/something', true],
|
||||||
|
['/path/to/something/file.php', true],
|
||||||
|
['relative/path/to/something', false],
|
||||||
|
['relative/path/to/something/file.php', false],
|
||||||
|
['c:/path/to/something', true],
|
||||||
|
['file://c:/path/to/something', true],
|
||||||
|
['zlib://c:/path/to/something', true],
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
@ -770,4 +770,59 @@ class PluginTest extends TestCase
|
|||||||
$this->project_analyzer->check('tests/DummyProject', true);
|
$this->project_analyzer->check('tests/DummyProject', true);
|
||||||
\Psalm\IssueBuffer::finish($this->project_analyzer, true, microtime(true));
|
\Psalm\IssueBuffer::finish($this->project_analyzer, true, microtime(true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testPluginFilenameCanBeAbsolute()
|
||||||
|
{
|
||||||
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||||
|
TestConfig::loadFromXML(
|
||||||
|
dirname(__DIR__) . DIRECTORY_SEPARATOR,
|
||||||
|
sprintf(
|
||||||
|
'<?xml version="1.0"?>
|
||||||
|
<psalm>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
<plugins>
|
||||||
|
<plugin filename="%s/examples/plugins/StringChecker.php" />
|
||||||
|
</plugins>
|
||||||
|
</psalm>',
|
||||||
|
__DIR__.'/..'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->project_analyzer->getCodebase()->config->initializePlugins($this->project_analyzer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException InvalidArgumentException
|
||||||
|
* @expectedExceptionMessage does-not-exist/plugins/StringChecker.php
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function testPluginInvalidAbsoluteFilenameThrowsException()
|
||||||
|
{
|
||||||
|
$this->project_analyzer = $this->getProjectAnalyzerWithConfig(
|
||||||
|
TestConfig::loadFromXML(
|
||||||
|
dirname(__DIR__) . DIRECTORY_SEPARATOR,
|
||||||
|
sprintf(
|
||||||
|
'<?xml version="1.0"?>
|
||||||
|
<psalm>
|
||||||
|
<projectFiles>
|
||||||
|
<directory name="src" />
|
||||||
|
</projectFiles>
|
||||||
|
<plugins>
|
||||||
|
<plugin filename="%s/does-not-exist/plugins/StringChecker.php" />
|
||||||
|
</plugins>
|
||||||
|
</psalm>',
|
||||||
|
__DIR__.'/..'
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->project_analyzer->getCodebase()->config->initializePlugins($this->project_analyzer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
ini_set('display_startup_errors', '1');
|
require_once(__DIR__.'/../src/command_functions.php');
|
||||||
ini_set('html_errors', '1');
|
|
||||||
ini_set('memory_limit', '-1');
|
|
||||||
error_reporting(E_ALL);
|
|
||||||
|
|
||||||
foreach ([__DIR__ . '/../../../autoload.php', __DIR__ . '/../vendor/autoload.php'] as $file) {
|
return require_once(__DIR__.'/../vendor/autoload.php');
|
||||||
if (file_exists($file)) {
|
|
||||||
require $file;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user