Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. UpdateCommand.php

function UpdateCommand::execute

Overrides Command::execute

File

vendor/composer/composer/src/Composer/Command/UpdateCommand.php, line 126

Class

UpdateCommand
@author Jordi Boggiano <j.boggiano@seld.be> @author Nils Adermann <naderman@naderman.de>

Namespace

Composer\Command

Code

protected function execute(InputInterface $input, OutputInterface $output) : int {
    $io = $this->getIO();
    if ($input->getOption('dev')) {
        $io->writeError('<warning>You are using the deprecated option "--dev". It has no effect and will break in Composer 3.</warning>');
    }
    if ($input->getOption('no-suggest')) {
        $io->writeError('<warning>You are using the deprecated option "--no-suggest". It has no effect and will break in Composer 3.</warning>');
    }
    $composer = $this->requireComposer();
    if (!HttpDownloader::isCurlEnabled()) {
        $io->writeError('<warning>Composer is operating significantly slower than normal because you do not have the PHP curl extension enabled.</warning>');
    }
    $packages = $input->getArgument('packages');
    $reqs = $this->formatRequirements($input->getOption('with'));
    // extract --with shorthands from the allowlist
    if (count($packages) > 0) {
        $allowlistPackagesWithRequirements = array_filter($packages, static function ($pkg) : bool {
            return Preg::isMatch('{\\S+[ =:]\\S+}', $pkg);
        });
        foreach ($this->formatRequirements($allowlistPackagesWithRequirements) as $package => $constraint) {
            $reqs[$package] = $constraint;
        }
        // replace the foo/bar:req by foo/bar in the allowlist
        foreach ($allowlistPackagesWithRequirements as $package) {
            $packageName = Preg::replace('{^([^ =:]+)[ =:].*$}', '$1', $package);
            $index = array_search($package, $packages);
            $packages[$index] = $packageName;
        }
    }
    $rootPackage = $composer->getPackage();
    $rootPackage->setReferences(RootPackageLoader::extractReferences($reqs, $rootPackage->getReferences()));
    $rootPackage->setStabilityFlags(RootPackageLoader::extractStabilityFlags($reqs, $rootPackage->getMinimumStability(), $rootPackage->getStabilityFlags()));
    $parser = new VersionParser();
    $temporaryConstraints = [];
    $rootRequirements = array_merge($rootPackage->getRequires(), $rootPackage->getDevRequires());
    foreach ($reqs as $package => $constraint) {
        $package = strtolower($package);
        $parsedConstraint = $parser->parseConstraints($constraint);
        $temporaryConstraints[$package] = $parsedConstraint;
        if (isset($rootRequirements[$package]) && !Intervals::haveIntersections($parsedConstraint, $rootRequirements[$package]->getConstraint())) {
            $io->writeError('<error>The temporary constraint "' . $constraint . '" for "' . $package . '" must be a subset of the constraint in your composer.json (' . $rootRequirements[$package]->getPrettyConstraint() . ')</error>');
            $io->write('<info>Run `composer require ' . $package . '` or `composer require ' . $package . ':' . $constraint . '` instead to replace the constraint</info>');
            return self::FAILURE;
        }
    }
    if ($input->getOption('patch-only')) {
        if (!$composer->getLocker()
            ->isLocked()) {
            throw new \InvalidArgumentException('patch-only can only be used with a lock file present');
        }
        foreach ($composer->getLocker()
            ->getLockedRepository(true)
            ->getCanonicalPackages() as $package) {
            if ($package->isDev()) {
                continue;
            }
            if (!Preg::isMatch('{^(\\d+\\.\\d+\\.\\d+)}', $package->getVersion(), $match)) {
                continue;
            }
            $constraint = $parser->parseConstraints('~' . $match[1]);
            if (isset($temporaryConstraints[$package->getName()])) {
                $temporaryConstraints[$package->getName()] = MultiConstraint::create([
                    $temporaryConstraints[$package->getName()],
                    $constraint,
                ], true);
            }
            else {
                $temporaryConstraints[$package->getName()] = $constraint;
            }
        }
    }
    if ($input->getOption('interactive')) {
        $packages = $this->getPackagesInteractively($io, $input, $output, $composer, $packages);
    }
    if ($input->getOption('root-reqs')) {
        $requires = array_keys($rootPackage->getRequires());
        if (!$input->getOption('no-dev')) {
            $requires = array_merge($requires, array_keys($rootPackage->getDevRequires()));
        }
        if (!empty($packages)) {
            $packages = array_intersect($packages, $requires);
        }
        else {
            $packages = $requires;
        }
    }
    // the arguments lock/nothing/mirrors are not package names but trigger a mirror update instead
    // they are further mutually exclusive with listing actual package names
    $filteredPackages = array_filter($packages, static function ($package) : bool {
        return !in_array($package, [
            'lock',
            'nothing',
            'mirrors',
        ], true);
    });
    $updateMirrors = $input->getOption('lock') || count($filteredPackages) !== count($packages);
    $packages = $filteredPackages;
    if ($updateMirrors && !empty($packages)) {
        $io->writeError('<error>You cannot simultaneously update only a selection of packages and regenerate the lock file metadata.</error>');
        return -1;
    }
    $commandEvent = new CommandEvent(PluginEvents::COMMAND, 'update', $input, $output);
    $composer->getEventDispatcher()
        ->dispatch($commandEvent->getName(), $commandEvent);
    $composer->getInstallationManager()
        ->setOutputProgress(!$input->getOption('no-progress'));
    $install = Installer::create($io, $composer);
    $config = $composer->getConfig();
    [
        $preferSource,
        $preferDist,
    ] = $this->getPreferredInstallOptions($config, $input);
    $optimize = $input->getOption('optimize-autoloader') || $config->get('optimize-autoloader');
    $authoritative = $input->getOption('classmap-authoritative') || $config->get('classmap-authoritative');
    $apcuPrefix = $input->getOption('apcu-autoloader-prefix');
    $apcu = $apcuPrefix !== null || $input->getOption('apcu-autoloader') || $config->get('apcu-autoloader');
    $updateAllowTransitiveDependencies = Request::UPDATE_ONLY_LISTED;
    if ($input->getOption('with-all-dependencies')) {
        $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS;
    }
    elseif ($input->getOption('with-dependencies')) {
        $updateAllowTransitiveDependencies = Request::UPDATE_LISTED_WITH_TRANSITIVE_DEPS_NO_ROOT_REQUIRE;
    }
    $install->setDryRun($input->getOption('dry-run'))
        ->setVerbose($input->getOption('verbose'))
        ->setPreferSource($preferSource)
        ->setPreferDist($preferDist)
        ->setDevMode(!$input->getOption('no-dev'))
        ->setDumpAutoloader(!$input->getOption('no-autoloader'))
        ->setOptimizeAutoloader($optimize)
        ->setClassMapAuthoritative($authoritative)
        ->setApcuAutoloader($apcu, $apcuPrefix)
        ->setUpdate(true)
        ->setInstall(!$input->getOption('no-install'))
        ->setUpdateMirrors($updateMirrors)
        ->setUpdateAllowList($packages)
        ->setUpdateAllowTransitiveDependencies($updateAllowTransitiveDependencies)
        ->setPlatformRequirementFilter($this->getPlatformRequirementFilter($input))
        ->setPreferStable($input->getOption('prefer-stable'))
        ->setPreferLowest($input->getOption('prefer-lowest'))
        ->setTemporaryConstraints($temporaryConstraints)
        ->setAudit(!$input->getOption('no-audit'))
        ->setAuditFormat($this->getAuditFormat($input))
        ->setMinimalUpdate($input->getOption('minimal-changes'));
    if ($input->getOption('no-plugins')) {
        $install->disablePlugins();
    }
    $result = $install->run();
    if ($result === 0) {
        $bumpAfterUpdate = $input->getOption('bump-after-update');
        if (false === $bumpAfterUpdate) {
            $bumpAfterUpdate = $composer->getConfig()
                ->get('bump-after-update');
        }
        if (false !== $bumpAfterUpdate) {
            $io->writeError('<info>Bumping dependencies</info>');
            $bumpCommand = new BumpCommand();
            $bumpCommand->setComposer($composer);
            $result = $bumpCommand->doBump($io, $bumpAfterUpdate === 'dev', $bumpAfterUpdate === 'no-dev', $input->getOption('dry-run'), $input->getArgument('packages'));
        }
    }
    return $result;
}
RSS feed
Powered by Drupal