Esempio n. 1
0
 /**
  * @param Pool                        $pool
  * @param PolicyInterface             $policy
  * @param WritableRepositoryInterface $localRepo
  * @param array                       $repositories
  */
 private function processPackageUrls($pool, $policy, $localRepo, $repositories)
 {
     if (!$this->update) {
         return;
     }
     $rootRefs = $this->package->getReferences();
     foreach ($localRepo->getCanonicalPackages() as $package) {
         // find similar packages (name/version) in all repositories
         $matches = $pool->whatProvides($package->getName(), new Constraint('=', $package->getVersion()));
         foreach ($matches as $index => $match) {
             // skip local packages
             if (!in_array($match->getRepository(), $repositories, true)) {
                 unset($matches[$index]);
                 continue;
             }
             // skip providers/replacers
             if ($match->getName() !== $package->getName()) {
                 unset($matches[$index]);
                 continue;
             }
             $matches[$index] = $match->getId();
         }
         // select preferred package according to policy rules
         if ($matches && ($matches = $policy->selectPreferredPackages($pool, array(), $matches))) {
             $newPackage = $pool->literalToPackage($matches[0]);
             // update the dist and source URLs
             $sourceUrl = $package->getSourceUrl();
             $newSourceUrl = $newPackage->getSourceUrl();
             $newReference = $newPackage->getSourceReference();
             if ($package->isDev() && isset($rootRefs[$package->getName()]) && $package->getSourceReference() === $rootRefs[$package->getName()]) {
                 $newReference = $rootRefs[$package->getName()];
             }
             $this->updatePackageUrl($package, $newSourceUrl, $newPackage->getSourceType(), $newReference, $newPackage->getDistUrl());
             if ($package instanceof CompletePackage && $newPackage instanceof CompletePackage) {
                 $package->setAbandoned($newPackage->getReplacementPackage() ?: $newPackage->isAbandoned());
             }
         }
     }
 }
Esempio n. 2
0
 private function processDevPackages($localRepo, $pool, $policy, $repositories, $lockedRepository, $installFromLock, $task, array $operations = null)
 {
     if ($task === 'force-updates' && null === $operations) {
         throw new \InvalidArgumentException('Missing operations argument');
     }
     if ($task === 'force-links') {
         $operations = array();
     }
     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) {
             foreach ($lockedRepository->findPackages($package->getName()) as $lockedPackage) {
                 if ($lockedPackage->isDev() && $lockedPackage->getVersion() === $package->getVersion()) {
                     if ($task === 'force-links') {
                         $package->setRequires($lockedPackage->getRequires());
                         $package->setConflicts($lockedPackage->getConflicts());
                         $package->setProvides($lockedPackage->getProvides());
                         $package->setReplaces($lockedPackage->getReplaces());
                     } elseif ($task === 'force-updates') {
                         if ($lockedPackage->getSourceReference() && $lockedPackage->getSourceReference() !== $package->getSourceReference() || $lockedPackage->getDistReference() && $lockedPackage->getDistReference() !== $package->getDistReference()) {
                             $operations[] = new UpdateOperation($package, $lockedPackage);
                         }
                     }
                     break;
                 }
             }
         } 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;
                 }
                 // find similar packages (name/version) in all repositories
                 $matches = $pool->whatProvides($package->getName(), new VersionConstraint('=', $package->getVersion()));
                 foreach ($matches as $index => $match) {
                     // skip local packages
                     if (!in_array($match->getRepository(), $repositories, true)) {
                         unset($matches[$index]);
                         continue;
                     }
                     // skip providers/replacers
                     if ($match->getName() !== $package->getName()) {
                         unset($matches[$index]);
                         continue;
                     }
                     $matches[$index] = $match->getId();
                 }
                 // select prefered package according to policy rules
                 if ($matches && ($matches = $policy->selectPreferedPackages($pool, array(), $matches))) {
                     $newPackage = $pool->literalToPackage($matches[0]);
                     if ($task === 'force-links' && $newPackage) {
                         $package->setRequires($newPackage->getRequires());
                         $package->setConflicts($newPackage->getConflicts());
                         $package->setProvides($newPackage->getProvides());
                         $package->setReplaces($newPackage->getReplaces());
                     }
                     if ($task === 'force-updates' && $newPackage && ($newPackage->getSourceReference() && $newPackage->getSourceReference() !== $package->getSourceReference() || $newPackage->getDistReference() && $newPackage->getDistReference() !== $package->getDistReference())) {
                         $operations[] = new UpdateOperation($package, $newPackage);
                     }
                 }
             }
             if ($task === 'force-updates') {
                 // 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);
                 }
             }
         }
     }
     return $operations;
 }
Esempio n. 3
0
 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;
 }