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

Breadcrumb

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

function Installer::doInstall

@phpstan-return self::ERROR_*

Parameters

bool $alreadySolved Whether the function is called as part of an update command or independently:

Return value

int exit code

2 calls to Installer::doInstall()
Installer::doUpdate in vendor/composer/composer/src/Composer/Installer.php
@phpstan-return self::ERROR_*
Installer::run in vendor/composer/composer/src/Composer/Installer.php
Run installation (or update)

File

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

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 doInstall(InstalledRepositoryInterface $localRepo, bool $alreadySolved = false) : int {
    if ($this->config
        ->get('lock')) {
        $this->io
            ->writeError('<info>Installing dependencies from lock file' . ($this->devMode ? ' (including require-dev)' : '') . '</info>');
    }
    $lockedRepository = $this->locker
        ->getLockedRepository($this->devMode);
    // verify that the lock file works with the current platform repository
    // we can skip this part if we're doing this as the second step after an update
    if (!$alreadySolved) {
        $this->io
            ->writeError('<info>Verifying lock file contents can be installed on current platform.</info>');
        $platformRepo = $this->createPlatformRepo(false);
        // creating repository set
        $policy = $this->createPolicy(false);
        // use aliases from lock file only, so empty root aliases here
        $repositorySet = $this->createRepositorySet(false, $platformRepo, [], $lockedRepository);
        $repositorySet->addRepository($lockedRepository);
        // creating requirements request
        $request = $this->createRequest($this->fixedRootPackage, $platformRepo, $lockedRepository);
        if (!$this->locker
            ->isFresh()) {
            $this->io
                ->writeError('<warning>Warning: The lock file is not up to date with the latest changes in composer.json. You may be getting outdated dependencies. It is recommended that you run `composer update` or `composer update <package name>`.</warning>', true, IOInterface::QUIET);
        }
        $missingRequirementInfo = $this->locker
            ->getMissingRequirementInfo($this->package, $this->devMode);
        if ($missingRequirementInfo !== []) {
            $this->io
                ->writeError($missingRequirementInfo);
            if (!$this->config
                ->get('allow-missing-requirements')) {
                return self::ERROR_LOCK_FILE_INVALID;
            }
        }
        foreach ($lockedRepository->getPackages() as $package) {
            $request->fixLockedPackage($package);
        }
        $rootRequires = $this->package
            ->getRequires();
        if ($this->devMode) {
            $rootRequires = array_merge($rootRequires, $this->package
                ->getDevRequires());
        }
        foreach ($rootRequires as $link) {
            if (PlatformRepository::isPlatformPackage($link->getTarget())) {
                $request->requireName($link->getTarget(), $link->getConstraint());
            }
        }
        foreach ($this->locker
            ->getPlatformRequirements($this->devMode) as $link) {
            if (!isset($rootRequires[$link->getTarget()])) {
                $request->requireName($link->getTarget(), $link->getConstraint());
            }
        }
        unset($rootRequires, $link);
        $pool = $repositorySet->createPool($request, $this->io, $this->eventDispatcher, null, $this->ignoredTypes, $this->allowedTypes);
        // solve dependencies
        $solver = new Solver($policy, $pool, $this->io);
        try {
            $lockTransaction = $solver->solve($request, $this->platformRequirementFilter);
            $solver = null;
            // installing the locked packages on this platform resulted in lock modifying operations, there wasn't a conflict, but the lock file as-is seems to not work on this system
            if (0 !== count($lockTransaction->getOperations())) {
                $this->io
                    ->writeError('<error>Your lock file cannot be installed on this system without changes. Please run composer update.</error>', true, IOInterface::QUIET);
                return self::ERROR_LOCK_FILE_INVALID;
            }
        } catch (SolverProblemsException $e) {
            $err = 'Your lock file does not contain a compatible set of packages. Please run composer update.';
            $prettyProblem = $e->getPrettyString($repositorySet, $request, $pool, $this->io
                ->isVerbose());
            $this->io
                ->writeError('<error>' . $err . '</error>', true, IOInterface::QUIET);
            $this->io
                ->writeError($prettyProblem);
            $ghe = new GithubActionError($this->io);
            $ghe->emit($err . "\n" . $prettyProblem);
            return max(self::ERROR_GENERIC_FAILURE, $e->getCode());
        }
    }
    // TODO in how far do we need to do anything here to ensure dev packages being updated to latest in lock without version change are treated correctly?
    $localRepoTransaction = new LocalRepoTransaction($lockedRepository, $localRepo);
    $this->eventDispatcher
        ->dispatchInstallerEvent(InstallerEvents::PRE_OPERATIONS_EXEC, $this->devMode, $this->executeOperations, $localRepoTransaction);
    $installs = $updates = $uninstalls = [];
    foreach ($localRepoTransaction->getOperations() as $operation) {
        if ($operation instanceof InstallOperation) {
            $installs[] = $operation->getPackage()
                ->getPrettyName() . ':' . $operation->getPackage()
                ->getFullPrettyVersion();
        }
        elseif ($operation instanceof UpdateOperation) {
            $updates[] = $operation->getTargetPackage()
                ->getPrettyName() . ':' . $operation->getTargetPackage()
                ->getFullPrettyVersion();
        }
        elseif ($operation instanceof UninstallOperation) {
            $uninstalls[] = $operation->getPackage()
                ->getPrettyName();
        }
    }
    if ($installs === [] && $updates === [] && $uninstalls === []) {
        $this->io
            ->writeError('Nothing to install, update or remove');
    }
    else {
        $this->io
            ->writeError(sprintf("<info>Package operations: %d install%s, %d update%s, %d removal%s</info>", count($installs), 1 === count($installs) ? '' : 's', count($updates), 1 === count($updates) ? '' : 's', count($uninstalls), 1 === count($uninstalls) ? '' : 's'));
        if ($installs) {
            $this->io
                ->writeError("Installs: " . implode(', ', $installs), true, IOInterface::VERBOSE);
        }
        if ($updates) {
            $this->io
                ->writeError("Updates: " . implode(', ', $updates), true, IOInterface::VERBOSE);
        }
        if ($uninstalls) {
            $this->io
                ->writeError("Removals: " . implode(', ', $uninstalls), true, IOInterface::VERBOSE);
        }
    }
    if ($this->executeOperations) {
        $localRepo->setDevPackageNames($this->locker
            ->getDevPackageNames());
        $this->installationManager
            ->execute($localRepo, $localRepoTransaction->getOperations(), $this->devMode, $this->runScripts, $this->downloadOnly);
        // see https://github.com/composer/composer/issues/2764
        if (count($localRepoTransaction->getOperations()) > 0) {
            $vendorDir = $this->config
                ->get('vendor-dir');
            if (is_dir($vendorDir)) {
                // suppress errors as this fails sometimes on OSX for no apparent reason
                // see https://github.com/composer/composer/issues/4070#issuecomment-129792748
                @touch($vendorDir);
            }
        }
    }
    else {
        foreach ($localRepoTransaction->getOperations() as $operation) {
            // output op, but alias op only in debug verbosity
            if (false === strpos($operation->getOperationType(), 'Alias') || $this->io
                ->isDebug()) {
                $this->io
                    ->writeError('  - ' . $operation->show(false));
            }
        }
    }
    return 0;
}

API Navigation

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