2012-03-03 05:35:40 +00:00
< ? php
/*
* This file is part of Composer .
*
* ( c ) Nils Adermann < naderman @ naderman . de >
* Jordi Boggiano < j . boggiano @ seld . be >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Composer ;
use Composer\Autoload\AutoloadGenerator ;
use Composer\DependencyResolver\DefaultPolicy ;
use Composer\DependencyResolver\Operation\UpdateOperation ;
2013-08-11 22:28:33 +00:00
use Composer\DependencyResolver\Operation\InstallOperation ;
2013-03-03 00:55:10 +00:00
use Composer\DependencyResolver\Operation\UninstallOperation ;
2013-08-11 22:28:33 +00:00
use Composer\DependencyResolver\Operation\OperationInterface ;
2012-03-03 05:35:40 +00:00
use Composer\DependencyResolver\Pool ;
use Composer\DependencyResolver\Request ;
2013-04-26 22:11:06 +00:00
use Composer\DependencyResolver\Rule ;
2012-03-03 05:35:40 +00:00
use Composer\DependencyResolver\Solver ;
2012-03-18 21:43:07 +00:00
use Composer\DependencyResolver\SolverProblemsException ;
2012-03-05 23:48:07 +00:00
use Composer\Downloader\DownloadManager ;
2013-08-14 15:42:11 +00:00
use Composer\EventDispatcher\EventDispatcher ;
2012-03-05 23:48:07 +00:00
use Composer\Installer\InstallationManager ;
2014-07-29 13:25:16 +00:00
use Composer\Installer\InstallerEvents ;
2012-05-23 13:39:33 +00:00
use Composer\Installer\NoopInstaller ;
2012-03-03 05:35:40 +00:00
use Composer\IO\IOInterface ;
2013-03-03 00:55:10 +00:00
use Composer\Json\JsonFile ;
2012-03-03 05:35:40 +00:00
use Composer\Package\AliasPackage ;
2014-10-03 12:48:28 +00:00
use Composer\Package\CompletePackage ;
2012-03-03 05:35:40 +00:00
use Composer\Package\Link ;
use Composer\Package\LinkConstraint\VersionConstraint ;
2012-03-05 23:48:07 +00:00
use Composer\Package\Locker ;
2012-03-03 05:35:40 +00:00
use Composer\Package\PackageInterface ;
2012-08-23 13:52:40 +00:00
use Composer\Package\RootPackageInterface ;
2012-03-03 05:35:40 +00:00
use Composer\Repository\CompositeRepository ;
2012-05-09 18:03:19 +00:00
use Composer\Repository\InstalledArrayRepository ;
2013-03-03 00:55:10 +00:00
use Composer\Repository\InstalledFilesystemRepository ;
2012-03-03 05:35:40 +00:00
use Composer\Repository\PlatformRepository ;
use Composer\Repository\RepositoryInterface ;
2012-03-05 23:48:07 +00:00
use Composer\Repository\RepositoryManager ;
2012-03-03 05:35:40 +00:00
use Composer\Script\ScriptEvents ;
2012-03-10 00:16:37 +00:00
/**
* @ author Jordi Boggiano < j . boggiano @ seld . be >
* @ author Beau Simensen < beau @ dflydev . com >
* @ author Konstantin Kudryashov < ever . zet @ gmail . com >
2013-08-15 15:14:48 +00:00
* @ author Nils Adermann < naderman @ naderman . de >
2012-03-10 00:16:37 +00:00
*/
2012-03-06 23:30:18 +00:00
class Installer
2012-03-03 05:35:40 +00:00
{
/**
2012-03-05 23:48:07 +00:00
* @ var IOInterface
*/
protected $io ;
2012-06-24 19:58:51 +00:00
/**
* @ var Config
*/
protected $config ;
2012-03-05 23:48:07 +00:00
/**
2012-08-23 13:52:40 +00:00
* @ var RootPackageInterface
2012-03-05 23:48:07 +00:00
*/
protected $package ;
/**
* @ var DownloadManager
*/
protected $downloadManager ;
/**
* @ var RepositoryManager
*/
protected $repositoryManager ;
/**
* @ var Locker
*/
protected $locker ;
/**
* @ var InstallationManager
*/
protected $installationManager ;
/**
* @ var EventDispatcher
*/
protected $eventDispatcher ;
2012-04-27 09:42:58 +00:00
/**
* @ var AutoloadGenerator
*/
protected $autoloadGenerator ;
2012-03-10 18:56:15 +00:00
protected $preferSource = false ;
2012-08-31 20:25:17 +00:00
protected $preferDist = false ;
2012-10-24 15:33:31 +00:00
protected $optimizeAutoloader = false ;
2012-04-14 09:55:57 +00:00
protected $devMode = false ;
2012-03-10 18:56:15 +00:00
protected $dryRun = false ;
protected $verbose = false ;
protected $update = false ;
2014-12-29 20:29:13 +00:00
protected $dumpAutoloader = true ;
2012-05-13 11:25:02 +00:00
protected $runScripts = true ;
2014-10-17 14:26:00 +00:00
protected $ignorePlatformReqs = false ;
2014-12-02 08:18:44 +00:00
protected $preferStable = false ;
protected $preferLowest = false ;
2014-02-24 11:28:08 +00:00
/**
* Array of package names / globs flagged for update
*
* @ var array | null
*/
2012-05-26 13:20:27 +00:00
protected $updateWhitelist = null ;
2013-10-14 08:49:34 +00:00
protected $whitelistDependencies = false ;
2012-03-10 17:08:36 +00:00
2012-04-15 15:44:47 +00:00
/**
* @ var array
*/
protected $suggestedPackages ;
2012-03-10 17:08:36 +00:00
/**
* @ var RepositoryInterface
*/
protected $additionalInstalledRepository ;
2012-03-05 23:48:07 +00:00
/**
* Constructor
2012-03-10 00:16:37 +00:00
*
2012-10-18 08:35:06 +00:00
* @ param IOInterface $io
* @ param Config $config
* @ param RootPackageInterface $package
* @ param DownloadManager $downloadManager
* @ param RepositoryManager $repositoryManager
* @ param Locker $locker
* @ param InstallationManager $installationManager
* @ param EventDispatcher $eventDispatcher
* @ param AutoloadGenerator $autoloadGenerator
2012-03-05 23:48:07 +00:00
*/
2012-08-23 13:52:40 +00:00
public function __construct ( IOInterface $io , Config $config , RootPackageInterface $package , DownloadManager $downloadManager , RepositoryManager $repositoryManager , Locker $locker , InstallationManager $installationManager , EventDispatcher $eventDispatcher , AutoloadGenerator $autoloadGenerator )
2012-03-05 23:48:07 +00:00
{
$this -> io = $io ;
2012-06-24 19:58:51 +00:00
$this -> config = $config ;
2012-03-05 23:48:07 +00:00
$this -> package = $package ;
$this -> downloadManager = $downloadManager ;
$this -> repositoryManager = $repositoryManager ;
$this -> locker = $locker ;
$this -> installationManager = $installationManager ;
$this -> eventDispatcher = $eventDispatcher ;
2012-04-27 09:42:58 +00:00
$this -> autoloadGenerator = $autoloadGenerator ;
2012-03-05 23:48:07 +00:00
}
/**
* Run installation ( or update )
2013-11-22 15:17:02 +00:00
*
* @ return int 0 on success or a positive error code on failure
2014-07-16 13:17:38 +00:00
*
* @ throws \Exception
2012-03-03 05:35:40 +00:00
*/
2012-03-10 17:08:36 +00:00
public function run ()
2012-03-03 05:35:40 +00:00
{
2014-12-02 14:02:20 +00:00
gc_collect_cycles ();
2014-12-02 10:23:21 +00:00
gc_disable ();
2012-03-10 17:08:36 +00:00
if ( $this -> dryRun ) {
$this -> verbose = true ;
2012-05-23 13:16:24 +00:00
$this -> runScripts = false ;
2012-05-23 13:39:33 +00:00
$this -> installationManager -> addInstaller ( new NoopInstaller );
2012-10-22 13:50:40 +00:00
$this -> mockLocalRepositories ( $this -> repositoryManager );
2012-03-03 05:35:40 +00:00
}
2013-03-03 00:55:10 +00:00
// TODO remove this BC feature at some point
// purge old require-dev packages to avoid conflicts with the new way of handling dev requirements
$devRepo = new InstalledFilesystemRepository ( new JsonFile ( $this -> config -> get ( 'vendor-dir' ) . '/composer/installed_dev.json' ));
if ( $devRepo -> getPackages ()) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<warning>BC Notice: Removing old dev packages to migrate to the new require-dev handling.</warning>' );
2013-03-03 00:55:10 +00:00
foreach ( $devRepo -> getPackages () as $package ) {
if ( $this -> installationManager -> isPackageInstalled ( $devRepo , $package )) {
$this -> installationManager -> uninstall ( $devRepo , new UninstallOperation ( $package ));
}
}
2013-03-04 16:10:54 +00:00
unlink ( $this -> config -> get ( 'vendor-dir' ) . '/composer/installed_dev.json' );
2013-03-03 00:55:10 +00:00
}
unset ( $devRepo , $package );
// end BC
2013-12-26 15:35:20 +00:00
if ( $this -> runScripts ) {
// dispatch pre event
$eventName = $this -> update ? ScriptEvents :: PRE_UPDATE_CMD : ScriptEvents :: PRE_INSTALL_CMD ;
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchScript ( $eventName , $this -> devMode );
2013-12-26 15:35:20 +00:00
}
2013-11-11 16:43:11 +00:00
$this -> downloadManager -> setPreferSource ( $this -> preferSource );
$this -> downloadManager -> setPreferDist ( $this -> preferDist );
2012-03-03 05:35:40 +00:00
2013-04-30 08:37:03 +00:00
// clone root package to have one in the installed repo that does not require anything
// we don't want it to be uninstallable, but its requirements should not conflict
// with the lock file for example
2012-05-28 16:57:59 +00:00
$installedRootPackage = clone $this -> package ;
$installedRootPackage -> setRequires ( array ());
$installedRootPackage -> setDevRequires ( array ());
2013-04-30 08:37:03 +00:00
// create installed repo, this contains all local packages + platform packages (php & extensions)
2013-03-02 23:41:12 +00:00
$localRepo = $this -> repositoryManager -> getLocalRepository ();
2015-04-29 21:38:07 +00:00
if ( ! $this -> update && $this -> locker -> isLocked ()) {
$platformOverrides = $this -> locker -> getPlatformOverrides ();
} else {
$platformOverrides = $this -> config -> get ( 'platform' ) ? : array ();
}
$platformRepo = new PlatformRepository ( array (), $platformOverrides );
2013-03-02 23:41:12 +00:00
$repos = array (
$localRepo ,
new InstalledArrayRepository ( array ( $installedRootPackage )),
$platformRepo ,
2012-04-27 09:42:58 +00:00
);
2012-04-14 13:45:25 +00:00
$installedRepo = new CompositeRepository ( $repos );
2012-03-10 17:08:36 +00:00
if ( $this -> additionalInstalledRepository ) {
$installedRepo -> addRepository ( $this -> additionalInstalledRepository );
2012-03-03 05:35:40 +00:00
}
2012-08-22 13:39:16 +00:00
$aliases = $this -> getRootAliases ();
$this -> aliasPlatformPackages ( $platformRepo , $aliases );
2012-03-03 05:35:40 +00:00
2012-11-28 17:44:49 +00:00
try {
$this -> suggestedPackages = array ();
2013-11-22 15:17:02 +00:00
$res = $this -> doInstall ( $localRepo , $installedRepo , $platformRepo , $aliases , $this -> devMode );
if ( $res !== 0 ) {
return $res ;
2012-04-15 15:44:47 +00:00
}
2012-11-28 17:44:49 +00:00
} catch ( \Exception $e ) {
$this -> installationManager -> notifyInstalls ();
throw $e ;
2012-04-14 13:45:25 +00:00
}
2012-11-28 17:44:49 +00:00
$this -> installationManager -> notifyInstalls ();
2012-04-14 13:45:25 +00:00
2014-04-05 22:07:20 +00:00
// output suggestions if we're in dev mode
2014-04-06 20:44:56 +00:00
if ( $this -> devMode ) {
2014-04-05 22:07:20 +00:00
foreach ( $this -> suggestedPackages as $suggestion ) {
$target = $suggestion [ 'target' ];
foreach ( $installedRepo -> getPackages () as $package ) {
if ( in_array ( $target , $package -> getNames ())) {
continue 2 ;
}
2012-09-05 19:00:24 +00:00
}
2013-03-10 12:32:59 +00:00
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( $suggestion [ 'source' ] . ' suggests installing ' . $suggestion [ 'target' ] . ' (' . $suggestion [ 'reason' ] . ')' );
2014-04-05 22:07:20 +00:00
}
2012-04-14 13:45:25 +00:00
}
2014-10-03 12:48:28 +00:00
# Find abandoned packages and warn user
foreach ( $localRepo -> getPackages () as $package ) {
if ( ! $package instanceof CompletePackage || ! $package -> isAbandoned ()) {
continue ;
}
$replacement = ( is_string ( $package -> getReplacementPackage ()))
? 'Use ' . $package -> getReplacementPackage () . ' instead'
: 'No replacement was suggested' ;
2015-02-06 12:52:44 +00:00
$this -> io -> writeError (
2014-10-03 12:48:28 +00:00
sprintf (
2015-04-30 21:34:26 +00:00
" <warning>Package %s is abandoned, you should avoid using it. %s.</warning> " ,
2014-10-03 12:48:28 +00:00
$package -> getPrettyName (),
$replacement
)
);
}
2012-04-14 13:45:25 +00:00
if ( ! $this -> dryRun ) {
// write lock
if ( $this -> update || ! $this -> locker -> isLocked ()) {
2013-03-02 23:41:12 +00:00
$localRepo -> reload ();
2013-03-06 21:20:03 +00:00
// if this is not run in dev mode and the root has dev requires, the lock must
// contain null to prevent dev installs from a non-dev lock
$devPackages = ( $this -> devMode || ! $this -> package -> getDevRequires ()) ? array () : null ;
2013-03-02 23:41:12 +00:00
// split dev and non-dev requirements by checking what would be removed if we update without the dev requirements
if ( $this -> devMode && $this -> package -> getDevRequires ()) {
2013-03-28 20:02:55 +00:00
$policy = $this -> createPolicy ();
2013-10-14 02:01:26 +00:00
$pool = $this -> createPool ( true );
2013-03-02 23:41:12 +00:00
$pool -> addRepository ( $installedRepo , $aliases );
// creating requirements request
2015-04-30 15:24:24 +00:00
$request = $this -> createRequest ( $this -> package , $platformRepo );
2013-03-02 23:41:12 +00:00
$request -> updateAll ();
foreach ( $this -> package -> getRequires () as $link ) {
$request -> install ( $link -> getTarget (), $link -> getConstraint ());
}
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchInstallerEvent ( InstallerEvents :: PRE_DEPENDENCIES_SOLVING , false , $policy , $pool , $installedRepo , $request );
2013-03-02 23:41:12 +00:00
$solver = new Solver ( $policy , $pool , $installedRepo );
2014-10-17 14:26:00 +00:00
$ops = $solver -> solve ( $request , $this -> ignorePlatformReqs );
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchInstallerEvent ( InstallerEvents :: POST_DEPENDENCIES_SOLVING , false , $policy , $pool , $installedRepo , $request , $ops );
2013-03-02 23:41:12 +00:00
foreach ( $ops as $op ) {
if ( $op -> getJobType () === 'uninstall' ) {
$devPackages [] = $op -> getPackage ();
}
}
}
2013-03-03 19:05:46 +00:00
$platformReqs = $this -> extractPlatformRequirements ( $this -> package -> getRequires ());
$platformDevReqs = $this -> devMode ? $this -> extractPlatformRequirements ( $this -> package -> getDevRequires ()) : array ();
2012-04-14 13:45:25 +00:00
$updatedLock = $this -> locker -> setLockData (
2013-04-28 20:32:46 +00:00
array_diff ( $localRepo -> getCanonicalPackages (), ( array ) $devPackages ),
2013-03-02 23:41:12 +00:00
$devPackages ,
2013-03-03 19:05:46 +00:00
$platformReqs ,
$platformDevReqs ,
2012-05-11 15:20:10 +00:00
$aliases ,
$this -> package -> getMinimumStability (),
2014-07-07 17:51:00 +00:00
$this -> package -> getStabilityFlags (),
2014-12-13 22:56:15 +00:00
$this -> preferStable || $this -> package -> getPreferStable (),
2015-04-29 21:38:07 +00:00
$this -> preferLowest ,
$this -> config -> get ( 'platform' ) ? : array ()
2012-04-14 13:45:25 +00:00
);
if ( $updatedLock ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Writing lock file</info>' );
2012-04-14 13:45:25 +00:00
}
}
2014-12-29 20:29:13 +00:00
if ( $this -> dumpAutoloader ) {
2014-11-21 21:16:19 +00:00
// write autoloader
if ( $this -> optimizeAutoloader ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Generating optimized autoload files</info>' );
2014-11-21 21:16:19 +00:00
} else {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Generating autoload files</info>' );
2014-11-21 21:16:19 +00:00
}
2014-12-29 20:29:13 +00:00
2014-11-21 21:16:19 +00:00
$this -> autoloadGenerator -> setDevMode ( $this -> devMode );
$this -> autoloadGenerator -> dump ( $this -> config , $localRepo , $this -> package , $this -> installationManager , 'composer' , $this -> optimizeAutoloader );
2014-01-17 14:04:10 +00:00
}
2012-05-13 11:25:02 +00:00
if ( $this -> runScripts ) {
2012-04-16 17:45:06 +00:00
// dispatch post event
$eventName = $this -> update ? ScriptEvents :: POST_UPDATE_CMD : ScriptEvents :: POST_INSTALL_CMD ;
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchScript ( $eventName , $this -> devMode );
2012-04-16 17:45:06 +00:00
}
2014-02-26 09:43:26 +00:00
$vendorDir = $this -> config -> get ( 'vendor-dir' );
if ( is_dir ( $vendorDir )) {
touch ( $vendorDir );
}
2012-04-14 13:45:25 +00:00
}
2013-11-22 15:17:02 +00:00
return 0 ;
2012-04-14 13:45:25 +00:00
}
2013-03-02 23:41:12 +00:00
protected function doInstall ( $localRepo , $installedRepo , $platformRepo , $aliases , $withDevReqs )
2012-04-14 13:45:25 +00:00
{
2012-11-22 21:47:19 +00:00
// init vars
$lockedRepository = null ;
$repositories = null ;
2012-04-24 08:49:49 +00:00
// initialize locker to create aliased packages
2015-04-30 14:14:20 +00:00
$installFromLock = ! $this -> update && $this -> locker -> isLocked ();
// initialize locked repo if we are installing from lock or in a partial update
// and a lock file is present as we need to force install non-whitelisted lock file
// packages in that case
if ( $installFromLock || ( ! empty ( $this -> updateWhitelist ) && $this -> locker -> isLocked ())) {
2013-04-05 13:01:18 +00:00
try {
$lockedRepository = $this -> locker -> getLockedRepository ( $withDevReqs );
} catch ( \RuntimeException $e ) {
// if there are dev requires, then we really can not install
if ( $this -> package -> getDevRequires ()) {
throw $e ;
}
// no require-dev in composer.json and the lock file was created with no dev info, so skip them
$lockedRepository = $this -> locker -> getLockedRepository ();
}
2012-04-24 08:49:49 +00:00
}
2012-05-28 10:02:15 +00:00
$this -> whitelistUpdateDependencies (
$localRepo ,
2013-03-02 23:41:12 +00:00
$withDevReqs ,
2012-05-28 10:02:15 +00:00
$this -> package -> getRequires (),
2012-07-01 16:03:01 +00:00
$this -> package -> getDevRequires ()
);
2012-05-27 23:58:54 +00:00
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Loading composer repositories with package information</info>' );
2012-08-16 23:42:05 +00:00
2012-04-15 17:05:16 +00:00
// creating repository pool
2013-03-28 20:02:55 +00:00
$policy = $this -> createPolicy ();
2015-04-30 14:14:20 +00:00
$pool = $this -> createPool ( $withDevReqs , $installFromLock ? $lockedRepository : null );
2012-08-22 12:20:43 +00:00
$pool -> addRepository ( $installedRepo , $aliases );
2013-03-17 18:50:56 +00:00
if ( ! $installFromLock ) {
2012-09-14 15:42:12 +00:00
$repositories = $this -> repositoryManager -> getRepositories ();
foreach ( $repositories as $repository ) {
$pool -> addRepository ( $repository , $aliases );
}
2012-04-15 17:05:16 +00:00
}
2015-04-30 14:14:20 +00:00
// Add the locked repository after the others in case we are doing a
// partial update so missing packages can be found there still.
// For installs from lock it's the only one added so it is first
if ( $lockedRepository ) {
$pool -> addRepository ( $lockedRepository , $aliases );
}
2012-04-15 17:05:16 +00:00
2012-03-03 05:35:40 +00:00
// creating requirements request
2015-04-30 15:24:24 +00:00
$request = $this -> createRequest ( $this -> package , $platformRepo );
2012-04-27 09:42:58 +00:00
2013-03-10 18:55:26 +00:00
if ( ! $installFromLock ) {
// remove unstable packages from the localRepo if they don't match the current stability settings
$removedUnstablePackages = array ();
foreach ( $localRepo -> getPackages () as $package ) {
if (
2013-04-04 15:37:52 +00:00
! $pool -> isPackageAcceptable ( $package -> getNames (), $package -> getStability ())
2013-03-10 18:55:26 +00:00
&& $this -> installationManager -> isPackageInstalled ( $localRepo , $package )
) {
$removedUnstablePackages [ $package -> getName ()] = true ;
$request -> remove ( $package -> getName (), new VersionConstraint ( '=' , $package -> getVersion ()));
}
}
}
2012-03-10 17:08:36 +00:00
if ( $this -> update ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Updating dependencies' . ( $withDevReqs ? ' (including require-dev)' : '' ) . '</info>' );
2012-03-03 05:35:40 +00:00
$request -> updateAll ();
2013-03-02 23:41:12 +00:00
if ( $withDevReqs ) {
$links = array_merge ( $this -> package -> getRequires (), $this -> package -> getDevRequires ());
} else {
$links = $this -> package -> getRequires ();
}
2012-03-03 05:35:40 +00:00
foreach ( $links as $link ) {
$request -> install ( $link -> getTarget (), $link -> getConstraint ());
}
2013-03-10 18:55:26 +00:00
// 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 -> updateWhitelist ) {
2015-04-30 14:14:20 +00:00
$currentPackages = $this -> getCurrentPackages ( $withDevReqs , $installedRepo );
2013-03-10 18:55:26 +00:00
// collect packages to fixate from root requirements 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 ) && ! isset ( $removedUnstablePackages [ $curPackage -> getName ()])) {
$constraint = new VersionConstraint ( '=' , $curPackage -> getVersion ());
$request -> install ( $curPackage -> getName (), $constraint );
}
break ;
}
}
}
}
2012-09-14 14:43:56 +00:00
} elseif ( $installFromLock ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Installing dependencies' . ( $withDevReqs ? ' (including require-dev)' : '' ) . ' from lock file</info>' );
2012-03-03 05:35:40 +00:00
2013-03-02 23:41:12 +00:00
if ( ! $this -> locker -> isFresh ()) {
2015-02-06 12:52:44 +00:00
$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. Run update to update them.</warning>' );
2012-03-03 05:35:40 +00:00
}
2012-09-14 14:43:56 +00:00
foreach ( $lockedRepository -> getPackages () as $package ) {
2012-03-03 05:35:40 +00:00
$version = $package -> getVersion ();
2012-08-22 12:20:43 +00:00
if ( isset ( $aliases [ $package -> getName ()][ $version ])) {
$version = $aliases [ $package -> getName ()][ $version ][ 'alias_normalized' ];
2012-03-03 05:35:40 +00:00
}
$constraint = new VersionConstraint ( '=' , $version );
2012-10-22 08:27:12 +00:00
$constraint -> setPrettyString ( $package -> getPrettyVersion ());
2012-03-03 05:35:40 +00:00
$request -> install ( $package -> getName (), $constraint );
}
2013-03-03 19:05:46 +00:00
foreach ( $this -> locker -> getPlatformRequirements ( $withDevReqs ) as $link ) {
$request -> install ( $link -> getTarget (), $link -> getConstraint ());
}
2012-03-03 05:35:40 +00:00
} else {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<info>Installing dependencies' . ( $withDevReqs ? ' (including require-dev)' : '' ) . '</info>' );
2012-03-03 05:35:40 +00:00
2013-03-02 23:41:12 +00:00
if ( $withDevReqs ) {
$links = array_merge ( $this -> package -> getRequires (), $this -> package -> getDevRequires ());
} else {
$links = $this -> package -> getRequires ();
}
2012-03-03 05:35:40 +00:00
foreach ( $links as $link ) {
$request -> install ( $link -> getTarget (), $link -> getConstraint ());
}
}
2012-11-22 21:47:19 +00:00
// force dev packages to have the latest links if we update or install from a (potentially new) lock
2015-04-30 14:14:20 +00:00
$this -> processDevPackages ( $localRepo , $pool , $policy , $repositories , $installedRepo , $lockedRepository , $installFromLock , $withDevReqs , 'force-links' );
2012-03-03 05:35:40 +00:00
// solve dependencies
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchInstallerEvent ( InstallerEvents :: PRE_DEPENDENCIES_SOLVING , $this -> devMode , $policy , $pool , $installedRepo , $request );
2012-11-22 21:47:19 +00:00
$solver = new Solver ( $policy , $pool , $installedRepo );
2012-03-18 21:43:07 +00:00
try {
2014-10-17 14:26:00 +00:00
$operations = $solver -> solve ( $request , $this -> ignorePlatformReqs );
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchInstallerEvent ( InstallerEvents :: POST_DEPENDENCIES_SOLVING , $this -> devMode , $policy , $pool , $installedRepo , $request , $operations );
2012-03-18 21:43:07 +00:00
} catch ( SolverProblemsException $e ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<error>Your requirements could not be resolved to an installable set of packages.</error>' );
$this -> io -> writeError ( $e -> getMessage ());
2012-03-18 21:43:07 +00:00
2013-11-22 15:17:02 +00:00
return max ( 1 , $e -> getCode ());
2012-03-18 21:43:07 +00:00
}
2012-03-03 05:35:40 +00:00
2012-04-02 19:46:05 +00:00
// force dev packages to be updated if we update or install from a (potentially new) lock
2015-04-30 14:14:20 +00:00
$operations = $this -> processDevPackages ( $localRepo , $pool , $policy , $repositories , $installedRepo , $lockedRepository , $installFromLock , $withDevReqs , 'force-updates' , $operations );
2012-11-22 21:47:19 +00:00
// execute operations
if ( ! $operations ) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( 'Nothing to install or update' );
2012-11-22 21:47:19 +00:00
}
2013-08-13 11:25:21 +00:00
$operations = $this -> movePluginsToFront ( $operations );
2014-04-07 09:10:26 +00:00
$operations = $this -> moveUninstallsToFront ( $operations );
2013-07-23 15:26:19 +00:00
2012-11-22 21:47:19 +00:00
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 ,
);
}
}
// 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 ()]);
}
}
2014-05-27 12:19:37 +00:00
if ( 'update' === $operation -> getJobType ()
&& $operation -> getTargetPackage () -> isDev ()
&& $operation -> getTargetPackage () -> getVersion () === $operation -> getInitialPackage () -> getVersion ()
&& $operation -> getTargetPackage () -> getSourceReference () === $operation -> getInitialPackage () -> getSourceReference ()
) {
if ( $this -> io -> isDebug ()) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( ' - Skipping update of ' . $operation -> getTargetPackage () -> getPrettyName () . ' to the same reference-locked version' );
$this -> io -> writeError ( '' );
2014-05-27 12:19:37 +00:00
}
continue ;
}
}
2015-02-23 15:31:54 +00:00
$event = 'Composer\Installer\PackageEvents::PRE_PACKAGE_' . strtoupper ( $operation -> getJobType ());
2014-05-27 12:19:37 +00:00
if ( defined ( $event ) && $this -> runScripts ) {
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchPackageEvent ( constant ( $event ), $this -> devMode , $policy , $pool , $installedRepo , $request , $operations , $operation );
2012-11-22 21:47:19 +00:00
}
2013-04-27 09:01:08 +00:00
// output non-alias ops in dry run, output alias ops in debug verbosity
if ( $this -> dryRun && false === strpos ( $operation -> getJobType (), 'Alias' )) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( ' - ' . $operation );
$this -> io -> writeError ( '' );
2013-04-27 09:01:08 +00:00
} elseif ( $this -> io -> isDebug () && false !== strpos ( $operation -> getJobType (), 'Alias' )) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( ' - ' . $operation );
$this -> io -> writeError ( '' );
2012-11-22 21:47:19 +00:00
}
$this -> installationManager -> execute ( $localRepo , $operation );
2013-04-27 09:01:08 +00:00
// output reasons why the operation was ran, only for install/update operations
if ( $this -> verbose && $this -> io -> isVeryVerbose () && in_array ( $operation -> getJobType (), array ( 'install' , 'update' ))) {
2013-04-26 22:11:06 +00:00
$reason = $operation -> getReason ();
if ( $reason instanceof Rule ) {
switch ( $reason -> getReason ()) {
case Rule :: RULE_JOB_INSTALL :
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( ' REASON: Required by root: ' . $reason -> getPrettyString ( $pool ));
$this -> io -> writeError ( '' );
2013-04-26 22:11:06 +00:00
break ;
case Rule :: RULE_PACKAGE_REQUIRES :
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( ' REASON: ' . $reason -> getPrettyString ( $pool ));
$this -> io -> writeError ( '' );
2013-04-26 22:11:06 +00:00
break ;
}
}
}
2015-02-23 15:31:54 +00:00
$event = 'Composer\Installer\PackageEvents::POST_PACKAGE_' . strtoupper ( $operation -> getJobType ());
2012-11-22 21:47:19 +00:00
if ( defined ( $event ) && $this -> runScripts ) {
2015-02-23 15:31:54 +00:00
$this -> eventDispatcher -> dispatchPackageEvent ( constant ( $event ), $this -> devMode , $policy , $pool , $installedRepo , $request , $operations , $operation );
2012-11-22 21:47:19 +00:00
}
if ( ! $this -> dryRun ) {
$localRepo -> write ();
}
}
2015-04-30 15:41:28 +00:00
if ( ! $this -> dryRun ) {
// force source/dist urls to be updated for all packages
$operations = $this -> processPackageUrls ( $pool , $policy , $localRepo , $repositories );
$localRepo -> write ();
}
2013-11-22 15:17:02 +00:00
return 0 ;
2012-11-22 21:47:19 +00:00
}
2013-07-23 15:26:19 +00:00
/**
2013-08-13 11:25:21 +00:00
* Workaround : if your packages depend on plugins , we must be sure
2013-08-11 22:28:33 +00:00
* that those are installed / updated first ; else it would lead to packages
* being installed multiple times in different folders , when running Composer
* twice .
2013-07-23 15:26:19 +00:00
*
2013-08-11 22:28:33 +00:00
* While this does not fix the root - causes of https :// github . com / composer / composer / issues / 1147 ,
* it at least fixes the symptoms and makes usage of composer possible ( again )
* in such scenarios .
*
2013-10-11 23:12:02 +00:00
* @ param OperationInterface [] $operations
2013-08-11 22:28:33 +00:00
* @ return OperationInterface [] reordered operation list
2013-07-23 15:26:19 +00:00
*/
2013-08-13 11:25:21 +00:00
private function movePluginsToFront ( array $operations )
2013-07-23 15:26:19 +00:00
{
2013-08-11 22:28:33 +00:00
$installerOps = array ();
foreach ( $operations as $idx => $op ) {
if ( $op instanceof InstallOperation ) {
$package = $op -> getPackage ();
2013-10-11 23:12:02 +00:00
} elseif ( $op instanceof UpdateOperation ) {
2013-08-11 22:28:33 +00:00
$package = $op -> getTargetPackage ();
} else {
continue ;
2013-07-23 15:26:19 +00:00
}
2014-09-22 16:04:58 +00:00
if ( $package -> getType () === 'composer-plugin' || $package -> getType () === 'composer-installer' ) {
// ignore requirements to platform or composer-plugin-api
$requires = array_keys ( $package -> getRequires ());
foreach ( $requires as $index => $req ) {
if ( $req === 'composer-plugin-api' || preg_match ( PlatformRepository :: PLATFORM_PACKAGE_REGEX , $req )) {
unset ( $requires [ $index ]);
}
}
// if there are no other requirements, move the plugin to the top of the op list
if ( ! count ( $requires )) {
$installerOps [] = $op ;
unset ( $operations [ $idx ]);
}
2013-08-11 22:28:33 +00:00
}
2013-07-23 15:26:19 +00:00
}
2013-08-11 22:28:33 +00:00
return array_merge ( $installerOps , $operations );
2013-07-23 15:26:19 +00:00
}
2014-04-07 09:10:26 +00:00
/**
* Removals of packages should be executed before installations in
* case two packages resolve to the same path ( due to custom installers )
*
* @ param OperationInterface [] $operations
* @ return OperationInterface [] reordered operation list
*/
private function moveUninstallsToFront ( array $operations )
{
$uninstOps = array ();
foreach ( $operations as $idx => $op ) {
if ( $op instanceof UninstallOperation ) {
$uninstOps [] = $op ;
unset ( $operations [ $idx ]);
}
}
return array_merge ( $uninstOps , $operations );
}
2015-02-17 14:37:33 +00:00
private function createPool ( $withDevReqs , RepositoryInterface $lockedRepository = null )
2013-03-02 23:41:12 +00:00
{
2015-02-17 14:37:33 +00:00
if ( ! $this -> update && $this -> locker -> isLocked ()) { // install from lock
2013-03-02 23:41:12 +00:00
$minimumStability = $this -> locker -> getMinimumStability ();
$stabilityFlags = $this -> locker -> getStabilityFlags ();
2015-02-17 14:37:33 +00:00
$requires = array ();
foreach ( $lockedRepository -> getPackages () as $package ) {
$constraint = new VersionConstraint ( '=' , $package -> getVersion ());
$constraint -> setPrettyString ( $package -> getPrettyVersion ());
$requires [ $package -> getName ()] = $constraint ;
}
} else {
$minimumStability = $this -> package -> getMinimumStability ();
$stabilityFlags = $this -> package -> getStabilityFlags ();
$requires = $this -> package -> getRequires ();
if ( $withDevReqs ) {
$requires = array_merge ( $requires , $this -> package -> getDevRequires ());
}
2013-10-14 02:01:26 +00:00
}
2015-02-17 14:37:33 +00:00
2013-10-14 02:01:26 +00:00
$rootConstraints = array ();
foreach ( $requires as $req => $constraint ) {
2014-10-17 14:26:00 +00:00
// skip platform requirements from the root package to avoid filtering out existing platform packages
if ( $this -> ignorePlatformReqs && preg_match ( PlatformRepository :: PLATFORM_PACKAGE_REGEX , $req )) {
continue ;
}
2015-02-17 14:37:33 +00:00
if ( $constraint instanceof Link ) {
$rootConstraints [ $req ] = $constraint -> getConstraint ();
} else {
$rootConstraints [ $req ] = $constraint ;
}
2013-10-14 02:01:26 +00:00
}
return new Pool ( $minimumStability , $stabilityFlags , $rootConstraints );
2013-03-28 20:02:55 +00:00
}
private function createPolicy ()
{
2014-07-19 17:43:59 +00:00
$preferStable = null ;
2014-12-13 22:56:15 +00:00
$preferLowest = null ;
2014-07-19 17:43:59 +00:00
if ( ! $this -> update && $this -> locker -> isLocked ()) {
$preferStable = $this -> locker -> getPreferStable ();
2014-12-13 22:56:15 +00:00
$preferLowest = $this -> locker -> getPreferLowest ();
2014-07-19 17:43:59 +00:00
}
2014-12-13 22:56:15 +00:00
// old lock file without prefer stable/lowest will return null
2014-07-19 17:43:59 +00:00
// so in this case we use the composer.json info
if ( null === $preferStable ) {
2014-12-02 08:18:44 +00:00
$preferStable = $this -> preferStable || $this -> package -> getPreferStable ();
2014-12-13 22:56:15 +00:00
}
if ( null === $preferLowest ) {
2014-12-02 08:18:44 +00:00
$preferLowest = $this -> preferLowest ;
2014-07-19 17:43:59 +00:00
}
2014-11-21 13:01:01 +00:00
return new DefaultPolicy ( $preferStable , $preferLowest );
2013-03-02 23:41:12 +00:00
}
2015-04-30 15:24:24 +00:00
private function createRequest ( RootPackageInterface $rootPackage , PlatformRepository $platformRepo )
2013-03-02 23:41:12 +00:00
{
2015-04-30 15:24:24 +00:00
$request = new Request ();
2013-03-02 23:41:12 +00:00
$constraint = new VersionConstraint ( '=' , $rootPackage -> getVersion ());
$constraint -> setPrettyString ( $rootPackage -> getPrettyVersion ());
$request -> install ( $rootPackage -> getName (), $constraint );
2013-05-11 11:01:08 +00:00
$fixedPackages = $platformRepo -> getPackages ();
2013-05-10 17:25:23 +00:00
if ( $this -> additionalInstalledRepository ) {
2013-05-11 11:01:08 +00:00
$additionalFixedPackages = $this -> additionalInstalledRepository -> getPackages ();
$fixedPackages = array_merge ( $fixedPackages , $additionalFixedPackages );
2013-05-10 17:25:23 +00:00
}
2013-05-11 11:01:08 +00:00
// 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 ) {
2013-03-02 23:41:12 +00:00
$constraint = new VersionConstraint ( '=' , $package -> getVersion ());
$constraint -> setPrettyString ( $package -> getPrettyVersion ());
2013-05-11 11:01:08 +00:00
// skip platform packages that are provided by the root package
if ( $package -> getRepository () !== $platformRepo
2013-03-02 23:41:12 +00:00
|| ! isset ( $provided [ $package -> getName ()])
|| ! $provided [ $package -> getName ()] -> getConstraint () -> matches ( $constraint )
) {
2014-10-17 14:26:00 +00:00
$request -> fix ( $package -> getName (), $constraint );
2013-03-02 23:41:12 +00:00
}
}
return $request ;
}
2015-04-30 14:14:20 +00:00
private function processDevPackages ( $localRepo , $pool , $policy , $repositories , $installedRepo , $lockedRepository , $installFromLock , $withDevReqs , $task , array $operations = null )
2012-11-22 21:47:19 +00:00
{
if ( $task === 'force-updates' && null === $operations ) {
throw new \InvalidArgumentException ( 'Missing operations argument' );
}
if ( $task === 'force-links' ) {
$operations = array ();
}
2015-04-30 14:14:20 +00:00
if ( ! $installFromLock && $this -> updateWhitelist ) {
$currentPackages = $this -> getCurrentPackages ( $withDevReqs , $installedRepo );
}
2013-04-28 20:32:46 +00:00
foreach ( $localRepo -> getCanonicalPackages () as $package ) {
2012-05-16 15:14:25 +00:00
// skip non-dev packages
if ( ! $package -> isDev ()) {
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 ;
2012-03-03 05:35:40 +00:00
}
2012-05-16 15:14:25 +00:00
}
2012-03-03 05:35:40 +00:00
2012-05-16 15:14:25 +00:00
// force update to locked version if it does not match the installed version
if ( $installFromLock ) {
2012-09-14 14:43:56 +00:00
foreach ( $lockedRepository -> findPackages ( $package -> getName ()) as $lockedPackage ) {
2012-11-22 21:47:19 +00:00
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 );
}
}
2012-09-14 14:43:56 +00:00
2012-05-16 15:14:25 +00:00
break ;
2012-03-03 05:35:40 +00:00
}
}
2012-05-16 15:14:25 +00:00
} else {
2012-04-02 19:46:05 +00:00
// force update to latest on update
if ( $this -> update ) {
2012-05-27 21:21:10 +00:00
// skip package if the whitelist is enabled and it is not in it
2012-05-27 22:11:47 +00:00
if ( $this -> updateWhitelist && ! $this -> isUpdateable ( $package )) {
2015-04-30 14:14:20 +00:00
// check if non-updateable packages are out of date compared to the lock file to ensure we don't corrupt it
foreach ( $currentPackages as $curPackage ) {
if ( $curPackage -> isDev () && $curPackage -> getName () === $package -> getName () && $curPackage -> getVersion () === $package -> getVersion ()) {
if ( $task === 'force-links' ) {
$package -> setRequires ( $curPackage -> getRequires ());
$package -> setConflicts ( $curPackage -> getConflicts ());
$package -> setProvides ( $curPackage -> getProvides ());
$package -> setReplaces ( $curPackage -> getReplaces ());
} elseif ( $task === 'force-updates' ) {
if (( $curPackage -> getSourceReference () && $curPackage -> getSourceReference () !== $package -> getSourceReference ())
|| ( $curPackage -> getDistReference () && $curPackage -> getDistReference () !== $package -> getDistReference ())
) {
$operations [] = new UpdateOperation ( $package , $curPackage );
}
}
break ;
}
}
2012-05-26 13:20:27 +00:00
continue ;
}
2012-10-24 15:06:42 +00:00
// find similar packages (name/version) in all repositories
2012-08-24 00:29:03 +00:00
$matches = $pool -> whatProvides ( $package -> getName (), new VersionConstraint ( '=' , $package -> getVersion ()));
2012-10-24 15:06:42 +00:00
foreach ( $matches as $index => $match ) {
2012-08-24 10:06:29 +00:00
// skip local packages
if ( ! in_array ( $match -> getRepository (), $repositories , true )) {
2012-10-24 15:06:42 +00:00
unset ( $matches [ $index ]);
2012-08-24 10:06:29 +00:00
continue ;
2012-08-24 00:29:03 +00:00
}
2012-08-24 10:06:29 +00:00
2012-08-27 10:03:07 +00:00
// skip providers/replacers
if ( $match -> getName () !== $package -> getName ()) {
2012-10-24 15:06:42 +00:00
unset ( $matches [ $index ]);
2012-08-27 10:03:07 +00:00
continue ;
}
2012-10-24 15:06:42 +00:00
$matches [ $index ] = $match -> getId ();
2012-08-24 00:29:03 +00:00
}
2015-03-20 14:23:24 +00:00
// select preferred package according to policy rules
if ( $matches && $matches = $policy -> selectPreferredPackages ( $pool , array (), $matches )) {
2012-10-24 15:06:42 +00:00
$newPackage = $pool -> literalToPackage ( $matches [ 0 ]);
2012-11-22 21:47:19 +00:00
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 ())
)
)) {
2012-10-24 15:06:42 +00:00
$operations [] = new UpdateOperation ( $package , $newPackage );
}
2012-04-02 19:46:05 +00:00
}
2012-05-16 15:14:25 +00:00
}
2012-11-22 21:47:19 +00:00
if ( $task === 'force-updates' ) {
2015-04-30 15:41:28 +00:00
// force installed package to update to referenced version in root package if it does not match the installed version
2012-05-23 13:16:24 +00:00
$references = $this -> package -> getReferences ();
2012-11-22 21:47:19 +00:00
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 );
2012-05-16 15:14:25 +00:00
}
2012-03-03 05:35:40 +00:00
}
2012-05-23 13:16:24 +00:00
}
2012-03-03 05:35:40 +00:00
}
2012-11-22 21:47:19 +00:00
return $operations ;
2012-04-14 13:45:25 +00:00
}
2015-04-30 14:14:20 +00:00
/**
* Loads the most " current " list of packages that are installed meaning from lock ideally or from installed repo as fallback
*/
private function getCurrentPackages ( $withDevReqs , $installedRepo )
{
if ( $this -> locker -> isLocked ()) {
try {
return $this -> locker -> getLockedRepository ( $withDevReqs ) -> getPackages ();
} catch ( \RuntimeException $e ) {
// fetch only non-dev packages from lock if doing a dev update fails due to a previously incomplete lock file
return $this -> locker -> getLockedRepository () -> getPackages ();
}
}
return $installedRepo -> getPackages ();
}
2012-08-22 13:39:16 +00:00
private function getRootAliases ()
2012-04-14 13:45:25 +00:00
{
if ( ! $this -> update && $this -> locker -> isLocked ()) {
$aliases = $this -> locker -> getAliases ();
} else {
$aliases = $this -> package -> getAliases ();
2012-04-14 10:07:49 +00:00
}
2012-08-22 12:20:43 +00:00
$normalizedAliases = array ();
2012-04-14 13:45:25 +00:00
foreach ( $aliases as $alias ) {
2012-08-22 13:39:16 +00:00
$normalizedAliases [ $alias [ 'package' ]][ $alias [ 'version' ]] = array (
'alias' => $alias [ 'alias' ],
'alias_normalized' => $alias [ 'alias_normalized' ]
);
2012-03-03 05:35:40 +00:00
}
2012-03-18 21:43:07 +00:00
2012-08-22 12:20:43 +00:00
return $normalizedAliases ;
2012-03-03 05:35:40 +00:00
}
2012-03-05 23:48:07 +00:00
2015-04-30 15:41:28 +00:00
private function processPackageUrls ( $pool , $policy , $localRepo , $repositories )
{
if ( ! $this -> update ) {
return ;
}
foreach ( $localRepo -> getCanonicalPackages () as $package ) {
// 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 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
$package -> setSourceUrl ( $newPackage -> getSourceUrl ());
2015-06-20 11:58:19 +00:00
// only update dist url for github/bitbucket dists as they use a combination of dist url + dist reference to install
2015-05-01 15:26:59 +00:00
// but for other urls this is ambiguous and could result in bad outcomes
2015-06-19 22:23:27 +00:00
if ( preg_match ( '{^https?://(?:(?:www\.)?bitbucket\.org|(api\.)?github\.com)/}' , $newPackage -> getDistUrl ())) {
2015-05-01 15:26:59 +00:00
$package -> setDistUrl ( $newPackage -> getDistUrl ());
}
2015-04-30 15:41:28 +00:00
}
}
}
2012-08-22 13:39:16 +00:00
private function aliasPlatformPackages ( PlatformRepository $platformRepo , $aliases )
{
foreach ( $aliases as $package => $versions ) {
foreach ( $versions as $version => $alias ) {
$packages = $platformRepo -> findPackages ( $package , $version );
foreach ( $packages as $package ) {
$aliasPackage = new AliasPackage ( $package , $alias [ 'alias_normalized' ], $alias [ 'alias' ]);
$aliasPackage -> setRootPackageAlias ( true );
$platformRepo -> addPackage ( $aliasPackage );
}
}
}
}
2012-05-27 22:11:47 +00:00
private function isUpdateable ( PackageInterface $package )
{
if ( ! $this -> updateWhitelist ) {
throw new \LogicException ( 'isUpdateable should only be called when a whitelist is present' );
}
2012-12-13 14:37:11 +00:00
foreach ( $this -> updateWhitelist as $whiteListedPattern => $void ) {
2014-02-24 11:28:08 +00:00
$patternRegexp = $this -> packageNameToRegexp ( $whiteListedPattern );
if ( preg_match ( $patternRegexp , $package -> getName ())) {
2012-12-13 09:08:04 +00:00
return true ;
}
}
return false ;
2012-05-27 23:58:54 +00:00
}
2014-02-24 11:28:08 +00:00
/**
* Build a regexp from a package name , expanding * globs as required
*
2014-06-10 14:02:44 +00:00
* @ param string $whiteListedPattern
2014-02-24 11:28:08 +00:00
* @ return string
*/
private function packageNameToRegexp ( $whiteListedPattern )
{
$cleanedWhiteListedPattern = str_replace ( '\\*' , '.*' , preg_quote ( $whiteListedPattern ));
2014-02-24 11:49:09 +00:00
return " { ^ " . $cleanedWhiteListedPattern . " $ }i " ;
2014-02-24 11:28:08 +00:00
}
2013-06-13 11:28:24 +00:00
private function extractPlatformRequirements ( $links )
{
2013-03-03 19:05:46 +00:00
$platformReqs = array ();
foreach ( $links as $link ) {
2013-04-06 20:26:10 +00:00
if ( preg_match ( PlatformRepository :: PLATFORM_PACKAGE_REGEX , $link -> getTarget ())) {
2013-03-03 19:05:46 +00:00
$platformReqs [ $link -> getTarget ()] = $link -> getPrettyConstraint ();
}
}
return $platformReqs ;
}
2012-05-27 23:58:54 +00:00
/**
* Adds all dependencies of the update whitelist to the whitelist , too .
*
2012-05-28 10:02:15 +00:00
* Packages which are listed as requirements in the root package will be
* skipped including their dependencies , unless they are listed in the
* update whitelist themselves .
*
2012-05-27 23:58:54 +00:00
* @ param RepositoryInterface $localRepo
2012-05-28 14:38:52 +00:00
* @ param boolean $devMode
* @ param array $rootRequires An array of links to packages in require of the root package
* @ param array $rootDevRequires An array of links to packages in require - dev of the root package
2012-05-27 23:58:54 +00:00
*/
2012-05-28 10:02:15 +00:00
private function whitelistUpdateDependencies ( $localRepo , $devMode , array $rootRequires , array $rootDevRequires )
2012-05-27 23:58:54 +00:00
{
if ( ! $this -> updateWhitelist ) {
return ;
2012-05-27 22:11:47 +00:00
}
2013-03-02 19:18:38 +00:00
$requiredPackageNames = array ();
foreach ( array_merge ( $rootRequires , $rootDevRequires ) as $require ) {
$requiredPackageNames [] = $require -> getTarget ();
}
2012-05-28 10:02:15 +00:00
if ( $devMode ) {
$rootRequires = array_merge ( $rootRequires , $rootDevRequires );
}
$skipPackages = array ();
foreach ( $rootRequires as $require ) {
$skipPackages [ $require -> getTarget ()] = true ;
}
2012-05-27 23:58:54 +00:00
$pool = new Pool ;
$pool -> addRepository ( $localRepo );
$seen = array ();
2014-02-24 11:28:08 +00:00
$rootRequiredPackageNames = array_keys ( $rootRequires );
2012-05-27 23:58:54 +00:00
foreach ( $this -> updateWhitelist as $packageName => $void ) {
$packageQueue = new \SplQueue ;
2013-03-01 13:35:32 +00:00
$depPackages = $pool -> whatProvides ( $packageName );
2014-02-24 11:28:08 +00:00
2014-02-24 11:49:09 +00:00
$nameMatchesRequiredPackage = in_array ( $packageName , $requiredPackageNames , true );
2014-02-24 11:28:08 +00:00
2014-02-24 11:49:09 +00:00
// check if the name is a glob pattern that did not match directly
2014-02-24 11:28:08 +00:00
if ( ! $nameMatchesRequiredPackage ) {
$whitelistPatternRegexp = $this -> packageNameToRegexp ( $packageName );
foreach ( $rootRequiredPackageNames as $rootRequiredPackageName ) {
if ( preg_match ( $whitelistPatternRegexp , $rootRequiredPackageName )) {
$nameMatchesRequiredPackage = true ;
break ;
}
}
}
if ( count ( $depPackages ) == 0 && ! $nameMatchesRequiredPackage && ! in_array ( $packageName , array ( 'nothing' , 'lock' ))) {
2015-02-06 12:52:44 +00:00
$this -> io -> writeError ( '<warning>Package "' . $packageName . '" listed for update is not installed. Ignoring.</warning>' );
2013-03-01 13:35:32 +00:00
}
foreach ( $depPackages as $depPackage ) {
2012-05-27 23:58:54 +00:00
$packageQueue -> enqueue ( $depPackage );
2012-05-27 22:11:47 +00:00
}
2012-05-27 23:58:54 +00:00
while ( ! $packageQueue -> isEmpty ()) {
$package = $packageQueue -> dequeue ();
if ( isset ( $seen [ $package -> getId ()])) {
continue ;
}
$seen [ $package -> getId ()] = true ;
$this -> updateWhitelist [ $package -> getName ()] = true ;
2013-10-14 08:49:34 +00:00
if ( ! $this -> whitelistDependencies ) {
continue ;
}
2012-05-27 23:58:54 +00:00
$requires = $package -> getRequires ();
foreach ( $requires as $require ) {
$requirePackages = $pool -> whatProvides ( $require -> getTarget ());
foreach ( $requirePackages as $requirePackage ) {
2012-05-28 10:02:15 +00:00
if ( isset ( $skipPackages [ $requirePackage -> getName ()])) {
continue ;
}
2012-05-27 23:58:54 +00:00
$packageQueue -> enqueue ( $requirePackage );
}
}
}
}
2012-05-27 22:11:47 +00:00
}
2012-10-22 13:50:40 +00:00
/**
* Replace local repositories with InstalledArrayRepository instances
*
* This is to prevent any accidental modification of the existing repos on disk
*
* @ param RepositoryManager $rm
*/
private function mockLocalRepositories ( RepositoryManager $rm )
{
2013-03-21 11:08:58 +00:00
$packages = array ();
foreach ( $rm -> getLocalRepository () -> getPackages () as $package ) {
$packages [( string ) $package ] = clone $package ;
}
2012-10-22 13:50:40 +00:00
foreach ( $packages as $key => $package ) {
if ( $package instanceof AliasPackage ) {
2013-03-21 11:08:58 +00:00
$alias = ( string ) $package -> getAliasOf ();
$packages [ $key ] = new AliasPackage ( $packages [ $alias ], $package -> getVersion (), $package -> getPrettyVersion ());
2012-10-22 13:50:40 +00:00
}
}
$rm -> setLocalRepository (
new InstalledArrayRepository ( $packages )
);
}
2012-03-05 23:48:07 +00:00
/**
2012-03-06 23:30:18 +00:00
* Create Installer
2012-03-10 00:16:37 +00:00
*
2013-06-13 11:28:24 +00:00
* @ param IOInterface $io
* @ param Composer $composer
2012-03-06 23:30:18 +00:00
* @ return Installer
2012-03-05 23:48:07 +00:00
*/
2013-01-06 19:34:52 +00:00
public static function create ( IOInterface $io , Composer $composer )
2012-03-05 23:48:07 +00:00
{
return new static (
$io ,
2012-06-24 19:58:51 +00:00
$composer -> getConfig (),
2012-03-05 23:48:07 +00:00
$composer -> getPackage (),
$composer -> getDownloadManager (),
$composer -> getRepositoryManager (),
$composer -> getLocker (),
$composer -> getInstallationManager (),
2013-01-06 19:34:52 +00:00
$composer -> getEventDispatcher (),
$composer -> getAutoloadGenerator ()
2012-03-05 23:48:07 +00:00
);
}
2012-03-10 17:08:36 +00:00
public function setAdditionalInstalledRepository ( RepositoryInterface $additionalInstalledRepository )
{
$this -> additionalInstalledRepository = $additionalInstalledRepository ;
return $this ;
}
/**
2012-10-24 23:14:04 +00:00
* Whether to run in drymode or not
2012-03-10 17:08:36 +00:00
*
2012-05-22 10:07:08 +00:00
* @ param boolean $dryRun
2012-03-10 17:08:36 +00:00
* @ return Installer
*/
2012-04-14 09:55:57 +00:00
public function setDryRun ( $dryRun = true )
2012-03-10 17:08:36 +00:00
{
2012-03-10 19:14:54 +00:00
$this -> dryRun = ( boolean ) $dryRun ;
2012-03-10 17:08:36 +00:00
return $this ;
}
2014-10-11 17:30:19 +00:00
/**
* Checks , if this is a dry run ( simulation mode ) .
*
* @ return bool
*/
public function isDryRun ()
{
return $this -> dryRun ;
}
2012-03-10 17:08:36 +00:00
/**
2012-04-14 09:55:57 +00:00
* prefer source installation
2012-03-10 17:08:36 +00:00
*
2012-05-22 10:07:08 +00:00
* @ param boolean $preferSource
2012-03-10 17:08:36 +00:00
* @ return Installer
*/
2012-04-14 09:55:57 +00:00
public function setPreferSource ( $preferSource = true )
2012-03-10 17:08:36 +00:00
{
2012-04-14 09:55:57 +00:00
$this -> preferSource = ( boolean ) $preferSource ;
2012-03-10 17:08:36 +00:00
return $this ;
}
2012-08-31 20:25:17 +00:00
/**
* prefer dist installation
*
* @ param boolean $preferDist
* @ return Installer
*/
public function setPreferDist ( $preferDist = true )
{
$this -> preferDist = ( boolean ) $preferDist ;
return $this ;
}
2012-10-23 11:41:17 +00:00
/**
2012-10-24 23:14:04 +00:00
* Whether or not generated autoloader are optimized
2012-10-23 11:41:17 +00:00
*
2013-01-05 19:01:58 +00:00
* @ param bool $optimizeAutoloader
2012-10-23 11:41:17 +00:00
* @ return Installer
*/
2012-10-24 15:33:31 +00:00
public function setOptimizeAutoloader ( $optimizeAutoloader = false )
2012-10-23 11:41:17 +00:00
{
2012-10-24 15:33:31 +00:00
$this -> optimizeAutoloader = ( boolean ) $optimizeAutoloader ;
2012-10-23 11:41:17 +00:00
return $this ;
}
2012-03-10 17:08:36 +00:00
/**
2012-04-14 09:55:57 +00:00
* update packages
2012-03-10 17:08:36 +00:00
*
2012-05-22 10:07:08 +00:00
* @ param boolean $update
2012-03-10 17:08:36 +00:00
* @ return Installer
*/
2012-04-14 09:55:57 +00:00
public function setUpdate ( $update = true )
2012-03-10 17:08:36 +00:00
{
2012-04-14 09:55:57 +00:00
$this -> update = ( boolean ) $update ;
2012-03-10 17:08:36 +00:00
return $this ;
}
/**
2012-04-14 09:55:57 +00:00
* enables dev packages
2012-03-10 17:08:36 +00:00
*
2012-05-23 09:11:19 +00:00
* @ param boolean $devMode
2012-03-10 17:08:36 +00:00
* @ return Installer
*/
2012-04-14 09:55:57 +00:00
public function setDevMode ( $devMode = true )
2012-03-10 17:08:36 +00:00
{
2012-04-14 09:55:57 +00:00
$this -> devMode = ( boolean ) $devMode ;
2012-03-10 17:08:36 +00:00
return $this ;
}
2014-11-21 21:16:19 +00:00
/**
* set whether to run autoloader or not
2014-12-29 20:29:13 +00:00
*
* @ param boolean $dumpAutoloader
2014-11-21 21:16:19 +00:00
* @ return Installer
*/
2014-12-29 20:29:13 +00:00
public function setDumpAutoloader ( $dumpAutoloader = true )
2014-11-21 21:16:19 +00:00
{
2014-12-29 20:29:13 +00:00
$this -> dumpAutoloader = ( boolean ) $dumpAutoloader ;
2014-11-21 21:16:19 +00:00
return $this ;
}
2012-04-16 17:45:06 +00:00
/**
2012-05-13 11:25:02 +00:00
* set whether to run scripts or not
2012-04-16 17:45:06 +00:00
*
2012-05-27 23:58:49 +00:00
* @ param boolean $runScripts
2012-04-16 17:45:06 +00:00
* @ return Installer
*/
2012-05-13 11:25:02 +00:00
public function setRunScripts ( $runScripts = true )
2012-04-16 17:45:06 +00:00
{
2012-05-13 11:25:02 +00:00
$this -> runScripts = ( boolean ) $runScripts ;
2012-04-16 17:45:06 +00:00
return $this ;
}
2012-06-24 19:58:51 +00:00
/**
* set the config instance
*
* @ param Config $config
* @ return Installer
*/
public function setConfig ( Config $config )
{
$this -> config = $config ;
return $this ;
}
2012-03-10 17:08:36 +00:00
/**
* run in verbose mode
*
2012-05-22 10:07:08 +00:00
* @ param boolean $verbose
2012-03-10 17:08:36 +00:00
* @ return Installer
*/
2012-04-14 09:55:57 +00:00
public function setVerbose ( $verbose = true )
2012-03-10 17:08:36 +00:00
{
2012-03-10 19:14:54 +00:00
$this -> verbose = ( boolean ) $verbose ;
2012-03-10 17:08:36 +00:00
return $this ;
}
2012-05-26 13:20:27 +00:00
2014-10-11 17:46:37 +00:00
/**
* Checks , if running in verbose mode .
*
* @ return bool
*/
public function isVerbose ()
{
return $this -> verbose ;
}
2014-10-02 05:01:15 +00:00
/**
* set ignore Platform Package requirements
*
2014-10-17 14:26:00 +00:00
* @ param boolean $ignorePlatformReqs
2014-10-02 05:01:15 +00:00
* @ return Installer
*/
2014-10-17 14:26:00 +00:00
public function setIgnorePlatformRequirements ( $ignorePlatformReqs = false )
2014-10-15 13:42:07 +00:00
{
2014-10-17 14:26:00 +00:00
$this -> ignorePlatformReqs = ( boolean ) $ignorePlatformReqs ;
2014-10-02 05:01:15 +00:00
return $this ;
}
2012-05-26 13:20:27 +00:00
/**
* restrict the update operation to a few packages , all other packages
* that are already installed will be kept at their current version
*
* @ param array $packages
* @ return Installer
*/
public function setUpdateWhitelist ( array $packages )
{
2012-05-27 23:58:54 +00:00
$this -> updateWhitelist = array_flip ( array_map ( 'strtolower' , $packages ));
2012-05-26 13:20:27 +00:00
return $this ;
}
2012-07-21 14:51:40 +00:00
2013-10-14 08:49:34 +00:00
/**
* Should dependencies of whitelisted packages be updated recursively ?
*
2014-06-10 14:02:44 +00:00
* @ param boolean $updateDependencies
2013-10-14 08:49:34 +00:00
* @ return Installer
*/
public function setWhitelistDependencies ( $updateDependencies = true )
{
$this -> whitelistDependencies = ( boolean ) $updateDependencies ;
return $this ;
}
2014-11-21 13:01:01 +00:00
/**
2015-03-20 14:23:24 +00:00
* Should packages be preferred in a stable version when updating ?
2014-12-02 08:18:44 +00:00
*
* @ param boolean $preferStable
* @ return Installer
*/
public function setPreferStable ( $preferStable = true )
{
$this -> preferStable = ( boolean ) $preferStable ;
return $this ;
}
/**
2015-03-20 14:23:24 +00:00
* Should packages be preferred in a lowest version when updating ?
2014-11-21 13:01:01 +00:00
*
2014-12-02 08:18:44 +00:00
* @ param boolean $preferLowest
2014-11-21 13:01:01 +00:00
* @ return Installer
*/
2014-12-02 08:18:44 +00:00
public function setPreferLowest ( $preferLowest = true )
2014-11-21 13:01:01 +00:00
{
2014-12-02 08:18:44 +00:00
$this -> preferLowest = ( boolean ) $preferLowest ;
2014-11-21 13:01:01 +00:00
return $this ;
}
2012-07-21 14:51:40 +00:00
/**
2013-08-13 11:25:21 +00:00
* Disables plugins .
2012-07-21 14:51:40 +00:00
*
* Call this if you want to ensure that third - party code never gets
* executed . The default is to automatically install , and execute
* custom third - party installers .
2012-11-01 15:22:37 +00:00
*
* @ return Installer
2012-07-21 14:51:40 +00:00
*/
2013-08-13 11:25:21 +00:00
public function disablePlugins ()
2012-07-21 14:51:40 +00:00
{
2013-08-13 11:25:21 +00:00
$this -> installationManager -> disablePlugins ();
2012-11-01 15:22:37 +00:00
return $this ;
2012-07-21 14:51:40 +00:00
}
2012-03-03 05:35:40 +00:00
}