Skip to content

Commit

Permalink
Error identifiers extractor - work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Jun 12, 2023
1 parent efdf202 commit 11690f6
Show file tree
Hide file tree
Showing 12 changed files with 410 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Expand Up @@ -4,6 +4,7 @@
/CODE_OF_CONDUCT.md export-ignore
/docker export-ignore
/e2e export-ignore
/identifier-extractor export-ignore
/playground-api export-ignore
/playground-runner export-ignore
/website/ export-ignore
Expand Down
40 changes: 40 additions & 0 deletions .github/workflows/build-identifier-extractor.yml
@@ -0,0 +1,40 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions

name: "Build Identifier Extractor"

on:
pull_request:
paths:
- 'identifier-extractor/**'
- '.github/workflows/build-identifier-extractor.yml'
push:
branches:
- "1.11.x"
paths:
- 'identifier-extractor/**'
- '.github/workflows/build-identifier-extractor.yml'

jobs:
build-identifier-extractor:
name: "Build Identifier Extractor"

runs-on: "ubuntu-latest"
timeout-minutes: 60

steps:
- name: "Checkout"
uses: actions/checkout@v3

- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.1"

- name: "Install Identifier Extractor dependencies"
working-directory: "identifier-extractor"
run: "composer install --no-interaction --no-progress"

- name: "PHPStan"
working-directory: "identifier-extractor"
run: ../phpstan
64 changes: 64 additions & 0 deletions .github/workflows/extract-identifiers.yml
@@ -0,0 +1,64 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions

name: "Extract identifiers"

on:
push:
branches:
- "1.11.x"
paths:
- '.github/workflows/extract-identifiers.yml'
- 'identifier-extractor/**'
- '.phar-checksum'

jobs:
extract:
name: "Extract identifiers"
runs-on: "ubuntu-latest"

strategy:
matrix:
repository:
- "https://github.com/phpstan/phpstan-src.git"
- "https://github.com/phpstan/phpstan-strict-rules.git"

steps:
- name: "Checkout"
uses: actions/checkout@v3

- name: "Checkout"
uses: actions/checkout@v3
with:
repository: ${{ matrix.repository }}
path: "identifier-extractor/repo"

- name: "Install PHP"
uses: "shivammathur/setup-php@v2"
with:
coverage: "none"
php-version: "8.1"

- name: "Install extractor dependencies"
working-directory: "identifier-extractor"
run: "composer install --no-interaction --no-progress"

- name: "Repository name"
id: repo-name
run: echo "name=$(basename -s .git "${{ matrix.repository }}")" >> $GITHUB_OUTPUT

- name: "Branch name"
id: branch-name
working-directory: "identifier-extractor/repo"
run: echo "name=$(git branch --show)" >> $GITHUB_OUTPUT

- name: "Extract"
working-directory: "identifier-extractor/repo"
run: ../../phpstan analyse -c ../extractor.neon -a ../vendor/autoload.php > ${{ steps.repo-name.outputs.name }}.json
env:
REPO: ${{ matrix.repository }}
BRANCH: ${{ steps.branch-name.outputs.name }}

- uses: actions/upload-artifact@v3
with:
name: identifiers
path: identifier-extractor/${{ steps.repo-name.outputs.name }}.json
2 changes: 2 additions & 0 deletions identifier-extractor/.gitignore
@@ -0,0 +1,2 @@
/vendor
/repo
11 changes: 11 additions & 0 deletions identifier-extractor/composer.json
@@ -0,0 +1,11 @@
{
"require": {
"php": "^8.1",
"nette/utils": "^4.0"
},
"autoload": {
"psr-4": {
"IdentifierExtractor\\": "src/"
}
}
}
108 changes: 108 additions & 0 deletions identifier-extractor/composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 22 additions & 0 deletions identifier-extractor/extractor.neon
@@ -0,0 +1,22 @@
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

parameters:
customRulesetUsed: true
errorFormat: extractor
paths:
- repo/src

rules:
- IdentifierExtractor\Rule

services:
errorFormatter.extractor:
class: IdentifierExtractor\ErrorFormatter
arguments:
relativePathHelper: @simpleRelativePathHelper

-
class: IdentifierExtractor\RuleErrorBuilderCollector
tags:
- phpstan.collector
7 changes: 7 additions & 0 deletions identifier-extractor/phpstan.neon
@@ -0,0 +1,7 @@
includes:
- phar://phpstan.phar/conf/bleedingEdge.neon

parameters:
level: 8
paths:
- src
52 changes: 52 additions & 0 deletions identifier-extractor/src/ErrorFormatter.php
@@ -0,0 +1,52 @@
<?php declare(strict_types = 1);

namespace IdentifierExtractor;

use Nette\Utils\Json;
use PHPStan\Command\AnalysisResult;
use PHPStan\Command\ErrorFormatter\TableErrorFormatter;
use PHPStan\Command\Output;
use PHPStan\File\RelativePathHelper;

class ErrorFormatter implements \PHPStan\Command\ErrorFormatter\ErrorFormatter
{

public function __construct(private RelativePathHelper $relativePathHelper, private TableErrorFormatter $tableErrorFormatter)
{
}

public function formatErrors(AnalysisResult $analysisResult, Output $output): int
{
if ($analysisResult->hasInternalErrors()) {
return $this->tableErrorFormatter->formatErrors($analysisResult, $output);
}

$json = [];
foreach ($analysisResult->getFileSpecificErrors() as $error) {
if ($error->getIdentifier() === 'ignore.unmatchedLine') {
continue;
}
if ($error->getIdentifier() !== 'phpstanIdentifierExtractor.data') {
return $this->tableErrorFormatter->formatErrors($analysisResult, $output);
}

$metadata = $error->getMetadata();
var_dump($metadata);
$json[] = [
'identifiers' => $metadata['identifiers'],
'class' => $metadata['class'],
'file' => $this->relativePathHelper->getRelativePath($metadata['file'] ?? ''),
'line' => $metadata['line'],
];
}

$output->writeRaw(Json::encode([
'repo' => $_SERVER['REPO'],
'branch' => $_SERVER['BRANCH'],
'data' => $json,
]));

return 0;
}

}
37 changes: 37 additions & 0 deletions identifier-extractor/src/Rule.php
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace IdentifierExtractor;

use PhpParser\Node;
use PHPStan\Analyser\Scope;
use PHPStan\Node\CollectedDataNode;
use PHPStan\Rules\RuleErrorBuilder;

/**
* @implements \PHPStan\Rules\Rule<CollectedDataNode>
*/
class Rule implements \PHPStan\Rules\Rule
{

public function getNodeType(): string
{
return CollectedDataNode::class;
}

public function processNode(Node $node, Scope $scope): array
{
$errors = [];

foreach ($node->get(RuleErrorBuilderCollector::class) as $rows) {
foreach ($rows as $row) {
$errors[] = RuleErrorBuilder::message('Metadata')
->identifier('phpstanIdentifierExtractor.data')
->metadata($row)
->build();
}
}

return $errors;
}

}

0 comments on commit 11690f6

Please sign in to comment.