Skip to content

Commit

Permalink
FRW-838 Fixed allowed memory size
Browse files Browse the repository at this point in the history
  • Loading branch information
olhalivitchuk committed Jul 22, 2024
1 parent a728660 commit 2482dba
Show file tree
Hide file tree
Showing 4 changed files with 243 additions and 24 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.

Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
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;

class FileErrorsFetcher implements FileErrorsFetcherInterface
{
Expand Down Expand Up @@ -83,6 +86,10 @@ public function fetchProjectFileErrorsAndSaveInBaseLine(array $dirs = []): array
{
$fileErrors = [];

if ($dirs === []) {
$dirs = $this->getDirectories($dirs);
}

try {
$errors = $this->fetchErrorsArray($dirs);
} catch (ProcessTimedOutException $e) {
Expand Down Expand Up @@ -150,14 +157,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 !== []) {
return $this->fetchErrorsArrayPerDirectory($dirs);
}

$process = $this->processRunnerService->run([
$this->executable,
'analyse',
Expand All @@ -168,6 +212,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 +269,62 @@ 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);

return Neon::decode($neonContent);

Check failure on line 284 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.0)

Parameter #1 $input of static method Nette\Neon\Neon::decode() expects string, string|false given.

Check failure on line 284 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.2)

Parameter #1 $input of static method Nette\Neon\Neon::decode() expects string, string|false given.

Check failure on line 284 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.3)

Parameter #1 $input of static method Nette\Neon\Neon::decode() expects string, string|false given.
}

/**
* @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);

Check failure on line 301 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.0)

Parameter #2 $replace of function str_replace expects array|string, string|false given.

Check failure on line 301 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.2)

Parameter #2 $replace of function str_replace expects array|string, string|false given.

Check failure on line 301 in src/DynamicEvaluator/Application/Checker/BrokenPhpFilesChecker/FileErrorsFetcher/FileErrorsFetcher.php

View workflow job for this annotation

GitHub Actions / validation (8.3)

Parameter #2 $replace of function str_replace expects array|string, string|false given.
$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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -243,4 +243,47 @@ public function testRunProcessWithException(): void
ProcessRunnerServiceInterface::DEFAULT_PROCESS_TIMEOUT,
), $fileErrors[0]->getMessage());
}

/**
* @return void
*/
public function testFetchProjectFileErrorsExecutesPerDir(): void
{
// Arrange
$returnValues = [
json_encode(['files' => ['src/someClass.php' => ['messages' => [['line' => 1, 'message' => 'test message']]]]], \JSON_THROW_ON_ERROR),
json_encode(['files' => ['src/someClass2.php' => ['messages' => [['line' => 1, 'message' => 'test message2']]]]], \JSON_THROW_ON_ERROR),
];

$process = $this->createMock(Process::class);
$process->expects($this->exactly(2))
->method('getOutput')
->willReturnOnConsecutiveCalls(...$returnValues);

/** @var \SprykerSdk\Utils\Infrastructure\Service\ProcessRunnerServiceInterface&\PHPUnit\Framework\MockObject\MockObject $processRunnerServiceMock */
$processRunnerServiceMock = $this->createMock(ProcessRunnerServiceInterface::class);
$processRunnerServiceMock->expects($this->exactly(2))
->method('run')
->willReturn($process);

$fileErrorsFetcher = new FileErrorsFetcher(
'config/DynamicEvaluator/checker_phpstan.neon',
'',
$processRunnerServiceMock,
new BaselineStorage(),
$this->createLoggerMock(),
);

// Act
$fileErrors = $fileErrorsFetcher->fetchProjectFileErrorsAndSaveInBaseLine(['dir1', 'dir2']);

// Assert
$this->assertCount(2, $fileErrors);
$this->assertSame('src/someClass.php', $fileErrors[0]->getFilename());
$this->assertSame(1, $fileErrors[0]->getLine());
$this->assertSame('test message', $fileErrors[0]->getMessage());
$this->assertSame('src/someClass2.php', $fileErrors[1]->getFilename());
$this->assertSame(1, $fileErrors[1]->getLine());
$this->assertSame('test message2', $fileErrors[1]->getMessage());
}
}

0 comments on commit 2482dba

Please sign in to comment.