Skip to content

Commit

Permalink
FRW-838 Fixed allowed memory size. (#322)
Browse files Browse the repository at this point in the history
* FRW-838 Fixed allowed memory size

* FRW-838 Fixed CI

* SUPESC-838 Optimization for phpstan

* SUPESC-838 Added config, adjustments

* SUPESC-838 Renamed the var

* SUPESC-838 Renamed the var
  • Loading branch information
olhalivitchuk authored Jul 30, 2024
1 parent 20ba799 commit cb51ac1
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 31 deletions.
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"http-interop/http-factory-guzzle": "^1.2",
"knplabs/github-api": "^3.13",
"m4tthumphrey/php-gitlab-api": "^11.12",
"nette/neon": "^3.4",
"nikic/php-parser": "4.15.*",
"phpstan/phpstan": "^1.10",
"spryker-sdk/azure-php-client": "^0.2.1",
Expand Down
70 changes: 69 additions & 1 deletion composer.lock

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

4 changes: 4 additions & 0 deletions config/DynamicEvaluator/checker_phpstan.neon
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
parameters:
level: 3 # for performance reasons
parallel:
maximumNumberOfProcesses: 2
paths:
- %currentWorkingDirectory%/src
excludePaths:
Expand All @@ -8,3 +10,5 @@ parameters:
- %currentWorkingDirectory%/src/Orm/*
- %currentWorkingDirectory%/src/Pyz/Zed/*/Persistence/*Repository.php
- %currentWorkingDirectory%/src/Pyz/Zed/*/Persistence/*QueryContainer.php
- %currentWorkingDirectory%/src/**/Spy*.php
- %currentWorkingDirectory%/src/**/*Transfer.php
16 changes: 16 additions & 0 deletions config/DynamicEvaluator/checker_phpstan_include_project.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
includes:
- %currentWorkingDirectory%/phpstan.neon
parameters:
level: 3 # for performance reasons
parallel:
maximumNumberOfProcesses: 2
paths:
- %currentWorkingDirectory%/src
excludePaths:
analyse:
- %currentWorkingDirectory%/src/Generated/*
- %currentWorkingDirectory%/src/Orm/*
- %currentWorkingDirectory%/src/**/*Repository.php
- %currentWorkingDirectory%/src/**/*QueryContainer.php
- %currentWorkingDirectory%/src/**/Spy*.php
- %currentWorkingDirectory%/src/**/*Transfer.php
2 changes: 2 additions & 0 deletions config/DynamicEvaluator/services.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
parameters:
checker_broken_php_files_executable_path: '%kernel.project_dir%/vendor/bin/phpstan'
checker_broken_php_files_config_executable_path: '%upgrader.root_dir%/config/DynamicEvaluator/checker_phpstan.neon'
checker_broken_php_files_with_project_config_executable_path: '%upgrader.root_dir%/config/DynamicEvaluator/checker_phpstan_include_project.neon'

services:
_defaults:
Expand All @@ -17,6 +18,7 @@ services:
DynamicEvaluator\Application\Checker\BrokenPhpFilesChecker\FileErrorsFetcher\FileErrorsFetcher:
arguments:
- '%checker_broken_php_files_config_executable_path%'
- '%checker_broken_php_files_with_project_config_executable_path%'
- '%checker_broken_php_files_executable_path%'
- '@SprykerSdk\Utils\Infrastructure\Service\ProcessRunnerService'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,14 @@
use DynamicEvaluator\Application\Checker\BrokenPhpFilesChecker\Dto\FileErrorDto;
use Exception;
use InvalidArgumentException;
use Nette\Neon\Neon;
use Psr\Log\LoggerInterface;
use RuntimeException;
use SprykerSdk\Utils\Infrastructure\Service\ProcessRunnerServiceInterface;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Process\Exception\ProcessTimedOutException;
use Symfony\Component\Process\Process;
use Upgrade\Infrastructure\Configuration\ConfigurationProvider;

class FileErrorsFetcher implements FileErrorsFetcherInterface
{
Expand Down Expand Up @@ -45,6 +49,11 @@ class FileErrorsFetcher implements FileErrorsFetcherInterface
*/
protected LoggerInterface $logger;

/**
* @var \Upgrade\Infrastructure\Configuration\ConfigurationProvider
*/
protected ConfigurationProvider $configurationProvider;

/**
* @var string
*/
Expand All @@ -56,6 +65,7 @@ class FileErrorsFetcher implements FileErrorsFetcherInterface
* @param \SprykerSdk\Utils\Infrastructure\Service\ProcessRunnerServiceInterface $processRunnerService
* @param \DynamicEvaluator\Application\Checker\BrokenPhpFilesChecker\Baseline\BaselineStorageInterface $baselineStorage
* @param \Psr\Log\LoggerInterface $logger
* @param \Upgrade\Infrastructure\Configuration\ConfigurationProvider $configurationProvider
* @param string $phpstanNeonFileName
*/
public function __construct(
Expand All @@ -64,13 +74,15 @@ public function __construct(
ProcessRunnerServiceInterface $processRunnerService,
BaselineStorageInterface $baselineStorage,
LoggerInterface $logger,
ConfigurationProvider $configurationProvider,
string $phpstanNeonFileName = 'phpstan.neon'
) {
$this->executableConfig = $executableConfig;
$this->executable = $executable;
$this->processRunnerService = $processRunnerService;
$this->baselineStorage = $baselineStorage;
$this->logger = $logger;
$this->configurationProvider = $configurationProvider;
$this->phpstanNeonFileName = $phpstanNeonFileName;
}

Expand All @@ -83,6 +95,10 @@ public function fetchProjectFileErrorsAndSaveInBaseLine(array $dirs = []): array
{
$fileErrors = [];

if ($dirs === [] && $this->configurationProvider->isPhpStanOptimizationRun() === true) {
$dirs = $this->getDirectories($dirs);
}

try {
$errors = $this->fetchErrorsArray($dirs);
} catch (ProcessTimedOutException $e) {
Expand Down Expand Up @@ -150,14 +166,51 @@ protected function fetchNewFileError(string $file, array $message): ?FileErrorDt
}

/**
* @param array<string> $dirs
* @return void
*/
public function reset(): void
{
$this->processRunnerService->mustRun([
$this->executable,
'clear-result-cache',
'-c',
$this->executableConfig,
]);

$this->baselineStorage->clear();
}

/**
* @param array<mixed> $data
* @param string $key
* @param bool $isArray
*
* @throws \RuntimeException
* @throws \InvalidArgumentException
*
* @return void
*/
protected function assertArrayKeyExists(array $data, string $key, bool $isArray = false): void
{
if (!array_key_exists($key, $data) || ($isArray && !is_array($data[$key]))) {
throw new InvalidArgumentException(sprintf(
'Unable to find %s key or it\'s not an array in %s. Tooling export format is changes.',
$key,
substr(json_encode($data, \JSON_THROW_ON_ERROR), 0, 100),
));
}
}

/**
* @param array<string> $dirs
*
* @return array<mixed>
*/
protected function fetchErrorsArray(array $dirs): array
{
if ($dirs !== [] && $this->configurationProvider->isPhpStanOptimizationRun() === true) {
return $this->fetchErrorsArrayPerDirectory($dirs);
}

$process = $this->processRunnerService->run([
$this->executable,
'analyse',
Expand All @@ -168,6 +221,44 @@ protected function fetchErrorsArray(array $dirs): array
...$dirs,
]);

return $this->runProcess($process);
}

/**
* @param array<string> $dirs
*
* @return array<string, mixed>
*/
protected function fetchErrorsArrayPerDirectory(array $dirs): array
{
$result = [];

foreach ($dirs as $dir) {
$process = $this->processRunnerService->run([
$this->executable,
'analyse',
'-c',
$this->executableConfig,
'--error-format',
'prettyJson',
$dir,
]);

$result = array_merge_recursive($result, $this->runProcess($process));
}

return $result;
}

/**
* @param \Symfony\Component\Process\Process $process
*
* @throws \RuntimeException
*
* @return array<string, mixed>
*/
protected function runProcess(Process $process): array
{
try {
$result = json_decode($process->getOutput(), true, 512, \JSON_THROW_ON_ERROR);
} catch (Exception $e) {
Expand All @@ -187,37 +278,66 @@ protected function fetchErrorsArray(array $dirs): array
}

/**
* @return void
* @param string $neonFilePath
*
* @return array<string, mixed>
*/
public function reset(): void
protected function parseNeonFile(string $neonFilePath): array
{
$this->processRunnerService->mustRun([
$this->executable,
'clear-result-cache',
'-c',
$this->executableConfig,
]);
if (file_exists($neonFilePath) === false) {
return [];
}

$this->baselineStorage->clear();
$neonContent = file_get_contents($neonFilePath);

if ($neonContent === false) {
return [];
}

return Neon::decode($neonContent);
}

/**
* @param array<mixed> $data
* @param string $key
* @param bool $isArray
* @param array<string> $dirs
*
* @throws \InvalidArgumentException
* @return array<string>
*/
protected function getDirectories(array $dirs = []): array
{
$config = $this->parseNeonFile($this->executableConfig);

if ($config === []) {
return $dirs;
}

foreach ($config['parameters']['paths'] as $basePath) {
$basePath = str_replace('%currentWorkingDirectory%', getcwd() ?: '', $basePath);
$dirs = array_merge($dirs, $this->findDirectories($basePath, $config['parameters']['excludePaths']['analyse']));
}

return $dirs;
}

/**
* @param string $baseDir
* @param array<string> $excludePaths
*
* @return void
* @return array<string>
*/
protected function assertArrayKeyExists(array $data, string $key, bool $isArray = false): void
protected function findDirectories(string $baseDir, array $excludePaths): array
{
if (!array_key_exists($key, $data) || ($isArray && !is_array($data[$key]))) {
throw new InvalidArgumentException(sprintf(
'Unable to find %s key or it\'s not an array in %s. Tooling export format is changes.',
$key,
substr(json_encode($data, \JSON_THROW_ON_ERROR), 0, 100),
));
$finder = new Finder();
$finder->directories()->in($baseDir)->depth('== 1');

foreach ($excludePaths as $excludePath) {
$finder->notPath($excludePath);
}

$dirs = [];
foreach ($finder as $dir) {
$dirs[] = $dir->getRealPath();
}

return $dirs;
}
}
Loading

0 comments on commit cb51ac1

Please sign in to comment.