diff --git a/src/Command/CommandHelper.php b/src/Command/CommandHelper.php index 47e4beba..4f53e09f 100644 --- a/src/Command/CommandHelper.php +++ b/src/Command/CommandHelper.php @@ -42,6 +42,7 @@ final class CommandHelper public const OPTION_WITH_PHP_CONFIG = 'with-php-config'; public const OPTION_WITH_PHP_PATH = 'with-php-path'; public const OPTION_WITH_PHPIZE_PATH = 'with-phpize-path'; + public const OPTION_WORKING_DIRECTORY = 'working-dir'; private const OPTION_MAKE_PARALLEL_JOBS = 'make-parallel-jobs'; private const OPTION_SKIP_ENABLE_EXTENSION = 'skip-enable-extension'; private const OPTION_FORCE = 'force'; @@ -73,13 +74,16 @@ public static function configurePhpConfigOptions(Command $command): void ); } - public static function configureDownloadBuildInstallOptions(Command $command): void + public static function configureDownloadBuildInstallOptions(Command $command, bool $withRequestedPackageAndVersion = true): void { - $command->addArgument( - self::ARG_REQUESTED_PACKAGE_AND_VERSION, - InputArgument::OPTIONAL, - 'The PIE package name and version constraint to use, in the format {vendor/package}{?:{?version-constraint}{?@stability}}, for example `xdebug/xdebug:^3.4@alpha`, `xdebug/xdebug:@alpha`, `xdebug/xdebug:^3.4`, etc.', - ); + if ($withRequestedPackageAndVersion) { + $command->addArgument( + self::ARG_REQUESTED_PACKAGE_AND_VERSION, + InputArgument::OPTIONAL, + 'The PIE package name and version constraint to use, in the format {vendor/package}{?:{?version-constraint}{?@stability}}, for example `xdebug/xdebug:^3.4@alpha`, `xdebug/xdebug:@alpha`, `xdebug/xdebug:^3.4`, etc.', + ); + } + $command->addOption( self::OPTION_MAKE_PARALLEL_JOBS, 'j', @@ -99,6 +103,13 @@ public static function configureDownloadBuildInstallOptions(Command $command): v 'To attempt to install a version that doesn\'t match the version constraints from the meta-data, for instance to install an older version than recommended, or when the signature is not available.', ); + $command->addOption( + self::OPTION_WORKING_DIRECTORY, + 'd', + InputOption::VALUE_REQUIRED, + 'The working directory to use, where applicable. If not specified, the current working directory is used. Only used in certain contexts.', + ); + self::configurePhpConfigOptions($command); /** diff --git a/src/Command/InstallExtensionsForProjectCommand.php b/src/Command/InstallExtensionsForProjectCommand.php index e80f0083..c5746a35 100644 --- a/src/Command/InstallExtensionsForProjectCommand.php +++ b/src/Command/InstallExtensionsForProjectCommand.php @@ -32,8 +32,10 @@ use function array_merge; use function array_walk; use function assert; +use function chdir; use function getcwd; use function in_array; +use function is_dir; use function is_string; use function realpath; use function sprintf; @@ -63,7 +65,7 @@ public function configure(): void { parent::configure(); - CommandHelper::configurePhpConfigOptions($this); + CommandHelper::configureDownloadBuildInstallOptions($this, false); } public function execute(InputInterface $input, OutputInterface $output): int @@ -71,6 +73,26 @@ public function execute(InputInterface $input, OutputInterface $output): int $helper = $this->getHelper('question'); assert($helper instanceof QuestionHelper); + $workingDirOption = (string) $input->getOption(CommandHelper::OPTION_WORKING_DIRECTORY); + $restoreWorkingDir = static function (): void { + }; + if ($workingDirOption !== '' && is_dir($workingDirOption)) { + $currentWorkingDir = getcwd(); + $restoreWorkingDir = static function () use ($currentWorkingDir, $output): void { + chdir($currentWorkingDir); + $output->writeln( + sprintf('Restored working directory to: %s', $currentWorkingDir), + OutputInterface::VERBOSITY_VERBOSE, + ); + }; + + chdir($workingDirOption); + $output->writeln( + sprintf('Changed working directory to: %s', $workingDirOption), + OutputInterface::VERBOSITY_VERBOSE, + ); + } + $rootPackage = $this->composerFactoryForProject->rootPackage($input, $output); if (ExtensionType::isValid($rootPackage->getType())) { @@ -78,10 +100,12 @@ public function execute(InputInterface $input, OutputInterface $output): int if (! is_string($cwd) || $cwd === '') { $output->writeln('Failed to determine current working directory.'); + $restoreWorkingDir(); + return Command::FAILURE; } - return ($this->installPiePackageFromPath)( + $exit = ($this->installPiePackageFromPath)( $this, $cwd, $rootPackage, @@ -89,6 +113,10 @@ public function execute(InputInterface $input, OutputInterface $output): int $input, $output, ); + + $restoreWorkingDir(); + + return $exit; } $targetPlatform = CommandHelper::determineTargetPlatformFromInputs($input, $output); @@ -201,6 +229,8 @@ static function (array $match): string { $output->writeln(PHP_EOL . 'Finished checking extensions.'); + $restoreWorkingDir(); + /** * @psalm-suppress TypeDoesNotContainType * @psalm-suppress RedundantCondition