/** * * @param PackageInterface $package * * @return string a path relative to the root of the composer.json that is being installed. */ public function getInstallPath(PackageInterface $package) { // custom install path only when it is the keeko/keeko package if ($this->root->getName() == 'keeko/keeko') { return 'packages/' . $package->getName(); } // ... anyway return the default return parent::getInstallPath($package); }
/** * Initialize the installed package. */ private function initInstalledPackages() { /* @var PackageInterface $package */ foreach ($this->installedRepository->getPackages() as $package) { $operator = $this->getFilterOperator($package); /* @var Link $link */ $link = current($this->arrayLoader->parseLinks($this->package->getName(), $this->package->getVersion(), 'installed', array($package->getName() => $operator . $package->getPrettyVersion()))); $link = $this->includeRootConstraint($package, $link); $this->requires[$package->getName()] = $link; } }
protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false) { $minimumStability = $this->package->getMinimumStability(); $stabilityFlags = $this->package->getStabilityFlags(); // init vars $lockedRepository = null; $repositories = null; // initialize locker to create aliased packages $installFromLock = false; if (!$this->update && $this->locker->isLocked($devMode)) { $installFromLock = true; $lockedRepository = $this->locker->getLockedRepository($devMode); $minimumStability = $this->locker->getMinimumStability(); $stabilityFlags = $this->locker->getStabilityFlags(); } $this->whitelistUpdateDependencies($localRepo, $devMode, $this->package->getRequires(), $this->package->getDevRequires()); $this->io->write('<info>Loading composer repositories with package information</info>'); // creating repository pool $policy = new DefaultPolicy(); $pool = new Pool($minimumStability, $stabilityFlags); $pool->addRepository($installedRepo, $aliases); if ($installFromLock) { $pool->addRepository($lockedRepository, $aliases); } if (!$installFromLock || !$this->locker->isCompleteFormat($devMode)) { $repositories = $this->repositoryManager->getRepositories(); foreach ($repositories as $repository) { $pool->addRepository($repository, $aliases); } } // creating requirements request $request = new Request($pool); $constraint = new VersionConstraint('=', $this->package->getVersion()); $constraint->setPrettyString($this->package->getPrettyVersion()); $request->install($this->package->getName(), $constraint); if ($this->update) { $this->io->write('<info>Updating ' . ($devMode ? 'dev ' : '') . 'dependencies</info>'); $request->updateAll(); $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires(); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } elseif ($installFromLock) { $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies from lock file</info>'); if (!$this->locker->isCompleteFormat($devMode)) { $this->io->write('<warning>Warning: Your lock file is in a deprecated format. It will most likely take a *long* time for composer to install dependencies, and may cause dependency solving issues.</warning>'); } if (!$this->locker->isFresh() && !$devMode) { $this->io->write('<warning>Warning: The lock file is not up to date with the latest changes in composer.json, you may be getting outdated dependencies, run update to update them.</warning>'); } foreach ($lockedRepository->getPackages() as $package) { $version = $package->getVersion(); if (isset($aliases[$package->getName()][$version])) { $version = $aliases[$package->getName()][$version]['alias_normalized']; } $constraint = new VersionConstraint('=', $version); $constraint->setPrettyString($package->getPrettyVersion()); $request->install($package->getName(), $constraint); } } else { $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies</info>'); $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires(); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } // fix the version of all installed packages (+ platform) that are not // in the current local repo to prevent rogue updates (e.g. non-dev // updating when in dev) foreach ($installedRepo->getPackages() as $package) { if ($package->getRepository() === $localRepo) { continue; } $constraint = new VersionConstraint('=', $package->getVersion()); $constraint->setPrettyString($package->getPrettyVersion()); $request->install($package->getName(), $constraint); } // if the updateWhitelist is enabled, packages not in it are also fixed // to the version specified in the lock, or their currently installed version if ($this->update && $this->updateWhitelist) { if ($this->locker->isLocked($devMode)) { $currentPackages = $this->locker->getLockedRepository($devMode)->getPackages(); } else { $currentPackages = $installedRepo->getPackages(); } // collect links from composer as well as installed packages $candidates = array(); foreach ($links as $link) { $candidates[$link->getTarget()] = true; } foreach ($localRepo->getPackages() as $package) { $candidates[$package->getName()] = true; } // fix them to the version in lock (or currently installed) if they are not updateable foreach ($candidates as $candidate => $dummy) { foreach ($currentPackages as $curPackage) { if ($curPackage->getName() === $candidate) { if ($this->isUpdateable($curPackage)) { break; } $constraint = new VersionConstraint('=', $curPackage->getVersion()); $request->install($curPackage->getName(), $constraint); } } } } // force dev packages to have the latest links if we update or install from a (potentially new) lock $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-links'); // solve dependencies $solver = new Solver($policy, $pool, $installedRepo); try { $operations = $solver->solve($request); } catch (SolverProblemsException $e) { $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>'); $this->io->write($e->getMessage()); return false; } if ($devMode) { // remove bogus operations that the solver creates for stuff that was force-updated in the non-dev pass // TODO this should not be necessary ideally, but it seems to work around the problem quite well foreach ($operations as $index => $op) { if ('update' === $op->getJobType() && $op->getInitialPackage()->getUniqueName() === $op->getTargetPackage()->getUniqueName() && $op->getInitialPackage()->getSourceReference() === $op->getTargetPackage()->getSourceReference() && $op->getInitialPackage()->getDistReference() === $op->getTargetPackage()->getDistReference()) { unset($operations[$index]); } } } // force dev packages to be updated if we update or install from a (potentially new) lock $operations = $this->processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, 'force-updates', $operations); // execute operations if (!$operations) { $this->io->write('Nothing to install or update'); } foreach ($operations as $operation) { // collect suggestions if ('install' === $operation->getJobType()) { foreach ($operation->getPackage()->getSuggests() as $target => $reason) { $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason); } } $event = 'Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType()); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation); } // not installing from lock, force dev packages' references if they're in root package refs if (!$installFromLock) { $package = null; if ('update' === $operation->getJobType()) { $package = $operation->getTargetPackage(); } elseif ('install' === $operation->getJobType()) { $package = $operation->getPackage(); } if ($package && $package->isDev()) { $references = $this->package->getReferences(); if (isset($references[$package->getName()])) { $package->setSourceReference($references[$package->getName()]); $package->setDistReference($references[$package->getName()]); } } } // output alias operations in verbose mode, or all ops in dry run if ($this->dryRun || $this->verbose && false !== strpos($operation->getJobType(), 'Alias')) { $this->io->write(' - ' . $operation); } $this->installationManager->execute($localRepo, $operation); $event = 'Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType()); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $this->devMode, $operation); } if (!$this->dryRun) { $localRepo->write(); } } return true; }
private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo) { $request = new Request($pool); $constraint = new VersionConstraint('=', $rootPackage->getVersion()); $constraint->setPrettyString($rootPackage->getPrettyVersion()); $request->install($rootPackage->getName(), $constraint); $fixedPackages = $platformRepo->getPackages(); if ($this->additionalInstalledRepository) { $additionalFixedPackages = $this->additionalInstalledRepository->getPackages(); $fixedPackages = array_merge($fixedPackages, $additionalFixedPackages); } // fix the version of all platform packages + additionally installed packages // to prevent the solver trying to remove or update those $provided = $rootPackage->getProvides(); foreach ($fixedPackages as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); $constraint->setPrettyString($package->getPrettyVersion()); // skip platform packages that are provided by the root package if ($package->getRepository() !== $platformRepo || !isset($provided[$package->getName()]) || !$provided[$package->getName()]->getConstraint()->matches($constraint)) { $request->fix($package->getName(), $constraint); } } return $request; }
private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo) { $request = new Request($pool); $constraint = new VersionConstraint('=', $rootPackage->getVersion()); $constraint->setPrettyString($rootPackage->getPrettyVersion()); $request->install($rootPackage->getName(), $constraint); // fix the version of all platform packages to prevent the solver trying to remove those foreach ($platformRepo->getPackages() as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); $constraint->setPrettyString($package->getPrettyVersion()); if (!($provided = $rootPackage->getProvides()) || !isset($provided[$package->getName()]) || !$provided[$package->getName()]->getConstraint()->matches($constraint)) { $request->install($package->getName(), $constraint); } } return $request; }
protected function doInstall($localRepo, $installedRepo, $aliases, $devMode = false) { $minimumStability = $this->package->getMinimumStability(); $stabilityFlags = $this->package->getStabilityFlags(); // initialize locker to create aliased packages if (!$this->update && $this->locker->isLocked($devMode)) { $lockedPackages = $this->locker->getLockedPackages($devMode); $minimumStability = $this->locker->getMinimumStability(); $stabilityFlags = $this->locker->getStabilityFlags(); } $this->whitelistUpdateDependencies($localRepo, $devMode, $this->package->getRequires(), $this->package->getDevRequires()); $this->io->write('<info>Loading composer repositories with package information</info>'); // creating repository pool $pool = new Pool($minimumStability, $stabilityFlags); $pool->addRepository($installedRepo, $aliases); $repositories = $this->repositoryManager->getRepositories(); foreach ($repositories as $repository) { $pool->addRepository($repository, $aliases); } // creating requirements request $installFromLock = false; $request = new Request($pool); $constraint = new VersionConstraint('=', $this->package->getVersion()); $request->install($this->package->getName(), $constraint); if ($this->update) { $this->io->write('<info>Updating ' . ($devMode ? 'dev ' : '') . 'dependencies</info>'); $request->updateAll(); $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires(); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } elseif ($this->locker->isLocked($devMode)) { $installFromLock = true; $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies from lock file</info>'); if (!$this->locker->isFresh() && !$devMode) { $this->io->write('<warning>Your lock file is out of sync with your composer.json, run "composer.phar update" to update dependencies</warning>'); } foreach ($lockedPackages as $package) { $version = $package->getVersion(); if (isset($aliases[$package->getName()][$version])) { $version = $aliases[$package->getName()][$version]['alias_normalized']; } $constraint = new VersionConstraint('=', $version); $request->install($package->getName(), $constraint); } } else { $this->io->write('<info>Installing ' . ($devMode ? 'dev ' : '') . 'dependencies</info>'); $links = $devMode ? $this->package->getDevRequires() : $this->package->getRequires(); foreach ($links as $link) { $request->install($link->getTarget(), $link->getConstraint()); } } // fix the version of all installed packages (+ platform) that are not // in the current local repo to prevent rogue updates (e.g. non-dev // updating when in dev) foreach ($installedRepo->getPackages() as $package) { if ($package->getRepository() === $localRepo) { continue; } $constraint = new VersionConstraint('=', $package->getVersion()); $request->install($package->getName(), $constraint); } // if the updateWhitelist is enabled, packages not in it are also fixed // to the version specified in the lock, or their currently installed version if ($this->update && $this->updateWhitelist) { if ($this->locker->isLocked($devMode)) { $currentPackages = $this->locker->getLockedPackages($devMode); } else { $currentPackages = $installedRepo->getPackages(); } // collect links from composer as well as installed packages $candidates = array(); foreach ($links as $link) { $candidates[$link->getTarget()] = true; } foreach ($localRepo->getPackages() as $package) { $candidates[$package->getName()] = true; } // fix them to the version in lock (or currently installed) if they are not updateable foreach ($candidates as $candidate => $dummy) { foreach ($currentPackages as $curPackage) { if ($curPackage->getName() === $candidate) { if ($this->isUpdateable($curPackage)) { break; } $constraint = new VersionConstraint('=', $curPackage->getVersion()); $request->install($curPackage->getName(), $constraint); } } } } // prepare solver $policy = new DefaultPolicy(); $solver = new Solver($policy, $pool, $installedRepo); // solve dependencies try { $operations = $solver->solve($request); } catch (SolverProblemsException $e) { $this->io->write('<error>Your requirements could not be resolved to an installable set of packages.</error>'); $this->io->write($e->getMessage()); return false; } // force dev packages to be updated if we update or install from a (potentially new) lock foreach ($localRepo->getPackages() as $package) { // skip non-dev packages if (!$package->isDev()) { continue; } if ($package instanceof AliasPackage) { continue; } // skip packages that will be updated/uninstalled foreach ($operations as $operation) { if ('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package) || 'uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package)) { continue 2; } } // force update to locked version if it does not match the installed version if ($installFromLock) { $lockData = $this->locker->getLockData(); unset($lockedReference); foreach ($lockData['packages'] as $lockedPackage) { if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) { $lockedReference = $lockedPackage['source-reference']; break; } } if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) { // changing the source ref to update to will be handled in the operations loop below $operations[] = new UpdateOperation($package, clone $package); } } else { // force update to latest on update if ($this->update) { // skip package if the whitelist is enabled and it is not in it if ($this->updateWhitelist && !$this->isUpdateable($package)) { continue; } $newPackage = null; $matches = $pool->whatProvides($package->getName(), new VersionConstraint('=', $package->getVersion())); foreach ($matches as $match) { // skip local packages if (!in_array($match->getRepository(), $repositories, true)) { continue; } // skip providers/replacers if ($match->getName() !== $package->getName()) { continue; } $newPackage = $match; break; } if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) { $operations[] = new UpdateOperation($package, $newPackage); } } // force installed package to update to referenced version if it does not match the installed version $references = $this->package->getReferences(); if (isset($references[$package->getName()]) && $references[$package->getName()] !== $package->getSourceReference()) { // changing the source ref to update to will be handled in the operations loop below $operations[] = new UpdateOperation($package, clone $package); } } } // execute operations if (!$operations) { $this->io->write('Nothing to install or update'); } foreach ($operations as $operation) { // collect suggestions if ('install' === $operation->getJobType()) { foreach ($operation->getPackage()->getSuggests() as $target => $reason) { $this->suggestedPackages[] = array('source' => $operation->getPackage()->getPrettyName(), 'target' => $target, 'reason' => $reason); } } $event = 'Composer\\Script\\ScriptEvents::PRE_PACKAGE_' . strtoupper($operation->getJobType()); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $operation); } // if installing from lock, restore dev packages' references to their locked state if ($installFromLock) { $package = null; if ('update' === $operation->getJobType()) { $package = $operation->getTargetPackage(); } elseif ('install' === $operation->getJobType()) { $package = $operation->getPackage(); } if ($package && $package->isDev()) { $lockData = $this->locker->getLockData(); foreach ($lockData['packages'] as $lockedPackage) { if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) { // update commit date to allow recovery in case the commit disappeared if (!empty($lockedPackage['commit-date'])) { $package->setReleaseDate(new \DateTime('@' . $lockedPackage['commit-date'])); } $package->setSourceReference($lockedPackage['source-reference']); break; } } } } else { // not installing from lock, force dev packages' references if they're in root package refs $package = null; if ('update' === $operation->getJobType()) { $package = $operation->getTargetPackage(); } elseif ('install' === $operation->getJobType()) { $package = $operation->getPackage(); } if ($package && $package->isDev()) { $references = $this->package->getReferences(); if (isset($references[$package->getName()])) { $package->setSourceReference($references[$package->getName()]); } } } // output alias operations in verbose mode, or all ops in dry run if ($this->dryRun || $this->verbose && false !== strpos($operation->getJobType(), 'Alias')) { $this->io->write(' - ' . $operation); } $this->installationManager->execute($localRepo, $operation); $event = 'Composer\\Script\\ScriptEvents::POST_PACKAGE_' . strtoupper($operation->getJobType()); if (defined($event) && $this->runScripts) { $this->eventDispatcher->dispatchPackageEvent(constant($event), $operation); } if (!$this->dryRun) { $localRepo->write(); } } return true; }
private function createRequest(Pool $pool, RootPackageInterface $rootPackage, PlatformRepository $platformRepo) { $request = new Request($pool); $constraint = new VersionConstraint('=', $rootPackage->getVersion()); $constraint->setPrettyString($rootPackage->getPrettyVersion()); $request->install($rootPackage->getName(), $constraint); $fixedPackages = $platformRepo->getPackages(); if ($this->additionalInstalledRepository) { $additionalFixedPackages = $this->additionalInstalledRepository->getPackages(); $fixedPackages = array_merge($fixedPackages, $additionalFixedPackages); } $provided = $rootPackage->getProvides(); foreach ($fixedPackages as $package) { $constraint = new VersionConstraint('=', $package->getVersion()); $constraint->setPrettyString($package->getPrettyVersion()); if ($package->getRepository() !== $platformRepo || !isset($provided[$package->getName()]) || !$provided[$package->getName()]->getConstraint()->matches($constraint)) { $request->install($package->getName(), $constraint); } } return $request; }
/** * @param Locker $locker * @param RootPackageInterface $rootPackage * * @return \Generator|\string[] */ private static function getVersions(Locker $locker, RootPackageInterface $rootPackage) : \Generator { $lockData = $locker->getLockData(); foreach (array_merge($lockData['packages'], $lockData['packages-dev']) as $package) { (yield $package['name'] => $package['version'] . '@' . $package['source']['reference']); } (yield $rootPackage->getName() => $rootPackage->getVersion() . '@' . $rootPackage->getSourceReference()); }
private function processFetches(RootPackageInterface $package, $fetches) { $targets = array(); $requires = $package->getRequires(); foreach ($fetches as $key => $data) { if ($key == 'base-dir') { continue; } $data = $this->handleShortSyntax($key, $data); $name = $this->packageName($data['source']); try { $fetcher = $this->createFetcher($this->determineType($data)); $targets += $fetcher->fetch($data, $name); } catch (\Exception $e) { throw new \Exception("Cannot fetch [{$key}]: " . $e->getMessage(), 0, $e); } $requires[$name] = new Link($package->getName(), $name); } $package->setRequires($requires); return $targets; }
/** * @param Locker $locker * @param RootPackageInterface $rootPackage * * @return \Generator|\string[] */ private static function getVersions(Locker $locker, RootPackageInterface $rootPackage) { $lockData = $locker->getLockData(); $lockData['packages-dev'] = isset($lockData['packages-dev']) ? $lockData['packages-dev'] : []; foreach (array_merge($lockData['packages'], $lockData['packages-dev']) as $package) { (yield $package['name'] => $package['version'] . '@' . (isset($package['source']['reference']) ? $package['source']['reference'] : (isset($package['dist']['reference']) ? $package['dist']['reference'] : ''))); } (yield $rootPackage->getName() => $rootPackage->getVersion() . '@' . $rootPackage->getSourceReference()); }