diff --git a/bin/box b/bin/box index 2b59c6950..df8e361c3 100755 --- a/bin/box +++ b/bin/box @@ -53,7 +53,7 @@ $findPhpScoperFunctions = function () { throw new RuntimeException('Unable to find the PHP-Scoper functions.'); }; -$bootstrap = function () use ($findAutoloader, $findPhpScoperFunctions) { +$bootstrap = function () use ($findAutoloader, $findPhpScoperFunctions): void { require_once $findAutoloader(); require_once $findPhpScoperFunctions(); }; diff --git a/doc/configuration.md b/doc/configuration.md index be49fc73e..543f9dae3 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -206,7 +206,7 @@ The default PHAR stub file can be used but Box also propose a couple of options The stub (`string`|`boolean`) setting is used to specify the location of a stub file or if one should be generated: - `string`: Path to the stub file will be used as is inside the PHAR -- `true`: A new stub will be generated +- `true` (default): A new stub will be generated - `false`: The default stub used by the PHAR class will be used If a custom stub file is provided, none of the other options ([`shebang`][shebang], [`intercept`][intercept] and @@ -239,7 +239,8 @@ The `alias` (`string`) setting is used when generating a new stub to call the [` makes it easier to refer to files in the PHAR and ensure the access to internal files will always work regardless of the location of the PHAR on the file system. -No alias is used by default. +If no alias is provided, a generated unique name will be used for it in order to map the [main file][main]. Note that this +may have undesirable effects if you are using the generated [stub][stub-stub] Example: diff --git a/src/Box.php b/src/Box.php index 3251ec446..b28390a67 100644 --- a/src/Box.php +++ b/src/Box.php @@ -331,7 +331,7 @@ private function processContents(array $files, string $cwd): array $mapFile = $this->mapFile; $placeholders = $this->placeholders; $compactors = $this->compactors; - $bootstrap = $GLOBALS['bootstrap'] ?? function () {}; + $bootstrap = $GLOBALS['bootstrap'] ?? function (): void {}; $processFile = function (string $file) use ($cwd, $basePath, $mapFile, $placeholders, $compactors, $bootstrap): array { chdir($cwd); diff --git a/src/Configuration.php b/src/Configuration.php index 6d20239ce..66f25837d 100644 --- a/src/Configuration.php +++ b/src/Configuration.php @@ -37,6 +37,7 @@ use function KevinGH\Box\FileSystem\longest_common_base_path; use function KevinGH\Box\FileSystem\make_path_absolute; use function KevinGH\Box\FileSystem\make_path_relative; +use function uniqid; final class Configuration { @@ -115,7 +116,7 @@ final class Configuration */ private function __construct( ?string $file, - ?string $alias, + string $alias, string $basePath, array $files, array $binaryFiles, @@ -271,7 +272,7 @@ public static function create(?string $file, stdClass $raw): self ); } - public function getAlias(): ?string + public function getAlias(): string { return $this->alias; } @@ -411,10 +412,10 @@ public function isStubGenerated(): bool return $this->isStubGenerated; } - private static function retrieveAlias(stdClass $raw): ?string + private static function retrieveAlias(stdClass $raw): string { if (false === isset($raw->alias)) { - return null; + return uniqid('box-auto-generated-alias-').'.phar'; } $alias = trim($raw->alias); diff --git a/src/Console/Command/Compile.php b/src/Console/Command/Compile.php index 77fdfcd84..a474f54c9 100644 --- a/src/Console/Command/Compile.php +++ b/src/Console/Command/Compile.php @@ -349,17 +349,15 @@ private function registerStub(Configuration $config, Box $box, string $main, Bui $box->registerStub($stub); } else { - if (null !== $config->getAlias()) { - $aliasWasAdded = $box->getPhar()->setAlias($config->getAlias()); + $aliasWasAdded = $box->getPhar()->setAlias($config->getAlias()); - Assertion::true( - $aliasWasAdded, - sprintf( - 'The alias "%s" is invalid. See Phar::setAlias() documentation for more information.', - $config->getAlias() - ) - ); - } + Assertion::true( + $aliasWasAdded, + sprintf( + 'The alias "%s" is invalid. See Phar::setAlias() documentation for more information.', + $config->getAlias() + ) + ); $box->getPhar()->setDefaultStub($main); diff --git a/src/StubGenerator.php b/src/StubGenerator.php index 4fe5ac8ec..9fb51e5ce 100644 --- a/src/StubGenerator.php +++ b/src/StubGenerator.php @@ -189,7 +189,10 @@ private function generatePharConfigStmt(): ?string } if (null !== $this->index) { - $stub[] = "require 'phar://' . __FILE__ . '/{$this->index}';"; + $stub[] = null === $this->alias + ? "require 'phar://' . __FILE__ . '/{$this->index}';" + : "require 'phar://{$this->alias}/{$this->index}';" + ; } if ([] === $stub) { diff --git a/tests/ConfigurationTest.php b/tests/ConfigurationTest.php index 3c28e83e8..dc874b330 100644 --- a/tests/ConfigurationTest.php +++ b/tests/ConfigurationTest.php @@ -70,10 +70,10 @@ public function test_it_can_be_created_without_a_file(): void $this->assertTrue(true); } - public function test_no_alias_is_registered_by_default(): void + public function test_a_default_alias_is_generted_if_no_alias_is_registered(): void { - $this->assertNull($this->config->getAlias()); - $this->assertNull($this->getNoFileConfig()->getAlias()); + $this->assertRegExp('/^box-auto-generated-alias-[\da-zA-Z]{13}\.phar$/', $this->config->getAlias()); + $this->assertRegExp('/^box-auto-generated-alias-[\da-zA-Z]{13}\.phar$/', $this->getNoFileConfig()->getAlias()); } public function test_the_alias_can_be_configured(): void diff --git a/tests/Console/Command/CompileTest.php b/tests/Console/Command/CompileTest.php index 6107ee0c7..65d1c4d75 100644 --- a/tests/Console/Command/CompileTest.php +++ b/tests/Console/Command/CompileTest.php @@ -29,6 +29,7 @@ use Traversable; use function KevinGH\Box\FileSystem\mirror; use function KevinGH\Box\FileSystem\rename; +use function preg_replace; /** * @covers \KevinGH\Box\Console\Command\Compile @@ -147,7 +148,7 @@ public function test_it_can_build_a_PHAR_file(): void */ Phar::mapPhar('alias-test.phar'); -require 'phar://' . __FILE__ . '/run.php'; +require 'phar://alias-test.phar/run.php'; __HALT_COMPILER(); ?> @@ -332,8 +333,6 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void 'files' => ['test.php'], 'finder' => [['in' => 'one']], 'finder-bin' => [['in' => 'two']], - 'key' => 'private.key', - 'key-pass' => true, 'main' => 'run.php', 'map' => [ ['a/deep/test/directory' => 'sub'], @@ -348,7 +347,6 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void $commandTester = $this->getCommandTester(); - $commandTester->setInputs(['test']); // Set input for the passphrase $commandTester->execute( ['command' => 'compile'], ['interactive' => true] @@ -392,8 +390,6 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void 'rand' => $rand, ) ? No compression -? Signing using a private key -Private key passphrase: ? Setting file permissions to 493 * Done. @@ -413,6 +409,12 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void 'Expected PHAR to be executable' ); + $this->assertSame( + 'Hello, world!', + exec('cp test.phar test; php test'), + 'Expected PHAR can be renamed' + ); + $phar = new Phar('test.phar'); // Check PHAR content @@ -428,7 +430,7 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void */ Phar::mapPhar('alias-test.phar'); -require 'phar://' . __FILE__ . '/other/run.php'; +require 'phar://alias-test.phar/other/run.php'; __HALT_COMPILER(); ?> @@ -459,6 +461,80 @@ public function test_it_can_build_a_PHAR_with_complete_mapping(): void $this->assertSame($expectedFiles, $actualFiles); } + public function test_it_can_build_a_PHAR_with_complete_mapping_without_an_alias(): void + { + mirror(self::FIXTURES_DIR.'/dir000', $this->tmp); + + file_put_contents( + 'box.json', + json_encode( + [ + 'chmod' => '0755', + 'compactors' => [Php::class], + 'directories' => ['a'], + 'files' => ['test.php'], + 'finder' => [['in' => 'one']], + 'finder-bin' => [['in' => 'two']], + 'main' => 'run.php', + 'map' => [ + ['a/deep/test/directory' => 'sub'], + ['' => 'other/'], + ], + 'metadata' => ['rand' => $rand = random_int(0, mt_getrandmax())], + 'output' => 'test.phar', + 'stub' => true, + ] + ) + ); + + $commandTester = $this->getCommandTester(); + + $commandTester->execute( + ['command' => 'compile'], + ['interactive' => true] + ); + + $this->assertSame( + 'Hello, world!', + exec('php test.phar'), + 'Expected PHAR to be executable' + ); + + $this->assertSame( + 'Hello, world!', + exec('cp test.phar test; php test'), + 'Expected PHAR can be renamed' + ); + + $phar = new Phar('test.phar'); + + // Check PHAR content + $actualStub = preg_replace( + '/box-auto-generated-alias-[\da-zA-Z]{13}\.phar/', + 'box-auto-generated-alias-__uniqid__.phar', + $this->normalizeDisplay($phar->getStub()) + ); + + $expectedStub = <<<'PHP' +#!/usr/bin/env php + + +PHP; + + $this->assertSame($expectedStub, $actualStub); + } + public function test_it_can_build_a_PHAR_file_in_verbose_mode(): void { mirror(self::FIXTURES_DIR.'/dir000', $this->tmp); diff --git a/tests/StubGeneratorTest.php b/tests/StubGeneratorTest.php index 04b95112e..0166da5b0 100644 --- a/tests/StubGeneratorTest.php +++ b/tests/StubGeneratorTest.php @@ -218,7 +218,7 @@ public function test_it_can_generate_a_complete_stub(): void Phar::mapPhar('test.phar'); Phar::interceptFileFuncs(); -require 'phar://' . __FILE__ . '/index.php'; +require 'phar://test.phar/index.php'; __HALT_COMPILER(); ?>