Skip to content

Commit

Permalink
Review Extract command (#667)
Browse files Browse the repository at this point in the history
Extracted from #646
  • Loading branch information
theofidry committed Jun 20, 2022
1 parent 1c69ca3 commit f97c4e5
Showing 1 changed file with 78 additions and 34 deletions.
112 changes: 78 additions & 34 deletions src/Console/Command/Extract.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,64 +59,108 @@ protected function configure(): void

protected function executeCommand(IO $io): int
{
$input = $io->getInput();
$filePath = self::getPharFilePath($io);
$outputDir = $io->getInput()->getArgument(self::OUTPUT_ARG);

$file = realpath($input->getArgument(self::PHAR_ARG));
if (null === $filePath) {
return 1;
}

if (false === $file) {
$io->error(
sprintf(
'The file "%s" could not be found.',
$input->getArgument(self::PHAR_ARG),
),
);
[$box, $cleanUpTmpPhar] = $this->getBox($filePath, $io);

if (null === $box) {
return 1;
}

$tmpFile = create_temporary_phar($file);
$restoreLimit = bump_open_file_descriptor_limit(count($box), $io);

$cleanUp = static function () use ($cleanUpTmpPhar, $restoreLimit): void {
$cleanUpTmpPhar();
$restoreLimit();
};

try {
$box = Box::create($tmpFile);
self::dumpPhar($outputDir, $box, $cleanUp);
} catch (RuntimeException $exception) {
$io->error($exception->getMessage());

return 1;
}

return 0;
}

private static function getPharFilePath(IO $io): ?string
{
$filePathArg = $io->getInput()->getArgument(self::PHAR_ARG);
$filePath = realpath((string) $filePathArg);

if (false !== $filePath) {
return $filePath;
}

$io->error(
sprintf(
'The file "%s" could not be found.',
$filePathArg,
),
);

return null;
}

/**
* @return array{Box, callable(): void}|array{null, null}
*/
private function getBox(string $filePath, IO $io): ?array
{
$tmpFile = create_temporary_phar($filePath);
$cleanUp = static fn () => remove($tmpFile);

try {
return [
Box::create($tmpFile),
$cleanUp,
];
} catch (Throwable $throwable) {
if ($io->isDebug()) {
throw new ConsoleRuntimeException(
'The given file is not a valid PHAR',
0,
$throwable,
);
}
// Continue
}

$io->error('The given file is not a valid PHAR');
if ($io->isDebug()) {
$cleanUp();

return 1;
throw new ConsoleRuntimeException(
'The given file is not a valid PHAR',
0,
$throwable,
);
}

$restoreLimit = bump_open_file_descriptor_limit(count($box), $io);
$io->error('The given file is not a valid PHAR');

$outputDir = $input->getArgument(self::OUTPUT_ARG);
$cleanUp();

return [null, null];
}

/**
* @param callable(): void $cleanUp
*/
private static function dumpPhar(string $outputDir, Box $box, callable $cleanUp): void
{
try {
remove($outputDir);

$rootLength = strlen('phar://'.$box->getPhar()->getPath()) + 1;

foreach (new RecursiveIteratorIterator($box->getPhar()) as $file) {
foreach (new RecursiveIteratorIterator($box->getPhar()) as $filePath) {
dump_file(
$outputDir.'/'.substr($file->getPathname(), $rootLength),
(string) $file->getContent(),
$outputDir.'/'.substr($filePath->getPathname(), $rootLength),
(string) $filePath->getContent(),
);
}
} catch (RuntimeException $exception) {
$io->error($exception->getMessage());

return 1;
} finally {
$restoreLimit();

remove($tmpFile);
$cleanUp();
}

return 0;
}
}

0 comments on commit f97c4e5

Please sign in to comment.