Skip to content

Commit

Permalink
Merge pull request #43 from EdgedesignCZ/phpstan
Browse files Browse the repository at this point in the history
Support phpstan v0.5
  • Loading branch information
zdenekdrahos committed Jan 7, 2017
2 parents 3f01f32 + 915d737 commit e116b09
Show file tree
Hide file tree
Showing 16 changed files with 105 additions and 15 deletions.
3 changes: 2 additions & 1 deletion .gitignore
@@ -1,3 +1,4 @@
/nbproject/
/vendor/
/build/
/build/
phpstan-phpqa.neon
5 changes: 5 additions & 0 deletions .phpqa.yml
Expand Up @@ -8,6 +8,11 @@ phpcpd:
minLines: 5
minTokens: 70

phpstan:
level: 0
# https://github.com/phpstan/phpstan#configuration
# standard: tests/.travis/phpstan.neon

# paths are relative to .phpqa.yml, so don't copy-paste this section if you don't have custom templates
report:
phploc: app/report/phploc.xsl
Expand Down
15 changes: 10 additions & 5 deletions README.md
Expand Up @@ -45,11 +45,14 @@ Tool| Description
##### Suggested tools

Newly added tools aren't preinstalled. You have to install relevant composer packages if
you want to use.
you want to use them.
Stable tool is executed if composer package is installed.
Experimental tool is executed only if the tool is specified in `--tools`.

