diff --git a/doc/03-cli.md b/doc/03-cli.md index 217d2ea0a..37a3f5723 100644 --- a/doc/03-cli.md +++ b/doc/03-cli.md @@ -149,6 +149,7 @@ php composer.phar update "vendor/*" * **--dry-run:** Simulate the command without actually doing anything. * **--dev:** Install packages listed in `require-dev` (this is the default behavior). * **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader generation skips the `autoload-dev` rules. +* **--no-install:** Does not run the install step after updating the composer.lock file. * **--lock:** Only updates the lock file hash to suppress warning about the lock file being out of date. * **--no-autoloader:** Skips autoloader generation. @@ -201,7 +202,8 @@ If you do not specify a package, composer will prompt you to search for a packag * **--prefer-dist:** Install packages from `dist` when available. * **--no-progress:** Removes the progress display that can mess with some terminals or scripts which don't handle backspace characters. -* **--no-update:** Disables the automatic update of the dependencies. +* **--no-update:** Disables the automatic update of the dependencies (implies --no-install). +* **--no-install:** Does not run the install step after updating the composer.lock file. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--update-no-dev:** Run the dependency update with the `--no-dev` option. * **--update-with-dependencies:** Also update dependencies of the newly required packages, except those that are root requirements. @@ -237,7 +239,8 @@ uninstalled. * **--dry-run:** Simulate the command without actually doing anything. * **--no-progress:** Removes the progress display that can mess with some terminals or scripts which don't handle backspace characters. -* **--no-update:** Disables the automatic update of the dependencies. +* **--no-update:** Disables the automatic update of the dependencies (implies --no-install). +* **--no-install:** Does not run the install step after updating the composer.lock file. * **--no-scripts:** Skips execution of scripts defined in `composer.json`. * **--update-no-dev:** Run the dependency update with the --no-dev option. * **--update-with-dependencies:** Also update dependencies of the removed packages. diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 033f32195..5f5565248 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -44,6 +44,7 @@ class InstallCommand extends BaseCommand new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), + new InputOption('no-install', null, InputOption::VALUE_NONE, 'Do not use, only defined here to catch misuse of the install command.'), new InputOption('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'), new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'), @@ -82,6 +83,12 @@ EOT return 1; } + if ($input->getOption('no-install')) { + $io->writeError('Invalid option "--no-install". Use "composer update --no-install" instead if you are trying to update the composer.lock file.'); + + return 1; + } + $composer = $this->getComposer(true, $input->getOption('no-plugins')); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'install', $input, $output); diff --git a/src/Composer/Command/RemoveCommand.php b/src/Composer/Command/RemoveCommand.php index 452b30585..7e4c7ed49 100644 --- a/src/Composer/Command/RemoveCommand.php +++ b/src/Composer/Command/RemoveCommand.php @@ -41,7 +41,8 @@ class RemoveCommand extends BaseCommand new InputOption('dev', null, InputOption::VALUE_NONE, 'Removes a package from the require-dev section.'), new InputOption('dry-run', null, InputOption::VALUE_NONE, 'Outputs the operations but will not execute anything (implicitly enables --verbose).'), new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), - new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'), + new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies (implies --no-install).'), + new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'), new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies. (Deprecrated, is now default behavior)'), @@ -237,6 +238,7 @@ EOT ->setClassMapAuthoritative($authoritative) ->setApcuAutoloader($apcu) ->setUpdate(true) + ->setInstall(!$input->getOption('no-install')) ->setUpdateAllowList($packages) ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies) ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')) diff --git a/src/Composer/Command/RequireCommand.php b/src/Composer/Command/RequireCommand.php index 67188504d..7e290aca6 100644 --- a/src/Composer/Command/RequireCommand.php +++ b/src/Composer/Command/RequireCommand.php @@ -61,7 +61,8 @@ class RequireCommand extends InitCommand new InputOption('fixed', null, InputOption::VALUE_NONE, 'Write fixed version to the composer.json.'), new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'), new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), - new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies.'), + new InputOption('no-update', null, InputOption::VALUE_NONE, 'Disables the automatic update of the dependencies (implies --no-install).'), + new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('update-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'), new InputOption('update-with-dependencies', null, InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated, except those that are root requirements.'), @@ -284,6 +285,7 @@ EOT ->setClassMapAuthoritative($authoritative) ->setApcuAutoloader($apcu) ->setUpdate(true) + ->setInstall(!$input->getOption('no-install')) ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies) ->setIgnorePlatformRequirements($input->getOption('ignore-platform-reqs')) ->setPreferStable($input->getOption('prefer-stable')) diff --git a/src/Composer/Command/UpdateCommand.php b/src/Composer/Command/UpdateCommand.php index 9c875a57d..4bb15fc9b 100644 --- a/src/Composer/Command/UpdateCommand.php +++ b/src/Composer/Command/UpdateCommand.php @@ -45,6 +45,7 @@ class UpdateCommand extends BaseCommand new InputOption('dev', null, InputOption::VALUE_NONE, 'DEPRECATED: Enables installation of require-dev packages (enabled by default, only present for BC).'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'), new InputOption('lock', null, InputOption::VALUE_NONE, 'Only updates the lock file hash to suppress warning about the lock file being out of date.'), + new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'), new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'), new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'), @@ -163,6 +164,7 @@ EOT ->setClassMapAuthoritative($authoritative) ->setApcuAutoloader($apcu) ->setUpdate(true) + ->setInstall(!$input->getOption('no-install')) ->setUpdateMirrors($updateMirrors) ->setUpdateAllowList($packages) ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies) diff --git a/src/Composer/Installer.php b/src/Composer/Installer.php index 1a9d4fc4f..2bca0618b 100644 --- a/src/Composer/Installer.php +++ b/src/Composer/Installer.php @@ -129,6 +129,7 @@ class Installer protected $dryRun = false; protected $verbose = false; protected $update = false; + protected $install = true; protected $dumpAutoloader = true; protected $runScripts = true; protected $ignorePlatformReqs = false; @@ -220,6 +221,10 @@ class Installer $this->mockLocalRepositories($this->repositoryManager); } + if ($this->update && !$this->install) { + $this->dumpAutoloader = false; + } + if ($this->runScripts) { $_SERVER['COMPOSER_DEV_MODE'] = (int) $this->devMode; putenv('COMPOSER_DEV_MODE='.$_SERVER['COMPOSER_DEV_MODE']); @@ -241,8 +246,7 @@ class Installer try { if ($this->update) { - // TODO introduce option to set doInstall to false (update lock file without vendor install) - $res = $this->doUpdate($localRepo, true); + $res = $this->doUpdate($localRepo, $this->install); } else { $res = $this->doInstall($localRepo); } @@ -250,13 +254,13 @@ class Installer return $res; } } catch (\Exception $e) { - if ($this->executeOperations && $this->config->get('notify-on-install')) { + if ($this->executeOperations && $this->install && $this->config->get('notify-on-install')) { $this->installationManager->notifyInstalls($this->io); } throw $e; } - if ($this->executeOperations && $this->config->get('notify-on-install')) { + if ($this->executeOperations && $this->install && $this->config->get('notify-on-install')) { $this->installationManager->notifyInstalls($this->io); } @@ -307,7 +311,7 @@ class Installer $this->autoloadGenerator->dump($this->config, $localRepo, $this->package, $this->installationManager, 'composer', $this->optimizeAutoloader); } - if ($this->executeOperations) { + if ($this->install && $this->executeOperations) { // force binaries re-generation in case they are missing foreach ($localRepo->getPackages() as $package) { $this->installationManager->ensureBinariesPresence($package); @@ -1018,6 +1022,19 @@ class Installer return $this; } + /** + * Allows disabling the install step after an update + * + * @param bool $install + * @return Installer + */ + public function setInstall($install = true) + { + $this->install = (bool) $install; + + return $this; + } + /** * enables dev packages *