1
0
Fork 0

Add --no-scripts to all commands and disable plugins/scripts when running self-update (#10371)

* Add --no-scripts as global parameter available to all commands, and handle it by default when creating a Composer instance from Command::getComposer

* Disable scripts/plugins for self-update command, fixes #10351
pull/10374/head
Jordi Boggiano 2021-12-20 14:23:35 +01:00 committed by GitHub
parent 24eac88321
commit 8f1b3d21db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 78 additions and 66 deletions

View File

@ -22,6 +22,7 @@ The following options are available with every command:
* **--quiet (-q):** Do not output any message. * **--quiet (-q):** Do not output any message.
* **--no-interaction (-n):** Do not ask any interactive question. * **--no-interaction (-n):** Do not ask any interactive question.
* **--no-plugins:** Disables plugins. * **--no-plugins:** Disables plugins.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-cache:** Disables the use of the cache directory. Same as setting the COMPOSER_CACHE_DIR * **--no-cache:** Disables the use of the cache directory. Same as setting the COMPOSER_CACHE_DIR
env var to /dev/null (or NUL on Windows). env var to /dev/null (or NUL on Windows).
* **--working-dir (-d):** If specified, use the given directory as working directory. * **--working-dir (-d):** If specified, use the given directory as working directory.
@ -100,7 +101,6 @@ resolution.
* **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader * **--no-dev:** Skip installing packages listed in `require-dev`. The autoloader
generation skips the `autoload-dev` rules. generation skips the `autoload-dev` rules.
* **--no-autoloader:** Skips autoloader generation. * **--no-autoloader:** Skips autoloader generation.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-progress:** Removes the progress display that can mess with some * **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters. terminals or scripts which don't handle backspace characters.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster * **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
@ -186,7 +186,6 @@ php composer.phar update vendor/package:2.0.1 vendor/package2:3.0.*
lock file being out of date. lock file being out of date.
* **--with:** Temporary version constraint to add, e.g. foo/bar:1.0.0 or foo/bar=1.0.0 * **--with:** Temporary version constraint to add, e.g. foo/bar:1.0.0 or foo/bar=1.0.0
* **--no-autoloader:** Skips autoloader generation. * **--no-autoloader:** Skips autoloader generation.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-progress:** Removes the progress display that can mess with some * **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters. terminals or scripts which don't handle backspace characters.
* **--with-dependencies (-w):** Update also dependencies of packages in the argument list, except those which are root requirements. * **--with-dependencies (-w):** Update also dependencies of packages in the argument list, except those which are root requirements.
@ -254,7 +253,6 @@ If you do not specify a package, Composer will prompt you to search for a packag
terminals or scripts which don't handle backspace characters. terminals or scripts which don't handle backspace characters.
* **--no-update:** Disables the automatic update of the dependencies (implies --no-install). * **--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-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-no-dev:** Run the dependency update with the `--no-dev` option.
* **--update-with-dependencies (-w):** Also update dependencies of the newly required packages, except those that are root requirements. * **--update-with-dependencies (-w):** Also update dependencies of the newly required packages, except those that are root requirements.
* **--update-with-all-dependencies (-W):** Also update dependencies of the newly required packages, including those that are root requirements. * **--update-with-all-dependencies (-W):** Also update dependencies of the newly required packages, including those that are root requirements.
@ -297,7 +295,6 @@ uninstalled.
terminals or scripts which don't handle backspace characters. terminals or scripts which don't handle backspace characters.
* **--no-update:** Disables the automatic update of the dependencies (implies --no-install). * **--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-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-no-dev:** Run the dependency update with the --no-dev option.
* **--update-with-dependencies (-w):** Also update dependencies of the removed packages. * **--update-with-dependencies (-w):** Also update dependencies of the removed packages.
(Deprecated, is now default behavior) (Deprecated, is now default behavior)
@ -348,7 +345,6 @@ php composer.phar reinstall "acme/*"
versions of packages, use `--prefer-install=auto`. See also [config.preferred-install](06-config.md#preferred-install). versions of packages, use `--prefer-install=auto`. See also [config.preferred-install](06-config.md#preferred-install).
Passing this flag will override the config value. Passing this flag will override the config value.
* **--no-autoloader:** Skips autoloader generation. * **--no-autoloader:** Skips autoloader generation.
* **--no-scripts:** Skips execution of scripts defined in `composer.json`.
* **--no-progress:** Removes the progress display that can mess with some * **--no-progress:** Removes the progress display that can mess with some
terminals or scripts which don't handle backspace characters. terminals or scripts which don't handle backspace characters.
* **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster * **--optimize-autoloader (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
@ -877,7 +873,6 @@ using this option you can still use PSR-0/4 for convenience and classmaps for
performance. performance.
### Options ### Options
* **--no-scripts:** Skips the execution of all scripts defined in the `composer.json` file.
* **--optimize (-o):** Convert PSR-0/4 autoloading to classmap to get a faster * **--optimize (-o):** Convert PSR-0/4 autoloading to classmap to get a faster
autoloader. This is recommended especially for production, but can take autoloader. This is recommended especially for production, but can take
a bit of time to run, so it is currently not done by default. a bit of time to run, so it is currently not done by default.

View File

@ -52,16 +52,17 @@ abstract class BaseCommand extends Command
/** /**
* @param bool $required * @param bool $required
* @param bool|null $disablePlugins * @param bool|null $disablePlugins
* @param bool|null $disableScripts
* @throws \RuntimeException * @throws \RuntimeException
* @return Composer|null * @return Composer|null
*/ */
public function getComposer($required = true, $disablePlugins = null) public function getComposer($required = true, $disablePlugins = null, $disableScripts = null)
{ {
if (null === $this->composer) { if (null === $this->composer) {
$application = $this->getApplication(); $application = $this->getApplication();
if ($application instanceof Application) { if ($application instanceof Application) {
/* @var $application Application */ /* @var $application Application */
$this->composer = $application->getComposer($required, $disablePlugins); $this->composer = $application->getComposer($required, $disablePlugins, $disableScripts);
/** @phpstan-ignore-next-line */ /** @phpstan-ignore-next-line */
} elseif ($required) { } elseif ($required) {
throw new \RuntimeException( throw new \RuntimeException(
@ -140,9 +141,15 @@ abstract class BaseCommand extends Command
{ {
// initialize a plugin-enabled Composer instance, either local or global // initialize a plugin-enabled Composer instance, either local or global
$disablePlugins = $input->hasParameterOption('--no-plugins'); $disablePlugins = $input->hasParameterOption('--no-plugins');
$composer = $this->getComposer(false, $disablePlugins); $disableScripts = $input->hasParameterOption('--no-scripts');
if ($this instanceof SelfUpdateCommand) {
$disablePlugins = true;
$disableScripts = true;
}
$composer = $this->getComposer(false, $disablePlugins, $disableScripts);
if (null === $composer) { if (null === $composer) {
$composer = Factory::createGlobal($this->getIO(), $disablePlugins); $composer = Factory::createGlobal($this->getIO(), $disablePlugins, $disableScripts);
} }
if ($composer) { if ($composer) {
$preCommandRunEvent = new PreCommandRunEvent(PluginEvents::PRE_COMMAND_RUN, $input, $this->getName()); $preCommandRunEvent = new PreCommandRunEvent(PluginEvents::PRE_COMMAND_RUN, $input, $this->getName());

View File

@ -170,25 +170,25 @@ EOT
} }
/** /**
* @param string|null $packageName * @param string|null $packageName
* @param string|null $directory * @param string|null $directory
* @param string|null $packageVersion * @param string|null $packageVersion
* @param string $stability * @param string $stability
* @param bool $preferSource * @param bool $preferSource
* @param bool $preferDist * @param bool $preferDist
* @param bool $installDevPackages * @param bool $installDevPackages
* @param string|array<string>|null $repositories * @param string|array<string>|null $repositories
* @param bool $disablePlugins * @param bool $disablePlugins
* @param bool $noScripts * @param bool $disableScripts
* @param bool $noProgress * @param bool $noProgress
* @param bool $noInstall * @param bool $noInstall
* @param bool $secureHttp * @param bool $secureHttp
* @param bool $addRepository * @param bool $addRepository
* *
* @return int * @return int
* @throws \Exception * @throws \Exception
*/ */
public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName = null, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositories = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $noInstall = false, PlatformRequirementFilterInterface $platformRequirementFilter = null, $secureHttp = true, $addRepository = false) public function installProject(IOInterface $io, Config $config, InputInterface $input, $packageName = null, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, $repositories = null, $disablePlugins = false, $disableScripts = false, $noProgress = false, $noInstall = false, PlatformRequirementFilterInterface $platformRequirementFilter = null, $secureHttp = true, $addRepository = false)
{ {
$oldCwd = getcwd(); $oldCwd = getcwd();
@ -204,7 +204,7 @@ EOT
$this->suggestedPackagesReporter = new SuggestedPackagesReporter($io); $this->suggestedPackagesReporter = new SuggestedPackagesReporter($io);
if ($packageName !== null) { if ($packageName !== null) {
$installedFromVcs = $this->installRootPackage($io, $config, $packageName, $platformRequirementFilter, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositories, $disablePlugins, $noScripts, $noProgress, $secureHttp); $installedFromVcs = $this->installRootPackage($io, $config, $packageName, $platformRequirementFilter, $directory, $packageVersion, $stability, $preferSource, $preferDist, $installDevPackages, $repositories, $disablePlugins, $disableScripts, $noProgress, $secureHttp);
} else { } else {
$installedFromVcs = false; $installedFromVcs = false;
} }
@ -213,8 +213,7 @@ EOT
unlink('composer.lock'); unlink('composer.lock');
} }
$composer = Factory::create($io, null, $disablePlugins); $composer = Factory::create($io, null, $disablePlugins, $disableScripts);
$composer->getEventDispatcher()->setRunScripts(!$noScripts);
// add the repository to the composer.json and use it for the install run later // add the repository to the composer.json and use it for the install run later
if ($repositories !== null && $addRepository) { if ($repositories !== null && $addRepository) {
@ -336,23 +335,23 @@ EOT
} }
/** /**
* @param string $packageName * @param string $packageName
* @param string|null $directory * @param string|null $directory
* @param string|null $packageVersion * @param string|null $packageVersion
* @param string|null $stability * @param string|null $stability
* @param bool $preferSource * @param bool $preferSource
* @param bool $preferDist * @param bool $preferDist
* @param bool $installDevPackages * @param bool $installDevPackages
* @param array<string>|null $repositories * @param array<string>|null $repositories
* @param bool $disablePlugins * @param bool $disablePlugins
* @param bool $noScripts * @param bool $disableScripts
* @param bool $noProgress * @param bool $noProgress
* @param bool $secureHttp * @param bool $secureHttp
* *
* @return bool * @return bool
* @throws \Exception * @throws \Exception
*/ */
protected function installRootPackage(IOInterface $io, Config $config, $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, array $repositories = null, $disablePlugins = false, $noScripts = false, $noProgress = false, $secureHttp = true) protected function installRootPackage(IOInterface $io, Config $config, $packageName, PlatformRequirementFilterInterface $platformRequirementFilter, $directory = null, $packageVersion = null, $stability = 'stable', $preferSource = false, $preferDist = false, $installDevPackages = false, array $repositories = null, $disablePlugins = false, $disableScripts = false, $noProgress = false, $secureHttp = true)
{ {
if (!$secureHttp) { if (!$secureHttp) {
$config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND); $config->merge(array('config' => array('secure-http' => false)), Config::SOURCE_COMMAND);

View File

@ -34,7 +34,6 @@ class DumpAutoloadCommand extends BaseCommand
->setAliases(array('dumpautoload')) ->setAliases(array('dumpautoload'))
->setDescription('Dumps the autoloader.') ->setDescription('Dumps the autoloader.')
->setDefinition(array( ->setDefinition(array(
new InputOption('no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'),
new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'), new InputOption('optimize', 'o', InputOption::VALUE_NONE, 'Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.'),
new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize`.'),
new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'), new InputOption('apcu', null, InputOption::VALUE_NONE, 'Use APCu to cache found/not-found classes.'),
@ -60,7 +59,6 @@ EOT
protected function execute(InputInterface $input, OutputInterface $output) protected function execute(InputInterface $input, OutputInterface $output)
{ {
$composer = $this->getComposer(); $composer = $this->getComposer();
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
$commandEvent = new CommandEvent(PluginEvents::COMMAND, 'dump-autoload', $input, $output); $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'dump-autoload', $input, $output);
$composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent); $composer->getEventDispatcher()->dispatch($commandEvent->getName(), $commandEvent);

View File

@ -48,7 +48,6 @@ class InstallCommand extends BaseCommand
new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'), new InputOption('no-suggest', null, InputOption::VALUE_NONE, 'DEPRECATED: This flag does not exist anymore.'),
new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'), new InputOption('no-dev', null, InputOption::VALUE_NONE, 'Disables installation of require-dev packages.'),
new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), 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-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('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('verbose', 'v|vv|vvv', InputOption::VALUE_NONE, 'Shows more details including new commits pulled in when updating packages.'),
@ -97,8 +96,7 @@ EOT
return 1; return 1;
} }
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
if ((!$composer->getLocker() || !$composer->getLocker()->isLocked()) && !HttpDownloader::isCurlEnabled()) { if ((!$composer->getLocker() || !$composer->getLocker()->isLocked()) && !HttpDownloader::isCurlEnabled()) {
$io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>'); $io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>');

View File

@ -44,7 +44,6 @@ class ReinstallCommand extends BaseCommand
new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'), new InputOption('prefer-dist', null, InputOption::VALUE_NONE, 'Forces installation from package dist (default behavior).'),
new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'), new InputOption('prefer-install', null, InputOption::VALUE_REQUIRED, 'Forces installation from package dist|source|auto (auto chooses source for dev versions, dist for the rest).'),
new InputOption('no-autoloader', null, InputOption::VALUE_NONE, 'Skips autoloader generation'), 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-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
new InputOption('optimize-autoloader', 'o', InputOption::VALUE_NONE, 'Optimize autoloader during autoloader dump'), 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`.'), new InputOption('classmap-authoritative', 'a', InputOption::VALUE_NONE, 'Autoload classes from the classmap only. Implicitly enables `--optimize-autoloader`.'),
@ -73,8 +72,7 @@ EOT
{ {
$io = $this->getIO(); $io = $this->getIO();
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
$localRepo = $composer->getRepositoryManager()->getLocalRepository(); $localRepo = $composer->getRepositoryManager()->getLocalRepository();
$packagesToReinstall = array(); $packagesToReinstall = array();

View File

@ -48,7 +48,6 @@ class RemoveCommand extends BaseCommand
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), 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 (implies --no-install).'), 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-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-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies. (Deprecrated, is now default behavior)'), new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated with explicit dependencies. (Deprecrated, is now default behavior)'),
new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'), new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'),
@ -217,8 +216,7 @@ EOT
// Update packages // Update packages
$this->resetComposer(); $this->resetComposer();
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
if ($dryRun) { if ($dryRun) {
$rootPackage = $composer->getPackage(); $rootPackage = $composer->getPackage();

View File

@ -77,7 +77,6 @@ class RequireCommand extends InitCommand
new InputOption('no-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'), 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 (implies --no-install).'), 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-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-no-dev', null, InputOption::VALUE_NONE, 'Run the dependency update with the --no-dev option.'),
new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated, except those that are root requirements.'), new InputOption('update-with-dependencies', 'w', InputOption::VALUE_NONE, 'Allows inherited dependencies to be updated, except those that are root requirements.'),
new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'), new InputOption('update-with-all-dependencies', 'W', InputOption::VALUE_NONE, 'Allows all inherited dependencies to be updated, including those that are root requirements.'),
@ -356,8 +355,7 @@ EOT
{ {
// Update packages // Update packages
$this->resetComposer(); $this->resetComposer();
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
$this->dependencyResolutionCompleted = false; $this->dependencyResolutionCompleted = false;
$composer->getEventDispatcher()->addListener(InstallerEvents::PRE_OPERATIONS_EXEC, array($this, 'markSolverComplete'), 10000); $composer->getEventDispatcher()->addListener(InstallerEvents::PRE_OPERATIONS_EXEC, array($this, 'markSolverComplete'), 10000);

View File

@ -59,7 +59,6 @@ class UpdateCommand extends BaseCommand
new InputOption('lock', null, InputOption::VALUE_NONE, 'Overwrites the lock file hash to suppress warning about the lock file being out of date without updating package versions. Package metadata like mirrors and URLs are updated if they changed.'), new InputOption('lock', null, InputOption::VALUE_NONE, 'Overwrites the lock file hash to suppress warning about the lock file being out of date without updating package versions. Package metadata like mirrors and URLs are updated if they changed.'),
new InputOption('no-install', null, InputOption::VALUE_NONE, 'Skip the install step after updating the composer.lock file.'), 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-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.'), 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-progress', null, InputOption::VALUE_NONE, 'Do not output download progress.'),
new InputOption('with-dependencies', 'w', InputOption::VALUE_NONE, 'Update also dependencies of packages in the argument list, except those which are root requirements.'), new InputOption('with-dependencies', 'w', InputOption::VALUE_NONE, 'Update also dependencies of packages in the argument list, except those which are root requirements.'),
@ -124,8 +123,7 @@ EOT
$io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>'); $io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>');
} }
$composer = $this->getComposer(true, $input->getOption('no-plugins')); $composer = $this->getComposer(true, $input->getOption('no-plugins'), $input->getOption('no-scripts'));
$composer->getEventDispatcher()->setRunScripts(!$input->getOption('no-scripts'));
if (!HttpDownloader::isCurlEnabled()) { if (!HttpDownloader::isCurlEnabled()) {
$io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>'); $io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>');

View File

@ -69,6 +69,8 @@ class Application extends BaseApplication
private $hasPluginCommands = false; private $hasPluginCommands = false;
/** @var bool */ /** @var bool */
private $disablePluginsByDefault = false; private $disablePluginsByDefault = false;
/** @var bool */
private $disableScriptsByDefault = false;
/** /**
* @var string Store the initial working directory at startup time * @var string Store the initial working directory at startup time
@ -134,6 +136,7 @@ class Application extends BaseApplication
public function doRun(InputInterface $input, OutputInterface $output) public function doRun(InputInterface $input, OutputInterface $output)
{ {
$this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins'); $this->disablePluginsByDefault = $input->hasParameterOption('--no-plugins');
$this->disableScriptsByDefault = $input->hasParameterOption('--no-scripts');
if (Platform::getEnv('COMPOSER_NO_INTERACTION') || !Platform::isTty(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'))) { if (Platform::getEnv('COMPOSER_NO_INTERACTION') || !Platform::isTty(defined('STDIN') ? STDIN : fopen('php://stdin', 'r'))) {
$input->setInteractive(false); $input->setInteractive(false);
@ -422,19 +425,23 @@ class Application extends BaseApplication
/** /**
* @param bool $required * @param bool $required
* @param bool|null $disablePlugins * @param bool|null $disablePlugins
* @param bool|null $disableScripts
* @throws JsonValidationException * @throws JsonValidationException
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @return ?\Composer\Composer If $required is true then the return value is guaranteed * @return ?\Composer\Composer If $required is true then the return value is guaranteed
*/ */
public function getComposer($required = true, $disablePlugins = null) public function getComposer($required = true, $disablePlugins = null, $disableScripts = null)
{ {
if (null === $disablePlugins) { if (null === $disablePlugins) {
$disablePlugins = $this->disablePluginsByDefault; $disablePlugins = $this->disablePluginsByDefault;
} }
if (null === $disableScripts) {
$disableScripts = $this->disableScriptsByDefault;
}
if (null === $this->composer) { if (null === $this->composer) {
try { try {
$this->composer = Factory::create($this->io, null, $disablePlugins); $this->composer = Factory::create($this->io, null, $disablePlugins, $disableScripts);
} catch (\InvalidArgumentException $e) { } catch (\InvalidArgumentException $e) {
if ($required) { if ($required) {
$this->io->writeError($e->getMessage()); $this->io->writeError($e->getMessage());
@ -552,6 +559,7 @@ class Application extends BaseApplication
$definition = parent::getDefaultInputDefinition(); $definition = parent::getDefaultInputDefinition();
$definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information')); $definition->addOption(new InputOption('--profile', null, InputOption::VALUE_NONE, 'Display timing and memory usage information'));
$definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.')); $definition->addOption(new InputOption('--no-plugins', null, InputOption::VALUE_NONE, 'Whether to disable plugins.'));
$definition->addOption(new InputOption('--no-scripts', null, InputOption::VALUE_NONE, 'Skips the execution of all scripts defined in composer.json file.'));
$definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.')); $definition->addOption(new InputOption('--working-dir', '-d', InputOption::VALUE_REQUIRED, 'If specified, use the given directory as working directory.'));
$definition->addOption(new InputOption('--no-cache', null, InputOption::VALUE_NONE, 'Prevent use of the cache')); $definition->addOption(new InputOption('--no-cache', null, InputOption::VALUE_NONE, 'Prevent use of the cache'));

View File

@ -294,13 +294,14 @@ class Factory
* @param array<string, mixed>|string|null $localConfig either a configuration array or a filename to read from, if null it will * @param array<string, mixed>|string|null $localConfig either a configuration array or a filename to read from, if null it will
* read from the default filename * read from the default filename
* @param bool $disablePlugins Whether plugins should not be loaded * @param bool $disablePlugins Whether plugins should not be loaded
* @param bool $disableScripts Whether scripts should not be run
* @param string|null $cwd * @param string|null $cwd
* @param bool $fullLoad Whether to initialize everything or only main project stuff (used when loading the global composer) * @param bool $fullLoad Whether to initialize everything or only main project stuff (used when loading the global composer)
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws \UnexpectedValueException * @throws \UnexpectedValueException
* @return Composer * @return Composer
*/ */
public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true) public function createComposer(IOInterface $io, $localConfig = null, $disablePlugins = false, $cwd = null, $fullLoad = true, $disableScripts = false)
{ {
$cwd = $cwd ?: (string) getcwd(); $cwd = $cwd ?: (string) getcwd();
@ -382,6 +383,7 @@ class Factory
// initialize event dispatcher // initialize event dispatcher
$dispatcher = new EventDispatcher($composer, $io, $process); $dispatcher = new EventDispatcher($composer, $io, $process);
$dispatcher->setRunScripts(!$disableScripts);
$composer->setEventDispatcher($dispatcher); $composer->setEventDispatcher($dispatcher);
// initialize repository manager // initialize repository manager
@ -428,7 +430,7 @@ class Factory
if ($fullLoad) { if ($fullLoad) {
$globalComposer = null; $globalComposer = null;
if (realpath($config->get('home')) !== $cwd) { if (realpath($config->get('home')) !== $cwd) {
$globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins); $globalComposer = $this->createGlobalComposer($io, $config, $disablePlugins, $disableScripts);
} }
$pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins); $pm = $this->createPluginManager($io, $composer, $globalComposer, $disablePlugins);
@ -460,13 +462,14 @@ class Factory
/** /**
* @param IOInterface $io IO instance * @param IOInterface $io IO instance
* @param bool $disablePlugins Whether plugins should not be loaded * @param bool $disablePlugins Whether plugins should not be loaded
* @param bool $disableScripts Whether scripts should not be executed
* @return Composer|null * @return Composer|null
*/ */
public static function createGlobal(IOInterface $io, $disablePlugins = false) public static function createGlobal(IOInterface $io, $disablePlugins = false, $disableScripts = false)
{ {
$factory = new static(); $factory = new static();
return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, true); return $factory->createGlobalComposer($io, static::createConfig($io), $disablePlugins, $disableScripts, true);
} }
/** /**
@ -487,15 +490,16 @@ class Factory
/** /**
* @param bool $disablePlugins * @param bool $disablePlugins
* @param bool $disableScripts
* @param bool $fullLoad * @param bool $fullLoad
* *
* @return Composer|null * @return Composer|null
*/ */
protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $fullLoad = false) protected function createGlobalComposer(IOInterface $io, Config $config, $disablePlugins, $disableScripts, $fullLoad = false)
{ {
$composer = null; $composer = null;
try { try {
$composer = $this->createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), $fullLoad); $composer = $this->createComposer($io, $config->get('home') . '/composer.json', $disablePlugins, $config->get('home'), $fullLoad, $disableScripts);
} catch (\Exception $e) { } catch (\Exception $e) {
$io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG); $io->writeError('Failed to initialize global composer: '.$e->getMessage(), true, IOInterface::DEBUG);
} }
@ -629,13 +633,14 @@ class Factory
* @param mixed $config either a configuration array or a filename to read from, if null it will read from * @param mixed $config either a configuration array or a filename to read from, if null it will read from
* the default filename * the default filename
* @param bool $disablePlugins Whether plugins should not be loaded * @param bool $disablePlugins Whether plugins should not be loaded
* @param bool $disableScripts Whether scripts should not be run
* @return Composer * @return Composer
*/ */
public static function create(IOInterface $io, $config = null, $disablePlugins = false) public static function create(IOInterface $io, $config = null, $disablePlugins = false, $disableScripts = false)
{ {
$factory = new static(); $factory = new static();
return $factory->createComposer($io, $config, $disablePlugins); return $factory->createComposer($io, $config, $disablePlugins, null, true, $disableScripts);
} }
/** /**

View File

@ -40,6 +40,11 @@ class ApplicationTest extends TestCase
->with($this->equalTo('--no-plugins')) ->with($this->equalTo('--no-plugins'))
->will($this->returnValue(true)); ->will($this->returnValue(true));
$inputMock->expects($this->at($index++))
->method('hasParameterOption')
->with($this->equalTo('--no-scripts'))
->will($this->returnValue(false));
$inputMock->expects($this->at($index++)) $inputMock->expects($this->at($index++))
->method('setInteractive') ->method('setInteractive')
->with($this->equalTo(false)); ->with($this->equalTo(false));
@ -108,6 +113,11 @@ class ApplicationTest extends TestCase
->with($this->equalTo('--no-plugins')) ->with($this->equalTo('--no-plugins'))
->will($this->returnValue(true)); ->will($this->returnValue(true));
$inputMock->expects($this->at($index++))
->method('hasParameterOption')
->with($this->equalTo('--no-scripts'))
->will($this->returnValue(false));
$inputMock->expects($this->at($index++)) $inputMock->expects($this->at($index++))
->method('setInteractive') ->method('setInteractive')
->with($this->equalTo(false)); ->with($this->equalTo(false));