From 30a174b8ae101881c600eefc47ec90a250c103f8 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Wed, 14 May 2025 13:39:08 +0200 Subject: [PATCH 1/3] Change working directory for installing a pie|php project --- src/Command/InstallCommand.php | 9 ++++++++ .../InstallExtensionsForProjectCommand.php | 23 ++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/Command/InstallCommand.php b/src/Command/InstallCommand.php index fd2c8fde..7bdbadb8 100644 --- a/src/Command/InstallCommand.php +++ b/src/Command/InstallCommand.php @@ -15,6 +15,7 @@ use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use function sprintf; @@ -39,6 +40,14 @@ public function configure(): void parent::configure(); CommandHelper::configureDownloadBuildInstallOptions($this); + + // @todo this doesn't make sense to be here, but is needed to pass the option down + $this->addOption( + 'working-dir', + 'd', + InputOption::VALUE_REQUIRED, + 'The working directory to use; if not specified, the current working directory is used', + ); } public function execute(InputInterface $input, OutputInterface $output): int diff --git a/src/Command/InstallExtensionsForProjectCommand.php b/src/Command/InstallExtensionsForProjectCommand.php index e80f0083..9e466506 100644 --- a/src/Command/InstallExtensionsForProjectCommand.php +++ b/src/Command/InstallExtensionsForProjectCommand.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; @@ -48,6 +49,8 @@ )] final class InstallExtensionsForProjectCommand extends Command { + private const OPTION_WORKING_DIRECTORY = 'working-dir'; + public function __construct( private readonly ComposerFactoryForProject $composerFactoryForProject, private readonly DetermineExtensionsRequired $determineExtensionsRequired, @@ -63,7 +66,15 @@ public function configure(): void { parent::configure(); - CommandHelper::configurePhpConfigOptions($this); + // @todo remove ARG_REQUESTED_PACKAGE_AND_VERSION as it doesn't make sense here + CommandHelper::configureDownloadBuildInstallOptions($this); + + $this->addOption( + self::OPTION_WORKING_DIRECTORY, + 'd', + InputOption::VALUE_REQUIRED, + 'The working directory to use; if not specified, the current working directory is used', + ); } public function execute(InputInterface $input, OutputInterface $output): int @@ -71,6 +82,16 @@ public function execute(InputInterface $input, OutputInterface $output): int $helper = $this->getHelper('question'); assert($helper instanceof QuestionHelper); + $workingDirOption = (string) $input->getOption(self::OPTION_WORKING_DIRECTORY); + if ($workingDirOption !== '' && is_dir($workingDirOption)) { + chdir($workingDirOption); + $output->writeln( + sprintf('Changed working directory to: %s', $workingDirOption), + OutputInterface::VERBOSITY_VERBOSE, + ); + } + // @todo check if we need to revert the cwd on exit (would need to check all exit branches) + $rootPackage = $this->composerFactoryForProject->rootPackage($input, $output); if (ExtensionType::isValid($rootPackage->getType())) { From 37f62f060cfa582d47efc1cb2c2b4273cf015df9 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Wed, 28 May 2025 12:14:39 +0100 Subject: [PATCH 2/3] Move working-dir param into configureDownloadBuildInstallOptions --- src/Command/CommandHelper.php | 23 ++++++++++++++----- src/Command/InstallCommand.php | 9 -------- .../InstallExtensionsForProjectCommand.php | 18 ++++----------- 3 files changed, 22 insertions(+), 28 deletions(-) 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/InstallCommand.php b/src/Command/InstallCommand.php index 7bdbadb8..fd2c8fde 100644 --- a/src/Command/InstallCommand.php +++ b/src/Command/InstallCommand.php @@ -15,7 +15,6 @@ use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use function sprintf; @@ -40,14 +39,6 @@ public function configure(): void parent::configure(); CommandHelper::configureDownloadBuildInstallOptions($this); - - // @todo this doesn't make sense to be here, but is needed to pass the option down - $this->addOption( - 'working-dir', - 'd', - InputOption::VALUE_REQUIRED, - 'The working directory to use; if not specified, the current working directory is used', - ); } public function execute(InputInterface $input, OutputInterface $output): int diff --git a/src/Command/InstallExtensionsForProjectCommand.php b/src/Command/InstallExtensionsForProjectCommand.php index 9e466506..8f418774 100644 --- a/src/Command/InstallExtensionsForProjectCommand.php +++ b/src/Command/InstallExtensionsForProjectCommand.php @@ -21,7 +21,6 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Output\OutputInterface; @@ -33,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; @@ -49,8 +50,6 @@ )] final class InstallExtensionsForProjectCommand extends Command { - private const OPTION_WORKING_DIRECTORY = 'working-dir'; - public function __construct( private readonly ComposerFactoryForProject $composerFactoryForProject, private readonly DetermineExtensionsRequired $determineExtensionsRequired, @@ -66,15 +65,7 @@ public function configure(): void { parent::configure(); - // @todo remove ARG_REQUESTED_PACKAGE_AND_VERSION as it doesn't make sense here - CommandHelper::configureDownloadBuildInstallOptions($this); - - $this->addOption( - self::OPTION_WORKING_DIRECTORY, - 'd', - InputOption::VALUE_REQUIRED, - 'The working directory to use; if not specified, the current working directory is used', - ); + CommandHelper::configureDownloadBuildInstallOptions($this, false); } public function execute(InputInterface $input, OutputInterface $output): int @@ -82,7 +73,7 @@ public function execute(InputInterface $input, OutputInterface $output): int $helper = $this->getHelper('question'); assert($helper instanceof QuestionHelper); - $workingDirOption = (string) $input->getOption(self::OPTION_WORKING_DIRECTORY); + $workingDirOption = (string) $input->getOption(CommandHelper::OPTION_WORKING_DIRECTORY); if ($workingDirOption !== '' && is_dir($workingDirOption)) { chdir($workingDirOption); $output->writeln( @@ -90,6 +81,7 @@ public function execute(InputInterface $input, OutputInterface $output): int OutputInterface::VERBOSITY_VERBOSE, ); } + // @todo check if we need to revert the cwd on exit (would need to check all exit branches) $rootPackage = $this->composerFactoryForProject->rootPackage($input, $output); From ba7cf846a95f5c107029476c4731f2062b0ccc11 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Wed, 28 May 2025 12:43:13 +0100 Subject: [PATCH 3/3] Restore previous working directory on exit --- .../InstallExtensionsForProjectCommand.php | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Command/InstallExtensionsForProjectCommand.php b/src/Command/InstallExtensionsForProjectCommand.php index 8f418774..c5746a35 100644 --- a/src/Command/InstallExtensionsForProjectCommand.php +++ b/src/Command/InstallExtensionsForProjectCommand.php @@ -73,8 +73,19 @@ public function execute(InputInterface $input, OutputInterface $output): int $helper = $this->getHelper('question'); assert($helper instanceof QuestionHelper); - $workingDirOption = (string) $input->getOption(CommandHelper::OPTION_WORKING_DIRECTORY); + $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), @@ -82,8 +93,6 @@ public function execute(InputInterface $input, OutputInterface $output): int ); } - // @todo check if we need to revert the cwd on exit (would need to check all exit branches) - $rootPackage = $this->composerFactoryForProject->rootPackage($input, $output); if (ExtensionType::isValid($rootPackage->getType())) { @@ -91,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, @@ -102,6 +113,10 @@ public function execute(InputInterface $input, OutputInterface $output): int $input, $output, ); + + $restoreWorkingDir(); + + return $exit; } $targetPlatform = CommandHelper::determineTargetPlatformFromInputs($input, $output); @@ -214,6 +229,8 @@ static function (array $match): string { $output->writeln(PHP_EOL . 'Finished checking extensions.'); + $restoreWorkingDir(); + /** * @psalm-suppress TypeDoesNotContainType * @psalm-suppress RedundantCondition