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

Breadcrumb

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

function Installer::doUpdate

@phpstan-return self::ERROR_*

1 call to Installer::doUpdate()
Installer::run in vendor/composer/composer/src/Composer/Installer.php
Run installation (or update)

File

vendor/composer/composer/src/Composer/Installer.php, line 454

Class

Installer
@author Jordi Boggiano <j.boggiano@seld.be> @author Beau Simensen <beau@dflydev.com> @author Konstantin Kudryashov <ever.zet@gmail.com> @author Nils Adermann <naderman@naderman.de>

Namespace

Composer

Code

protected function doUpdate(InstalledRepositoryInterface $localRepo, bool $doInstall) : int {
    $platformRepo = $this->createPlatformRepo(true);
    $aliases = $this->getRootAliases(true);
    $lockedRepository = null;
    try {
        if ($this->locker
            ->isLocked()) {
            $lockedRepository = $this->locker
                ->getLockedRepository(true);
        }
    } catch (\Seld\JsonLint\ParsingException $e) {
        if ($this->updateAllowList !== null || $this->updateMirrors) {
            // in case we are doing a partial update or updating mirrors, the lock file is needed so we error
            throw $e;
        }
        // otherwise, ignoring parse errors as the lock file will be regenerated from scratch when
        // doing a full update
    }
    if (($this->updateAllowList !== null || $this->updateMirrors) && !$lockedRepository) {
        $this->io
            ->writeError('<error>Cannot update ' . ($this->updateMirrors ? 'lock file information' : 'only a partial set of packages') . ' without a lock file present. Run `composer update` to generate a lock file.</error>', true, IOInterface::QUIET);
        return self::ERROR_NO_LOCK_FILE_FOR_PARTIAL_UPDATE;
    }
    $this->io
        ->writeError('<info>Loading composer repositories with package information</info>');
    // creating repository set
    $policy = $this->createPolicy(true, $lockedRepository);
    $repositorySet = $this->createRepositorySet(true, $platformRepo, $aliases);
    $repositories = $this->repositoryManager
        ->getRepositories();
    foreach ($repositories as $repository) {
        $repositorySet->addRepository($repository);
    }
    if ($lockedRepository) {
        $repositorySet->addRepository($lockedRepository);
    }
    $request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
    $this->requirePackagesForUpdate($request, $lockedRepository, true);
    // pass the allow list into the request, so the pool builder can apply it
    if ($this->updateAllowList !== null) {
        $request->setUpdateAllowList($this->updateAllowList, $this->updateAllowTransitiveDependencies);
    }
    $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, $this->createPoolOptimizer($policy), $this->ignoredTypes, $this->allowedTypes);
    $this->io
        ->writeError('<info>Updating dependencies</info>');
    // solve dependencies
    $solver = new Solver($policy, $pool, $this->io);
    try {
        $lockTransaction = $solver->solve($request, $this->platformRequirementFilter);
        $ruleSetSize = $solver->getRuleSetSize();
        $solver = null;
    } catch (SolverProblemsException $e) {
        $err = 'Your requirements could not be resolved to an installable set of packages.';
        $prettyProblem = $e->getPrettyString($repositorySet, $request, $pool, $this->io
            ->isVerbose());
        $this->io
            ->writeError('<error>' . $err . '</error>', true, IOInterface::QUIET);
        $this->io
            ->writeError($prettyProblem);
        if (!$this->devMode) {
            $this->io
                ->writeError('<warning>Running update with --no-dev does not mean require-dev is ignored, it just means the packages will not be installed. If dev requirements are blocking the update you have to resolve those problems.</warning>', true, IOInterface::QUIET);
        }
        $ghe = new GithubActionError($this->io);
        $ghe->emit($err . "\n" . $prettyProblem);
        return max(self::ERROR_GENERIC_FAILURE, $e->getCode());
    }
    $this->io
        ->writeError("Analyzed " . count($pool) . " packages to resolve dependencies", true, IOInterface::VERBOSE);
    $this->io
        ->writeError("Analyzed " . $ruleSetSize . " rules to resolve dependencies", true, IOInterface::VERBOSE);
    $pool = null;
    if (!$lockTransaction->getOperations()) {
        $this->io
            ->writeError('Nothing to modify in lock file');
    }
    $exitCode = $this->extractDevPackages($lockTransaction, $platformRepo, $aliases, $policy, $lockedRepository);
    if ($exitCode !== 0) {
        return $exitCode;
    }
    \Composer\Semver\CompilingMatcher::clear();
    // write lock
    $platformReqs = $this->extractPlatformRequirements($this->package
        ->getRequires());
    $platformDevReqs = $this->extractPlatformRequirements($this->package
        ->getDevRequires());
    $installsUpdates = $uninstalls = [];
    if ($lockTransaction->getOperations()) {
        $installNames = $updateNames = $uninstallNames = [];
        foreach ($lockTransaction->getOperations() as $operation) {
            if ($operation instanceof InstallOperation) {
                $installsUpdates[] = $operation;
                $installNames[] = $operation->getPackage()
                    ->getPrettyName() . ':' . $operation->getPackage()
                    ->getFullPrettyVersion();
            }
            elseif ($operation instanceof UpdateOperation) {
                // when mirrors/metadata from a package gets updated we do not want to list it as an
                // update in the output as it is only an internal lock file metadata update
                if ($this->updateMirrors && $operation->getInitialPackage()
                    ->getName() === $operation->getTargetPackage()
                    ->getName() && $operation->getInitialPackage()
                    ->getVersion() === $operation->getTargetPackage()
                    ->getVersion()) {
                    continue;
                }
                $installsUpdates[] = $operation;
                $updateNames[] = $operation->getTargetPackage()
                    ->getPrettyName() . ':' . $operation->getTargetPackage()
                    ->getFullPrettyVersion();
            }
            elseif ($operation instanceof UninstallOperation) {
                $uninstalls[] = $operation;
                $uninstallNames[] = $operation->getPackage()
                    ->getPrettyName();
            }
        }
        if ($this->config
            ->get('lock')) {
            $this->io
                ->writeError(sprintf("<info>Lock file operations: %d install%s, %d update%s, %d removal%s</info>", count($installNames), 1 === count($installNames) ? '' : 's', count($updateNames), 1 === count($updateNames) ? '' : 's', count($uninstalls), 1 === count($uninstalls) ? '' : 's'));
            if ($installNames) {
                $this->io
                    ->writeError("Installs: " . implode(', ', $installNames), true, IOInterface::VERBOSE);
            }
            if ($updateNames) {
                $this->io
                    ->writeError("Updates: " . implode(', ', $updateNames), true, IOInterface::VERBOSE);
            }
            if ($uninstalls) {
                $this->io
                    ->writeError("Removals: " . implode(', ', $uninstallNames), true, IOInterface::VERBOSE);
            }
        }
    }
    $sortByName = static function ($a, $b) : int {
        if ($a instanceof UpdateOperation) {
            $a = $a->getTargetPackage()
                ->getName();
        }
        else {
            $a = $a->getPackage()
                ->getName();
        }
        if ($b instanceof UpdateOperation) {
            $b = $b->getTargetPackage()
                ->getName();
        }
        else {
            $b = $b->getPackage()
                ->getName();
        }
        return strcmp($a, $b);
    };
    usort($uninstalls, $sortByName);
    usort($installsUpdates, $sortByName);
    foreach (array_merge($uninstalls, $installsUpdates) as $operation) {
        // collect suggestions
        if ($operation instanceof InstallOperation) {
            $this->suggestedPackagesReporter
                ->addSuggestionsFromPackage($operation->getPackage());
        }
        // output op if lock file is enabled, but alias op only in debug verbosity
        if ($this->config
            ->get('lock') && (false === strpos($operation->getOperationType(), 'Alias') || $this->io
            ->isDebug())) {
            $sourceRepo = '';
            if ($this->io
                ->isVeryVerbose() && false === strpos($operation->getOperationType(), 'Alias')) {
                $operationPkg = $operation instanceof UpdateOperation ? $operation->getTargetPackage() : $operation->getPackage();
                if ($operationPkg->getRepository() !== null) {
                    $sourceRepo = ' from ' . $operationPkg->getRepository()
                        ->getRepoName();
                }
            }
            $this->io
                ->writeError('  - ' . $operation->show(true) . $sourceRepo);
        }
    }
    $updatedLock = $this->locker
        ->setLockData($lockTransaction->getNewLockPackages(false, $this->updateMirrors), $lockTransaction->getNewLockPackages(true, $this->updateMirrors), $platformReqs, $platformDevReqs, $lockTransaction->getAliases($aliases), $this->package
        ->getMinimumStability(), $this->package
        ->getStabilityFlags(), $this->preferStable || $this->package
        ->getPreferStable(), $this->preferLowest, $this->config
        ->get('platform') ?: [], $this->writeLock && $this->executeOperations);
    if ($updatedLock && $this->writeLock && $this->executeOperations) {
        $this->io
            ->writeError('<info>Writing lock file</info>');
    }
    if ($doInstall) {
        // TODO ensure lock is used from locker as-is, since it may not have been written to disk in case of executeOperations == false
        return $this->doInstall($localRepo, true);
    }
    return 0;
}

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal