From c4be6deb9aabf1b20987605565c39b05c49e8de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20FIDRY?= Date: Wed, 30 May 2018 18:06:37 +0200 Subject: [PATCH] Fix verify command on PHAR files without the .phar extension (#244) - Fix some typos - Ensures the `verify` command works on a PHAR which does not have the `.phar` extension - Throws the throwable catch in debug mode instead of verbose for the `verify` command --- Makefile | 20 +++++----- fixtures/verify/simple-phar | Bin 0 -> 6765 bytes src/Configuration.php | 8 +++- src/Console/Command/Compile.php | 6 +-- .../Command/CreateTemporaryPharFile.php | 35 ++++++++++++++++++ src/Console/Command/Info.php | 18 ++++----- src/Console/Command/Verify.php | 13 ++++++- tests/Console/Command/VerifyTest.php | 18 ++++++++- 8 files changed, 89 insertions(+), 29 deletions(-) create mode 100644 fixtures/verify/simple-phar create mode 100644 src/Console/Command/CreateTemporaryPharFile.php diff --git a/Makefile b/Makefile index 3fd182ded..2731fd29c 100644 --- a/Makefile +++ b/Makefile @@ -13,19 +13,19 @@ help: #--------------------------------------------------------------------------- .PHONY: clean -clean: ## Clean all created artifacts +clean: ## Cleans all created artifacts clean: git clean --exclude=.idea/ -ffdx .PHONY: cs PHPCSFIXER=vendor-bin/php-cs-fixer/vendor/bin/php-cs-fixer -cs: ## Fix CS +cs: ## Fixes CS cs: $(PHPCSFIXER) $(PHPNOGC) $(PHPCSFIXER) fix $(PHPNOGC) $(PHPCSFIXER) fix --config .php_cs_53.dist .PHONY: compile -compile: ## Compile the application into the PHAR +compile: ## Compiles the application into the PHAR compile: box cp -f box bin/box.phar @@ -43,38 +43,38 @@ dump-requirement-checker: requirement-checker requirement-checker/vendor #--------------------------------------------------------------------------- .PHONY: test -test: ## Run all the tests +test: ## Runs all the tests test: tu e2e .PHONY: tu -tu: ## Run the unit tests +tu: ## Runs the unit tests tu: tu_requirement_checker tu_box .PHONY: tu_box -tu_box: ## Run the unit tests +tu_box: ## Runs the unit tests TU_BOX_DEPS = bin/phpunit fixtures/default_stub.php .requirement-checker fixtures/composer-dump/dir001/vendor tu_box: $(TU_BOX_DEPS) $(PHPNOGC) bin/phpunit .PHONY: tu_box_phar_readonly -tu_box_phar_readonly: ## Runs the unit tests with the setting `phar.readonly` to `On` +tu_box_phar_readonly: ## Runs the unit tests with the setting `phar.readonly` to `On` tu_box_phar_readonly: $(TU_BOX_DEPS) php -d zend.enable_gc=0 -d phar.readonly=1 bin/phpunit .PHONY: tu_requirement_checker -tu_requirement_checker: ## Run the unit tests +tu_requirement_checker: ## Runs the unit tests tu_requirement_checker: requirement-checker/bin/phpunit requirement-checker/tests/DisplayNormalizer.php requirement-checker/actual_terminal_diff cd requirement-checker && $(PHPNOGC) bin/phpunit diff requirement-checker/expected_terminal_diff requirement-checker/actual_terminal_diff .PHONY: tc -tc: ## Run the unit tests with code coverage +tc: ## Runs the unit tests with code coverage tc: bin/phpunit phpdbg -qrr -d zend.enable_gc=0 bin/phpunit --coverage-html=dist/coverage --coverage-text .PHONY: tm -tm: ## Run Infection +tm: ## Runs Infection tm: $(TU_BOX_DEPS) $(PHPNOGC) bin/infection diff --git a/fixtures/verify/simple-phar b/fixtures/verify/simple-phar new file mode 100644 index 0000000000000000000000000000000000000000..a8bfeb3d49ff52a2e69e266cbda1893e833709e0 GIT binary patch literal 6765 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, $main, $checkRequirements, $logger); - $box->getPhar()->setStub($stub->generate()); + $box->getPhar()->setStub($stub); return; } @@ -729,7 +729,7 @@ private function correctPermissions(string $path, Configuration $config, BuildLo } } - private function createStub(Configuration $config, ?string $main, bool $checkRequirements, BuildLogger $logger): StubGenerator + private function createStub(Configuration $config, ?string $main, bool $checkRequirements, BuildLogger $logger): string { $stub = StubGenerator::create() ->alias($config->getAlias()) @@ -783,7 +783,7 @@ private function createStub(Configuration $config, ?string $main, bool $checkReq $stub->banner($banner); } - return $stub; + return $stub->generate(); } private function logMap(MapFile $fileMapper, BuildLogger $logger): void diff --git a/src/Console/Command/CreateTemporaryPharFile.php b/src/Console/Command/CreateTemporaryPharFile.php new file mode 100644 index 000000000..903bc3740 --- /dev/null +++ b/src/Console/Command/CreateTemporaryPharFile.php @@ -0,0 +1,35 @@ + + * Théo Fidry + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace KevinGH\Box\Console\Command; + +use DateTimeImmutable; +use function KevinGH\Box\FileSystem\copy; + +/** + * @private + */ +trait CreateTemporaryPharFile +{ + final private function createTemporaryPhar(string $file): string + { + if ('' === pathinfo($file, PATHINFO_EXTENSION)) { + copy($file, $tmpFile = sys_get_temp_dir().'/'.(new DateTimeImmutable())->getTimestamp().$file.'.phar'); + + return $tmpFile; + } + + return $file; + } +} diff --git a/src/Console/Command/Info.php b/src/Console/Command/Info.php index 5e9f267a5..325b2a988 100644 --- a/src/Console/Command/Info.php +++ b/src/Console/Command/Info.php @@ -15,7 +15,6 @@ namespace KevinGH\Box\Console\Command; use Assert\Assertion; -use DateTimeImmutable; use DirectoryIterator; use Phar; use PharData; @@ -38,7 +37,6 @@ use function filesize; use function is_array; use function iterator_to_array; -use function KevinGH\Box\FileSystem\copy; use function KevinGH\Box\FileSystem\remove; use function KevinGH\Box\format_size; use function key; @@ -46,7 +44,6 @@ use function sprintf; use function str_repeat; use function str_replace; -use function sys_get_temp_dir; use function var_export; /** @@ -54,6 +51,8 @@ */ final class Info extends Command { + use CreateTemporaryPharFile; + private const PHAR_ARG = 'phar'; private const LIST_OPT = 'list'; private const METADATA_OPT = 'metadata'; @@ -162,18 +161,15 @@ public function execute(InputInterface $input, OutputInterface $output): int return 1; } - if ('' === pathinfo($file, PATHINFO_EXTENSION)) { - // It is likely to be a PHAR without extension - copy($file, $tmpFile = sys_get_temp_dir().'/'.(new DateTimeImmutable())->getTimestamp().$file.'.phar'); + $tmpFile = $this->createTemporaryPhar($file); - try { - return $this->showInfo($tmpFile, $file, $input, $output, $io); - } finally { + try { + return $this->showInfo($tmpFile, $file, $input, $output, $io); + } finally { + if ($file !== $tmpFile) { remove($tmpFile); } } - - return $this->showInfo($file, $file, $input, $output, $io); } public function showInfo(string $file, string $originalFile, InputInterface $input, OutputInterface $output, SymfonyStyle $io): int diff --git a/src/Console/Command/Verify.php b/src/Console/Command/Verify.php index cfb9eeb81..06615892c 100644 --- a/src/Console/Command/Verify.php +++ b/src/Console/Command/Verify.php @@ -15,6 +15,7 @@ namespace KevinGH\Box\Console\Command; use Assert\Assertion; +use function KevinGH\Box\FileSystem\remove; use Phar; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -30,6 +31,8 @@ */ final class Verify extends Command { + use CreateTemporaryPharFile; + private const PHAR_ARG = 'phar'; private const VERBOSITY_LEVEL = OutputInterface::VERBOSITY_VERBOSE; @@ -83,8 +86,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int self::VERBOSITY_LEVEL ); + $tmpPharPath = $this->createTemporaryPhar($pharPath); + try { - $phar = new Phar($pharPath); + $phar = new Phar($tmpPharPath); $verified = true; $signature = $phar->getSignature(); @@ -93,6 +98,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int $verified = false; $signature = null; + } finally { + if ($tmpPharPath !== $pharPath) { + remove($tmpPharPath); + } } if (false === $verified) { @@ -108,7 +117,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ) ); - if (isset($throwable) && $output->isVerbose()) { + if (isset($throwable) && $output->isDebug()) { throw $throwable; } diff --git a/tests/Console/Command/VerifyTest.php b/tests/Console/Command/VerifyTest.php index d7400e6ac..6a038efcc 100644 --- a/tests/Console/Command/VerifyTest.php +++ b/tests/Console/Command/VerifyTest.php @@ -61,6 +61,22 @@ public function test_it_verifies_the_signature_of_the_given_file_using_the_phar_ $expected = <<<'OUTPUT' The PHAR passed verification. +OUTPUT; + + $this->assertSame($expected, $this->commandTester->getDisplay(true)); + $this->assertSame(0, $this->commandTester->getStatusCode()); + } + + public function test_it_can_verify_a_PHAR_which_does_not_have_the_PHAR_extension(): void + { + $this->commandTester->execute([ + 'command' => 'verify', + 'phar' => realpath(self::FIXTURES_DIR.'/simple-phar'), + ]); + + $expected = <<<'OUTPUT' +The PHAR passed verification. + OUTPUT; $this->assertSame($expected, $this->commandTester->getDisplay(true)); @@ -70,7 +86,7 @@ public function test_it_verifies_the_signature_of_the_given_file_using_the_phar_ /** * @dataProvider providePassingPharPaths */ - public function test_it_verifies_the_signature_of_the_given_file_in_verbose_mode(string $pharPath): void + public function test_it_verifies_the_signature_of_the_given_file_in_debug_mode(string $pharPath): void { $signature = (new Phar($pharPath))->getSignature();