Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support phpstan v0.5 #43

Merged
merged 17 commits into from Jan 7, 2017
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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