Tool | Supported since | Description |
---- | --------------- |----------- |
[parallel-lint](https://github.com/JakubOnderka/PHP-Parallel-Lint) | `>= 1.9` | Check syntax of PHP files |
Tool | PHP | Supported since | Description | Status |
---- | --- | --------------- | ----------- | ------ |
[parallel-lint](https://github.com/JakubOnderka/PHP-Parallel-Lint) | `>= 5.4` | `1.9` | Check syntax of PHP files | stable |
[phpstan](https://github.com/phpstan/phpstan) | `>= 7.0` | `1.9` | Discover bugs in your code without running it | _experimental_ ([`v0.5`](https://github.com/EdgedesignCZ/phpqa/pull/43)) |

_Tip_: use [`bin/suggested-tools.sh install`](/bin/suggested-tools.sh) for installing the tools.

Expand Down Expand Up @@ -136,6 +139,7 @@ pdepend | [pdepend-jdepend.xml](https://edgedesigncz.github.io/phpqa/report/pdep
phpmd | [phpmd.xml](https://edgedesigncz.github.io/phpqa/report/phpmd.xml) | [](https://github.com/phpmd/phpmd/blob/master/src/main/php/PHPMD/Renderer/TextRenderer.php#L47) |
phpmetrics | [phpmetrics.html](https://edgedesigncz.github.io/phpqa/report/phpmetrics.html), [phpmetrics.xml](https://edgedesigncz.github.io/phpqa/report/phpmetrics.xml) | [](https://github.com/phpmetrics/PhpMetrics#usage) |
parallel-lint | [parallel-lint.html](https://edgedesigncz.github.io/phpqa/report/parallel-lint.html) | [](https://github.com/JakubOnderka/PHP-Parallel-Lint#example-output) |
phpstan | [phpstan.html](https://edgedesigncz.github.io/phpqa/report/phpstan.html), [phpstan-phpqa.neon](https://edgedesigncz.github.io/phpqa/report/phpstan-phpqa.neon) | [](https://edgedesigncz.github.io/phpqa/report/phpstan.html), [phpstan-phpqa.neon](https://edgedesigncz.github.io/phpqa/report/phpstan-phpqa.neon "Generated configuration is saved in current working directory") |

## Exit code

Expand All @@ -152,7 +156,7 @@ or [Circle CI](https://circleci.com/docs/manually/#overview) build should fail w
Define number of allowed errors for each tools and watch the build:

```bash
phpqa --report --tools phpcs:0,phpmd:0,phpcpd:0,parallel-lint:0,phpmetrics,phploc,pdepend
phpqa --report --tools phpcs:0,phpmd:0,phpcpd:0,parallel-lint:0,phpstan:0,phpmetrics,phploc,pdepend
```

**File mode**
Expand All @@ -174,6 +178,7 @@ Tool | Settings | Default Value | Your value
[phpcs](https://pear.php.net/manual/en/package.php.php-codesniffer.usage.php#package.php.php-codesniffer.usage.coding-standard) | Coding standard | PSR2 | Name of existing standard (`PEAR`, `PHPCS`, `PSR1`, `PSR2`, `Squiz`, `Zend`), or path to your coding standard
[phpmd](http://phpmd.org/documentation/creating-a-ruleset.html) | Ruleset | [Edgedesign's standard](/app/phpmd.xml) | Path to ruleset
[phpcpd](https://github.com/sebastianbergmann/phpcpd/blob/de9056615da6c1230f3294384055fa7d722c38fa/src/CLI/Command.php#L136) | Minimum number of lines/tokens for copy-paste detection | 5 lines, 70 tokens |
[phpstan](https://github.com/phpstan/phpstan#configuration) | Level, config file | Level 0, `%currentWorkingDirectory%/phpstan.neon` | Take a look at [phpqa config in tests/.travis](/tests/.travis/) |

`.phpqa.yml` is automatically detected in current working directory, but you can specify
directory via option:
Expand Down
4 changes: 2 additions & 2 deletions app/report/cli.html.twig
@@ -1,5 +1,5 @@
<h1>Parallel Lint</h1>
<pre id="cli">{{ process.getOutput() }}{{ process.getErrorOutput() }}</pre>
<h1>{{ tool }}</h1>
<pre id="cli">{{ process.getOutput() }}</pre>

<style>
html, body {
Expand Down
2 changes: 1 addition & 1 deletion bin/ci.sh
@@ -1,3 +1,3 @@
#!/bin/sh

./phpqa --verbose --report --tools phpcs:0,phpmd:0,phpcpd:0,parallel-lint:0,phpmetrics,phploc,pdepend
./phpqa --verbose --report --config tests/.travis --tools phpcs:0,phpmd:0,phpcpd:0,parallel-lint:0,phpstan:0,phpmetrics,phploc,pdepend
1 change: 1 addition & 0 deletions bin/deploy-report.sh
Expand Up @@ -29,6 +29,7 @@ copy_artifacts() {
cp -R build/*.html $repository/report
cp -R build/*.svg $repository/report
cp -R build/*.xml $repository/report
cp -R build/*.neon $repository/report
}

publish_changes() {
Expand Down
4 changes: 2 additions & 2 deletions bin/suggested-tools.sh
Expand Up @@ -9,8 +9,8 @@ mode="$1"
if [ $mode = "install" ]
then
echo "Installing suggested tools"
composer require jakub-onderka/php-parallel-lint jakub-onderka/php-console-highlighter
composer require jakub-onderka/php-parallel-lint jakub-onderka/php-console-highlighter phpstan/phpstan
else
echo "Removing suggested tools"
composer remove jakub-onderka/php-parallel-lint jakub-onderka/php-console-highlighter
composer remove jakub-onderka/php-parallel-lint jakub-onderka/php-console-highlighter phpstan/phpstan
fi
3 changes: 2 additions & 1 deletion composer.json
Expand Up @@ -34,7 +34,8 @@
},
"suggest": {
"jakub-onderka/php-parallel-lint": "Check PHP syntax",
"jakub-onderka/php-console-highlighter": "Colored output in parallel-lint"
"jakub-onderka/php-console-highlighter": "Colored output in parallel-lint",
"phpstan/phpstan": "PHP Static Analysis Tool - discover bugs in your code without running it!"
},
"require-dev": {
"phpunit/phpunit": "~4.8",
Expand Down
56 changes: 55 additions & 1 deletion src/CodeAnalysisTasks.php
Expand Up @@ -44,6 +44,12 @@ trait CodeAnalysisTasks
'hasOnlyConsoleOutput' => true,
'composer' => 'jakub-onderka/php-parallel-lint',
),
'phpstan' => array(
'optionSeparator' => ' ',
'internalClass' => 'PHPStan\Analyser\Analyser',
'hasOnlyConsoleOutput' => true,
'composer' => 'phpstan/phpstan',
),
);
/** @var Options */
private $options;
Expand Down Expand Up @@ -256,14 +262,62 @@ private function parallellint()
);
}

private function phpstan()
{
$createAbsolutePaths = function (array $relativeDirs) {
return array_values(array_filter(array_map(
function ($relativeDir) {
return '%currentWorkingDirectory%/' . trim($relativeDir, '"');
},
$relativeDirs
)));
};

$defaultConfig = $this->config->path('phpstan.standard') ?: (getcwd() . '/phpstan.neon');
if (file_exists($defaultConfig)) {
$params = \Nette\Neon\Neon::decode(file_get_contents($defaultConfig))['parameters'] + [
'excludes_analyse' => []
];
} else {
$params = [
'autoload_directories' => $createAbsolutePaths($this->options->getAnalyzedDirs()),
'excludes_analyse' => [],
];
}

$params['excludes_analyse'] = array_merge(
$params['excludes_analyse'],
$createAbsolutePaths($this->options->ignore->phpstan())
);

$neonDir = $this->options->isSavedToFiles ? $this->options->rawFile('') : getcwd();
$neonFile = "{$neonDir}/phpstan-phpqa.neon";
file_put_contents(
$neonFile,
"# Configuration generated in phpqa\n" .
\Nette\Neon\Neon::encode(['parameters' => $params])
);

return array(
'analyze',
'ansi' => '',
'level' => $this->config->value('phpstan.level'),
'configuration' => $neonFile,
$this->options->getAnalyzedDirs(' '),
);
}

private function buildHtmlReport()
{
foreach ($this->usedTools as $tool) {
$tool->htmlReport = $this->options->rawFile("{$tool}.html");
if ($tool->hasOnlyConsoleOutput) {
twigToHtml(
'cli.html.twig',
array('process' => $tool->process),
array(
'tool' => (string) $tool,
'process' => $tool->process
),
$this->options->rawFile("{$tool}.html")
);
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/Config.php
Expand Up @@ -56,7 +56,7 @@ private function get($path, $extractor)
{
foreach ($this->configs as $dir => $config) {
$value = $this->findInConfig($config, $path);
if ($value) {
if ($value !== null) {
return $extractor($value, $dir);
}
}
Expand Down
5 changes: 5 additions & 0 deletions src/IgnoredPaths.php
Expand Up @@ -50,6 +50,11 @@ public function parallelLint()
return $this->ignore(' --exclude ', ' --exclude ', '');
}

public function phpstan()
{
return $this->ignoreBoth;
}

private function ignore($before, $dirSeparator, $after, $fileSeparator = null)
{
if ($fileSeparator) {
Expand Down
2 changes: 1 addition & 1 deletion src/RunningTool.php
Expand Up @@ -43,7 +43,7 @@ public function isInstalled()

public function buildOption($arg, $value)
{
if ($value) {
if ($value || $value === 0) {
return "--{$arg}{$this->optionSeparator}{$value}";
} else {
return "--{$arg}";
Expand Down
4 changes: 4 additions & 0 deletions tests/.travis/.phpqa.yml
@@ -0,0 +1,4 @@
phpstan:
level: 5
# https://github.com/phpstan/phpstan#configuration
standard: phpstan.neon
12 changes: 12 additions & 0 deletions tests/.travis/phpstan.neon
@@ -0,0 +1,12 @@
# Required config for analyzing root directory (RobotLoader. throws Nette\InvalidStateException: Ambiguous class)
# phpqa --report --output cli --tools phpstan --analyzedDirs ./ --ignoredDirs=vendor

parameters:
bootstrap: %currentWorkingDirectory%/vendor/autoload.php
autoload_directories:
- %currentWorkingDirectory%/tests
autoload_files:
- %currentWorkingDirectory%/RoboFile.php
ignoreErrors:
- '#Call to an undefined method Prophecy\\Prophecy\\ObjectProphecy::[a-zA-Z0-9_]+\(\)#'
- '#Access to an undefined property DOMDocument::\$documentElement.#'
1 change: 1 addition & 0 deletions tests/Config/ConfigTest.php
Expand Up @@ -11,6 +11,7 @@ public function testLoadDefaultConfig()
assertThat($config->value('phpcpd.minTokens'), is(greaterThan(0)));
assertThat($config->value('phpcs.standard'), is(nonEmptyString()));
assertThat($config->path('phpmd.standard'), is(nonEmptyString()));
assertThat($config->value('phpstan.level'), identicalTo(0));
}

public function testBuildAbsolutePath()
Expand Down
1 change: 1 addition & 0 deletions tests/RunningToolTest.php
Expand Up @@ -11,6 +11,7 @@ public function testBuildOptionWithDefinedSeparator()
$tool = new RunningTool('tool', ['optionSeparator' => ' ']);
assertThat($tool->buildOption('option', ''), is('--option'));
assertThat($tool->buildOption('option', 'value'), is('--option value'));
assertThat($tool->buildOption('option', 0), is('--option 0'));
}

public function testMarkSuccessWhenXPathIsNotDefined()
Expand Down

0 comments on commit e116b09

Please sign in to comment.