From d84dfd23d32a300343458ece7f50ecb180799b44 Mon Sep 17 00:00:00 2001 From: Alexandre Daubois Date: Wed, 20 Nov 2024 14:08:04 +0100 Subject: [PATCH] Add the `--dry-run` option --- src/BinaryFile.php | 11 ++++ src/Building/Build.php | 1 + src/Building/UnixBuild.php | 39 ++++++++++++- src/Building/WindowsBuild.php | 1 + src/Command/BuildCommand.php | 3 + src/Command/CommandHelper.php | 16 ++++++ src/Command/DownloadCommand.php | 1 + src/Command/InfoCommand.php | 1 + src/Command/InstallCommand.php | 3 + .../InstallAndBuildProcess.php | 2 + .../PieComposerRequest.php | 1 + src/Installing/Install.php | 1 + src/Installing/UnixInstall.php | 28 +++++---- src/Installing/WindowsInstall.php | 38 ++++++++++--- test/integration/Building/UnixBuildTest.php | 5 ++ .../ResolveDependencyWithComposerTest.php | 1 + .../Installing/UnixInstallTest.php | 54 ++++++++++++++++++ .../Installing/WindowsInstallTest.php | 57 ++++++++++++++++++- .../InstallAndBuildProcessTest.php | 3 + .../InstalledJsonMetadataTest.php | 2 + .../OverrideWindowsUrlInstallListenerTest.php | 3 + 21 files changed, 247 insertions(+), 24 deletions(-) diff --git a/src/BinaryFile.php b/src/BinaryFile.php index 5461118..e7d94e4 100644 --- a/src/BinaryFile.php +++ b/src/BinaryFile.php @@ -15,6 +15,8 @@ final class BinaryFile { private const HASH_TYPE_SHA256 = 'sha256'; + private const DRY_RUN_FAKE_HASH = 'dry_run_fake_hash'; + /** * @param non-empty-string $filePath * @param non-empty-string $checksum @@ -33,4 +35,13 @@ public static function fromFileWithSha256Checksum(string $filePath): self hash_file(self::HASH_TYPE_SHA256, $filePath), ); } + + /** @param non-empty-string $filePath */ + public static function nonExistentForDryRun(string $filePath): self + { + return new self( + 'dry-run::' . $filePath, + self::DRY_RUN_FAKE_HASH, + ); + } } diff --git a/src/Building/Build.php b/src/Building/Build.php index 884b170..c11b246 100644 --- a/src/Building/Build.php +++ b/src/Building/Build.php @@ -20,5 +20,6 @@ public function __invoke( array $configureOptions, OutputInterface $output, PhpizePath|null $phpizePath, + bool $dryRun, ): BinaryFile; } diff --git a/src/Building/UnixBuild.php b/src/Building/UnixBuild.php index 6e7c994..76a37f7 100644 --- a/src/Building/UnixBuild.php +++ b/src/Building/UnixBuild.php @@ -31,6 +31,7 @@ public function __invoke( array $configureOptions, OutputInterface $output, PhpizePath|null $phpizePath, + bool $dryRun, ): BinaryFile { $outputCallback = null; if ($output->isVerbose()) { @@ -60,6 +61,7 @@ public function __invoke( $downloadedPackage, $output, $outputCallback, + $dryRun, ); $output->writeln('phpize complete.'); @@ -69,16 +71,28 @@ public function __invoke( $configureOptions[] = '--with-php-config=' . $phpConfigPath; } - $this->configure($downloadedPackage, $configureOptions, $output, $outputCallback); + $this->configure( + $downloadedPackage, + $configureOptions, + $output, + $outputCallback, + $dryRun, + ); $optionsOutput = count($configureOptions) ? ' with options: ' . implode(' ', $configureOptions) : '.'; $output->writeln('Configure complete' . $optionsOutput); - $this->make($targetPlatform, $downloadedPackage, $output, $outputCallback); + $this->make( + $targetPlatform, + $downloadedPackage, + $output, + $outputCallback, + $dryRun, + ); $expectedSoFile = $downloadedPackage->extractedSourcePath . '/modules/' . $downloadedPackage->package->extensionName->name() . '.so'; - if (! file_exists($expectedSoFile)) { + if (! $dryRun && ! file_exists($expectedSoFile)) { throw ExtensionBinaryNotFound::fromExpectedBinary($expectedSoFile); } @@ -87,6 +101,10 @@ public function __invoke( $expectedSoFile, )); + if ($dryRun) { + return BinaryFile::nonExistentForDryRun($expectedSoFile); + } + return BinaryFile::fromFileWithSha256Checksum($expectedSoFile); } @@ -96,6 +114,7 @@ private function phpize( DownloadedPackage $downloadedPackage, OutputInterface $output, callable|null $outputCallback, + bool $dryRun, ): void { $phpizeCommand = [$phpize->phpizeBinaryPath]; @@ -103,6 +122,10 @@ private function phpize( $output->writeln('Running phpize step using: ' . implode(' ', $phpizeCommand) . ''); } + if ($dryRun) { + return; + } + Process::run( $phpizeCommand, $downloadedPackage->extractedSourcePath, @@ -120,6 +143,7 @@ private function configure( array $configureOptions, OutputInterface $output, callable|null $outputCallback, + bool $dryRun, ): void { $configureCommand = ['./configure', ...$configureOptions]; @@ -127,6 +151,10 @@ private function configure( $output->writeln('Running configure step with: ' . implode(' ', $configureCommand) . ''); } + if ($dryRun) { + return; + } + Process::run( $configureCommand, $downloadedPackage->extractedSourcePath, @@ -141,6 +169,7 @@ private function make( DownloadedPackage $downloadedPackage, OutputInterface $output, callable|null $outputCallback, + bool $dryRun, ): void { $makeCommand = ['make']; @@ -154,6 +183,10 @@ private function make( $output->writeln('Running make step with: ' . implode(' ', $makeCommand) . ''); } + if ($dryRun) { + return; + } + Process::run( $makeCommand, $downloadedPackage->extractedSourcePath, diff --git a/src/Building/WindowsBuild.php b/src/Building/WindowsBuild.php index 991ac77..ad98cc9 100644 --- a/src/Building/WindowsBuild.php +++ b/src/Building/WindowsBuild.php @@ -23,6 +23,7 @@ public function __invoke( array $configureOptions, OutputInterface $output, PhpizePath|null $phpizePath, + bool $dryRun, ): BinaryFile { $prebuiltDll = WindowsExtensionAssetName::determineDllName($targetPlatform, $downloadedPackage); diff --git a/src/Command/BuildCommand.php b/src/Command/BuildCommand.php index 46bd27e..bcdf789 100644 --- a/src/Command/BuildCommand.php +++ b/src/Command/BuildCommand.php @@ -37,6 +37,7 @@ public function configure(): void parent::configure(); CommandHelper::configureDownloadBuildInstallOptions($this); + CommandHelper::configureDryRunOption($this); } public function execute(InputInterface $input, OutputInterface $output): int @@ -54,6 +55,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Resolve, [], // Configure options are not needed for resolve only null, + CommandHelper::determineDryRunFromInputs($input), ), ); @@ -74,6 +76,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Build, $configureOptionsValues, CommandHelper::determinePhpizePathFromInputs($input), + false, ), ); diff --git a/src/Command/CommandHelper.php b/src/Command/CommandHelper.php index 68b55d2..c25b7a1 100644 --- a/src/Command/CommandHelper.php +++ b/src/Command/CommandHelper.php @@ -38,6 +38,7 @@ final class CommandHelper private const OPTION_WITH_PHP_PATH = 'with-php-path'; private const OPTION_WITH_PHPIZE_PATH = 'with-phpize-path'; private const OPTION_MAKE_PARALLEL_JOBS = 'make-parallel-jobs'; + private const OPTION_DRY_RUN = 'dry-run'; /** @psalm-suppress UnusedConstructor */ private function __construct() @@ -89,6 +90,16 @@ public static function configureDownloadBuildInstallOptions(Command $command): v $command->ignoreValidationErrors(); } + public static function configureDryRunOption(Command $command): void + { + $command->addOption( + self::OPTION_DRY_RUN, + null, + InputOption::VALUE_NONE, + 'Do not actually build or install the extension, just show the steps that would be run.', + ); + } + public static function validateInput(InputInterface $input, Command $command): void { $input->bind($command->getDefinition()); @@ -154,6 +165,11 @@ public static function determineTargetPlatformFromInputs(InputInterface $input, return $targetPlatform; } + public static function determineDryRunFromInputs(InputInterface $input): bool + { + return $input->hasOption(self::OPTION_DRY_RUN) && $input->getOption(self::OPTION_DRY_RUN); + } + public static function determinePhpizePathFromInputs(InputInterface $input): PhpizePath|null { if ($input->hasOption(self::OPTION_WITH_PHPIZE_PATH)) { diff --git a/src/Command/DownloadCommand.php b/src/Command/DownloadCommand.php index a6c237d..86d750b 100644 --- a/src/Command/DownloadCommand.php +++ b/src/Command/DownloadCommand.php @@ -56,6 +56,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Download, [], // Configure options are not needed for download only null, + CommandHelper::determineDryRunFromInputs($input), ), ); diff --git a/src/Command/InfoCommand.php b/src/Command/InfoCommand.php index 0d3a6cc..71a8811 100644 --- a/src/Command/InfoCommand.php +++ b/src/Command/InfoCommand.php @@ -54,6 +54,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Resolve, [], // Configure options are not needed for resolve only null, + CommandHelper::determineDryRunFromInputs($input), ), ); diff --git a/src/Command/InstallCommand.php b/src/Command/InstallCommand.php index ca29316..82fde35 100644 --- a/src/Command/InstallCommand.php +++ b/src/Command/InstallCommand.php @@ -38,6 +38,7 @@ public function configure(): void parent::configure(); CommandHelper::configureDownloadBuildInstallOptions($this); + CommandHelper::configureDryRunOption($this); } public function execute(InputInterface $input, OutputInterface $output): int @@ -59,6 +60,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Resolve, [], // Configure options are not needed for resolve only null, + CommandHelper::determineDryRunFromInputs($input), ), ); @@ -79,6 +81,7 @@ public function execute(InputInterface $input, OutputInterface $output): int PieOperation::Install, $configureOptionsValues, CommandHelper::determinePhpizePathFromInputs($input), + false, ), ); diff --git a/src/ComposerIntegration/InstallAndBuildProcess.php b/src/ComposerIntegration/InstallAndBuildProcess.php index c694472..4621c7d 100644 --- a/src/ComposerIntegration/InstallAndBuildProcess.php +++ b/src/ComposerIntegration/InstallAndBuildProcess.php @@ -56,6 +56,7 @@ public function __invoke( $composerRequest->configureOptions, $output, $composerRequest->phpizePath, + $composerRequest->dryRun, ); $this->installedJsonMetadata->addBuildMetadata( @@ -77,6 +78,7 @@ public function __invoke( $downloadedPackage, $composerRequest->targetPlatform, $output, + $composerRequest->dryRun, ), ); } diff --git a/src/ComposerIntegration/PieComposerRequest.php b/src/ComposerIntegration/PieComposerRequest.php index 536a347..7c7008c 100644 --- a/src/ComposerIntegration/PieComposerRequest.php +++ b/src/ComposerIntegration/PieComposerRequest.php @@ -24,6 +24,7 @@ public function __construct( public readonly PieOperation $operation, public readonly array $configureOptions, public readonly PhpizePath|null $phpizePath, + public readonly bool $dryRun, ) { } } diff --git a/src/Installing/Install.php b/src/Installing/Install.php index 71e2849..07c9973 100644 --- a/src/Installing/Install.php +++ b/src/Installing/Install.php @@ -20,5 +20,6 @@ public function __invoke( DownloadedPackage $downloadedPackage, TargetPlatform $targetPlatform, OutputInterface $output, + bool $dryRun, ): BinaryFile; } diff --git a/src/Installing/UnixInstall.php b/src/Installing/UnixInstall.php index 6411e6b..4dcab93 100644 --- a/src/Installing/UnixInstall.php +++ b/src/Installing/UnixInstall.php @@ -22,7 +22,7 @@ final class UnixInstall implements Install { private const MAKE_INSTALL_TIMEOUT_SECS = 60; // 1 minute - public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $targetPlatform, OutputInterface $output): BinaryFile + public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $targetPlatform, OutputInterface $output, bool $dryRun): BinaryFile { $targetExtensionPath = $targetPlatform->phpBinaryPath->extensionPath(); @@ -47,18 +47,20 @@ public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $t array_unshift($makeInstallCommand, 'sudo'); } - $makeInstallOutput = Process::run( - $makeInstallCommand, - $downloadedPackage->extractedSourcePath, - self::MAKE_INSTALL_TIMEOUT_SECS, - ); + if (! $dryRun) { + $makeInstallOutput = Process::run( + $makeInstallCommand, + $downloadedPackage->extractedSourcePath, + self::MAKE_INSTALL_TIMEOUT_SECS, + ); - if ($output->isVeryVerbose()) { - $output->writeln($makeInstallOutput); - } + if ($output->isVeryVerbose()) { + $output->writeln($makeInstallOutput); + } - if (! file_exists($expectedSharedObjectLocation)) { - throw new RuntimeException('Install failed, ' . $expectedSharedObjectLocation . ' was not installed.'); + if (! file_exists($expectedSharedObjectLocation)) { + throw new RuntimeException('Install failed, ' . $expectedSharedObjectLocation . ' was not installed.'); + } } $output->writeln('Install complete: ' . $expectedSharedObjectLocation); @@ -74,6 +76,10 @@ public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $t $downloadedPackage->package->extensionName->name(), )); + if ($dryRun) { + return BinaryFile::nonExistentForDryRun($expectedSharedObjectLocation); + } + return BinaryFile::fromFileWithSha256Checksum($expectedSharedObjectLocation); } } diff --git a/src/Installing/WindowsInstall.php b/src/Installing/WindowsInstall.php index a9f6c3c..92cc2e0 100644 --- a/src/Installing/WindowsInstall.php +++ b/src/Installing/WindowsInstall.php @@ -31,17 +31,17 @@ /** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */ final class WindowsInstall implements Install { - public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $targetPlatform, OutputInterface $output): BinaryFile + public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $targetPlatform, OutputInterface $output, bool $dryRun): BinaryFile { $extractedSourcePath = $downloadedPackage->extractedSourcePath; $sourceDllName = WindowsExtensionAssetName::determineDllName($targetPlatform, $downloadedPackage); $sourcePdbName = str_replace('.dll', '.pdb', $sourceDllName); assert($sourcePdbName !== ''); - $destinationDllName = $this->copyExtensionDll($targetPlatform, $downloadedPackage, $sourceDllName); + $destinationDllName = $this->copyExtensionDll($targetPlatform, $downloadedPackage, $sourceDllName, $dryRun); $output->writeln('Copied DLL to: ' . $destinationDllName); - $destinationPdbName = $this->copyExtensionPdb($targetPlatform, $downloadedPackage, $sourcePdbName, $destinationDllName); + $destinationPdbName = $this->copyExtensionPdb($targetPlatform, $downloadedPackage, $sourcePdbName, $destinationDllName, $dryRun); if ($destinationPdbName !== null) { $output->writeln('Copied PDB to: ' . $destinationPdbName); } @@ -60,14 +60,14 @@ public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $t continue; } - $destinationExtraDll = $this->copyDependencyDll($targetPlatform, $file); + $destinationExtraDll = $this->copyDependencyDll($targetPlatform, $file, $dryRun); if ($destinationExtraDll !== null) { $output->writeln('Copied extra DLL: ' . $destinationExtraDll); continue; } - $destinationPathname = $this->copyExtraFile($targetPlatform, $downloadedPackage, $file); + $destinationPathname = $this->copyExtraFile($targetPlatform, $downloadedPackage, $file, $dryRun); $output->writeln('Copied extras: ' . $destinationPathname); } @@ -82,6 +82,10 @@ public function __invoke(DownloadedPackage $downloadedPackage, TargetPlatform $t $downloadedPackage->package->extensionName->name(), )); + if ($dryRun) { + return BinaryFile::nonExistentForDryRun($destinationDllName); + } + return BinaryFile::fromFileWithSha256Checksum($destinationDllName); } @@ -101,11 +105,15 @@ private function normalisedPathsMatch(string $first, string $second): bool * * @return non-empty-string */ - private function copyExtensionDll(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, string $sourceDllName): string + private function copyExtensionDll(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, string $sourceDllName, bool $dryRun): string { $destinationDllName = $targetPlatform->phpBinaryPath->extensionPath() . DIRECTORY_SEPARATOR . 'php_' . $downloadedPackage->package->extensionName->name() . '.dll'; + if ($dryRun) { + return $destinationDllName; + } + if (! copy($sourceDllName, $destinationDllName) || ! file_exists($destinationDllName) && ! is_file($destinationDllName)) { throw new RuntimeException('Failed to install DLL to ' . $destinationDllName); } @@ -124,7 +132,7 @@ private function copyExtensionDll(TargetPlatform $targetPlatform, DownloadedPack * * @return non-empty-string|null */ - private function copyExtensionPdb(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, string $sourcePdbName, string $destinationDllName): string|null + private function copyExtensionPdb(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, string $sourcePdbName, string $destinationDllName, bool $dryRun): string|null { if (! file_exists($sourcePdbName)) { return null; @@ -133,6 +141,10 @@ private function copyExtensionPdb(TargetPlatform $targetPlatform, DownloadedPack $destinationPdbName = str_replace('.dll', '.pdb', $destinationDllName); assert($destinationPdbName !== ''); + if ($dryRun) { + return $destinationPdbName; + } + if (! copy($sourcePdbName, $destinationPdbName) || ! file_exists($destinationPdbName) && ! is_file($destinationPdbName)) { throw new RuntimeException('Failed to install PDB to ' . $destinationPdbName); } @@ -148,7 +160,7 @@ private function copyExtensionPdb(TargetPlatform $targetPlatform, DownloadedPack * * @return non-empty-string|null */ - private function copyDependencyDll(TargetPlatform $targetPlatform, SplFileInfo $file): string|null + private function copyDependencyDll(TargetPlatform $targetPlatform, SplFileInfo $file, bool $dryRun): string|null { if ($file->getExtension() !== 'dll') { return null; @@ -156,6 +168,10 @@ private function copyDependencyDll(TargetPlatform $targetPlatform, SplFileInfo $ $destinationExtraDll = dirname($targetPlatform->phpBinaryPath->phpBinaryPath) . DIRECTORY_SEPARATOR . $file->getFilename(); + if ($dryRun) { + return $destinationExtraDll; + } + if (! copy($file->getPathname(), $destinationExtraDll) || ! file_exists($destinationExtraDll) && ! is_file($destinationExtraDll)) { throw new RuntimeException('Failed to copy to ' . $destinationExtraDll); } @@ -168,7 +184,7 @@ private function copyDependencyDll(TargetPlatform $targetPlatform, SplFileInfo $ * * @return non-empty-string */ - private function copyExtraFile(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, SplFileInfo $file): string + private function copyExtraFile(TargetPlatform $targetPlatform, DownloadedPackage $downloadedPackage, SplFileInfo $file, bool $dryRun): string { $destinationFullFilename = dirname($targetPlatform->phpBinaryPath->phpBinaryPath) . DIRECTORY_SEPARATOR . 'extras' . DIRECTORY_SEPARATOR @@ -177,6 +193,10 @@ private function copyExtraFile(TargetPlatform $targetPlatform, DownloadedPackage $destinationPath = dirname($destinationFullFilename); + if ($dryRun) { + return $destinationFullFilename; + } + if (! file_exists($destinationPath)) { mkdir($destinationPath, 0777, true); } diff --git a/test/integration/Building/UnixBuildTest.php b/test/integration/Building/UnixBuildTest.php index 41bffb7..12a9f86 100644 --- a/test/integration/Building/UnixBuildTest.php +++ b/test/integration/Building/UnixBuildTest.php @@ -59,6 +59,7 @@ public function testUnixBuildCanBuildExtension(): void ['--enable-pie_test_ext'], $output, null, + false, ); self::assertNotEmpty($builtBinary); @@ -115,6 +116,7 @@ public function testUnixBuildWillThrowExceptionWhenExpectedBinaryNameMismatches( ['--enable-pie_test_ext'], $output, null, + false, ); } finally { (new Process(['make', 'clean'], $downloadedPackage->extractedSourcePath))->mustRun(); @@ -153,6 +155,7 @@ public function testUnixBuildCanBuildExtensionWithBuildPath(): void ['--enable-pie_test_ext'], $output, null, + false, ); self::assertNotEmpty($builtBinary); @@ -210,6 +213,7 @@ public function testCleanupDoesNotCleanWhenConfigureIsMissing(): void ['--enable-pie_test_ext'], $output, null, + false, ); $outputString = $output->fetch(); @@ -252,6 +256,7 @@ public function testVerboseOutputShowsCleanupMessages(): void ['--enable-pie_test_ext'], $output, null, + false, ); $outputString = $output->fetch(); diff --git a/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php b/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php index c708dff..1477b39 100644 --- a/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php +++ b/test/integration/DependencyResolver/ResolveDependencyWithComposerTest.php @@ -90,6 +90,7 @@ public function testDependenciesAreResolvedToExpectedVersions( PieOperation::Resolve, [], null, + false, ), ), $targetPlatform, diff --git a/test/integration/Installing/UnixInstallTest.php b/test/integration/Installing/UnixInstallTest.php index 5bf7bb9..b333566 100644 --- a/test/integration/Installing/UnixInstallTest.php +++ b/test/integration/Installing/UnixInstallTest.php @@ -101,12 +101,14 @@ public function testUnixInstallCanInstallExtension(string $phpConfig): void ['--enable-pie_test_ext'], $output, null, + false, ); $installedSharedObject = (new UnixInstall())->__invoke( $downloadedPackage, $targetPlatform, $output, + false, ); $outputString = $output->fetch(); @@ -125,4 +127,56 @@ public function testUnixInstallCanInstallExtension(string $phpConfig): void (new Process(['make', 'clean'], $downloadedPackage->extractedSourcePath))->mustRun(); (new Process(['phpize', '--clean'], $downloadedPackage->extractedSourcePath))->mustRun(); } + + #[DataProvider('phpPathProvider')] + public function testUnixInstallCanInstallExtensionWithDryRun(string $phpConfig): void + { + assert($phpConfig !== ''); + if (Platform::isWindows()) { + self::markTestSkipped('Unix build test cannot be run on Windows'); + } + + $output = new BufferedOutput(); + $targetPlatform = TargetPlatform::fromPhpBinaryPath(PhpBinaryPath::fromPhpConfigExecutable($phpConfig), null); + $extensionPath = $targetPlatform->phpBinaryPath->extensionPath(); + + $downloadedPackage = DownloadedPackage::fromPackageAndExtractedPath( + new Package( + $this->createMock(CompletePackage::class), + ExtensionType::PhpModule, + ExtensionName::normaliseFromString('pie_test_ext'), + 'pie_test_ext', + '0.1.0', + null, + [ConfigureOption::fromComposerJsonDefinition(['name' => 'enable-pie_test_ext'])], + true, + true, + null, + ), + self::TEST_EXTENSION_PATH, + ); + + (new UnixBuild())->__invoke( + $downloadedPackage, + $targetPlatform, + ['--enable-pie_test_ext'], + $output, + null, + true, + ); + + $installedSharedObject = (new UnixInstall())->__invoke( + $downloadedPackage, + $targetPlatform, + $output, + true, + ); + $outputString = $output->fetch(); + + self::assertStringContainsString('Install complete: ' . $extensionPath . '/pie_test_ext.so', $outputString); + self::assertStringContainsString('You must now add "extension=pie_test_ext" to your php.ini', $outputString); + + self::assertSame('dry-run::' . $extensionPath . '/pie_test_ext.so', $installedSharedObject->filePath); + self::assertFileDoesNotExist($installedSharedObject->filePath); + } } diff --git a/test/integration/Installing/WindowsInstallTest.php b/test/integration/Installing/WindowsInstallTest.php index 0905fa9..864e40e 100644 --- a/test/integration/Installing/WindowsInstallTest.php +++ b/test/integration/Installing/WindowsInstallTest.php @@ -71,7 +71,7 @@ public function testWindowsInstallCanInstallExtension(): void $installer = new WindowsInstall(); - $installedDll = $installer->__invoke($downloadedPackage, $targetPlatform, $output); + $installedDll = $installer->__invoke($downloadedPackage, $targetPlatform, $output, false); self::assertSame($extensionPath . '\php_pie_test_ext.dll', $installedDll->filePath); $outputString = $output->fetch(); @@ -99,6 +99,61 @@ public function testWindowsInstallCanInstallExtension(): void $this->delete($extrasDirectory); } + #[RequiresOperatingSystemFamily('Windows')] + public function testWindowsInstallCanInstallExtensionWithDryRun(): void + { + $downloadedPackage = DownloadedPackage::fromPackageAndExtractedPath( + new Package( + $this->createMock(CompletePackage::class), + ExtensionType::PhpModule, + ExtensionName::normaliseFromString('pie_test_ext'), + 'php/pie-test-ext', + '1.2.3', + null, + [], + true, + true, + null, + ), + self::TEST_EXTENSION_PATH, + ); + $output = new BufferedOutput(); + $targetPlatform = new TargetPlatform( + OperatingSystem::Windows, + PhpBinaryPath::fromCurrentProcess(), + Architecture::x86_64, + ThreadSafetyMode::ThreadSafe, + 1, + WindowsCompiler::VS16, + ); + $phpPath = dirname($targetPlatform->phpBinaryPath->phpBinaryPath); + $extensionPath = $targetPlatform->phpBinaryPath->extensionPath(); + + $installer = new WindowsInstall(); + + $installedDll = $installer->__invoke($downloadedPackage, $targetPlatform, $output, true); + self::assertSame($extensionPath . '\php_pie_test_ext.dll', $installedDll->filePath); + + $outputString = $output->fetch(); + + self::assertStringContainsString('Copied DLL to: ' . $extensionPath . '\php_pie_test_ext.dll', $outputString); + self::assertStringContainsString('You must now add "extension=pie_test_ext" to your php.ini', $outputString); + + $extrasDirectory = $phpPath . DIRECTORY_SEPARATOR . 'extras' . DIRECTORY_SEPARATOR . 'pie_test_ext'; + + $expectedPdb = str_replace('.dll', '.pdb', $installedDll->filePath); + $expectedSupportingDll = $phpPath . DIRECTORY_SEPARATOR . 'supporting-library.dll'; + $expectedSupportingOtherFile = $extrasDirectory . DIRECTORY_SEPARATOR . 'README.md'; + $expectedSubdirectoryFile = $extrasDirectory . DIRECTORY_SEPARATOR . 'more' . DIRECTORY_SEPARATOR . 'more-information.txt'; + assert($expectedPdb !== ''); + + self::assertFileDoesNotExist($installedDll->filePath); + self::assertFileDoesNotExist($expectedPdb); + self::assertFileDoesNotExist($expectedSupportingDll); + self::assertFileDoesNotExist($expectedSupportingOtherFile); + self::assertFileDoesNotExist($expectedSubdirectoryFile); + } + /** * Recursively remove a file/path to clean up after testing * diff --git a/test/unit/ComposerIntegration/InstallAndBuildProcessTest.php b/test/unit/ComposerIntegration/InstallAndBuildProcessTest.php index c8ff3cc..0054c70 100644 --- a/test/unit/ComposerIntegration/InstallAndBuildProcessTest.php +++ b/test/unit/ComposerIntegration/InstallAndBuildProcessTest.php @@ -66,6 +66,7 @@ public function testDownloadWithoutBuildAndInstall(): void PieOperation::Download, ['--foo', '--bar="yes"'], null, + false, ); $composerPackage = new CompletePackage('foo/bar', '1.2.3.0', '1.2.3'); $installPath = '/path/to/install'; @@ -106,6 +107,7 @@ public function testDownloadAndBuildWithoutInstall(): void PieOperation::Build, ['--foo', '--bar="yes"'], null, + false, ); $composerPackage = new CompletePackage('foo/bar', '1.2.3.0', '1.2.3'); $installPath = '/path/to/install'; @@ -149,6 +151,7 @@ public function testDownloadBuildAndInstall(): void PieOperation::Install, ['--foo', '--bar="yes"'], null, + false, ); $composerPackage = new CompletePackage('foo/bar', '1.2.3.0', '1.2.3'); $installPath = '/path/to/install'; diff --git a/test/unit/ComposerIntegration/InstalledJsonMetadataTest.php b/test/unit/ComposerIntegration/InstalledJsonMetadataTest.php index 93a0672..5fa1626 100644 --- a/test/unit/ComposerIntegration/InstalledJsonMetadataTest.php +++ b/test/unit/ComposerIntegration/InstalledJsonMetadataTest.php @@ -62,6 +62,7 @@ public function testMetadataForDownloads(): void PieOperation::Build, ['--foo', '--bar="yes"'], null, + false, ), clone $package, ); @@ -99,6 +100,7 @@ public function testMetadataForBuilds(): void PieOperation::Build, ['--foo', '--bar="yes"'], new PhpizePath('/path/to/phpize'), + false, ), clone $package, new BinaryFile('/path/to/built', 'sha256-checksum-value'), diff --git a/test/unit/ComposerIntegration/OverrideWindowsUrlInstallListenerTest.php b/test/unit/ComposerIntegration/OverrideWindowsUrlInstallListenerTest.php index 233566c..2efb4ae 100644 --- a/test/unit/ComposerIntegration/OverrideWindowsUrlInstallListenerTest.php +++ b/test/unit/ComposerIntegration/OverrideWindowsUrlInstallListenerTest.php @@ -78,6 +78,7 @@ public function testEventListenerRegistration(): void PieOperation::Install, [], null, + false, ), ); } @@ -122,6 +123,7 @@ public function testWindowsUrlInstallerDoesNotRunOnNonWindows(): void PieOperation::Install, [], null, + false, ), ))($installerEvent); @@ -178,6 +180,7 @@ public function testDistUrlIsUpdatedForWindowsInstallers(): void PieOperation::Install, [], null, + false, ), ))($installerEvent);