2011-09-23 23:09:51 +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\Downloader ;
use Composer\Package\PackageInterface ;
use Composer\Downloader\DownloaderInterface ;
2012-02-09 17:45:28 +00:00
use Composer\Util\Filesystem ;
2011-09-23 23:09:51 +00:00
/**
* Downloaders manager .
*
* @ author Konstantin Kudryashov < ever . zet @ gmail . com >
*/
class DownloadManager
{
2012-08-31 20:25:17 +00:00
private $preferDist = false ;
2011-09-23 23:09:51 +00:00
private $preferSource = false ;
2012-04-27 09:21:58 +00:00
private $filesystem ;
2011-09-23 23:09:51 +00:00
private $downloaders = array ();
/**
* Initializes download manager .
*
2012-08-18 14:18:41 +00:00
* @ param bool $preferSource prefer downloading from source
* @ param Filesystem | null $filesystem custom Filesystem object
2011-09-23 23:09:51 +00:00
*/
2012-04-27 09:21:58 +00:00
public function __construct ( $preferSource = false , Filesystem $filesystem = null )
2011-09-23 23:09:51 +00:00
{
$this -> preferSource = $preferSource ;
2012-04-27 09:21:58 +00:00
$this -> filesystem = $filesystem ? : new Filesystem ();
2011-09-23 23:09:51 +00:00
}
/**
* Makes downloader prefer source installation over the dist .
*
2012-06-23 09:58:18 +00:00
* @ param bool $preferSource prefer downloading from source
2011-09-23 23:09:51 +00:00
*/
2011-10-30 19:59:41 +00:00
public function setPreferSource ( $preferSource )
2011-09-23 23:09:51 +00:00
{
$this -> preferSource = $preferSource ;
2012-05-18 14:12:18 +00:00
2012-05-17 18:07:49 +00:00
return $this ;
2011-09-23 23:09:51 +00:00
}
2012-08-31 20:25:17 +00:00
/**
* Makes downloader prefer dist installation over the source .
*
* @ param bool $preferDist prefer downloading from dist
*/
public function setPreferDist ( $preferDist )
{
$this -> preferDist = $preferDist ;
return $this ;
}
2011-09-23 23:09:51 +00:00
/**
* Sets installer downloader for a specific installation type .
*
2012-05-22 10:07:08 +00:00
* @ param string $type installation type
* @ param DownloaderInterface $downloader downloader instance
2011-09-23 23:09:51 +00:00
*/
public function setDownloader ( $type , DownloaderInterface $downloader )
{
2012-05-17 18:07:49 +00:00
$type = strtolower ( $type );
2011-09-23 23:09:51 +00:00
$this -> downloaders [ $type ] = $downloader ;
2012-05-18 14:12:18 +00:00
2012-05-17 18:07:49 +00:00
return $this ;
2011-09-23 23:09:51 +00:00
}
/**
* Returns downloader for a specific installation type .
*
2012-05-22 10:07:08 +00:00
* @ param string $type installation type
2011-09-23 23:09:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ return DownloaderInterface
2011-09-23 23:09:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ throws UnexpectedValueException if downloader for provided type is not registeterd
2011-09-23 23:09:51 +00:00
*/
public function getDownloader ( $type )
{
2012-05-17 18:07:49 +00:00
$type = strtolower ( $type );
2011-09-23 23:09:51 +00:00
if ( ! isset ( $this -> downloaders [ $type ])) {
2011-10-30 19:16:41 +00:00
throw new \InvalidArgumentException ( 'Unknown downloader type: ' . $type );
2011-09-23 23:09:51 +00:00
}
return $this -> downloaders [ $type ];
}
2011-09-29 01:11:51 +00:00
/**
* Returns downloader for already installed package .
*
2012-05-22 10:07:08 +00:00
* @ param PackageInterface $package package instance
2011-09-29 01:11:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ return DownloaderInterface
2011-09-29 01:11:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ throws InvalidArgumentException if package has no installation source specified
* @ throws LogicException if specific downloader used to load package with
2011-09-29 01:11:51 +00:00
* wrong type
*/
public function getDownloaderForInstalledPackage ( PackageInterface $package )
{
$installationSource = $package -> getInstallationSource ();
if ( 'dist' === $installationSource ) {
$downloader = $this -> getDownloader ( $package -> getDistType ());
} elseif ( 'source' === $installationSource ) {
$downloader = $this -> getDownloader ( $package -> getSourceType ());
} else {
throw new \InvalidArgumentException (
'Package ' . $package . ' seems not been installed properly'
);
}
if ( $installationSource !== $downloader -> getInstallationSource ()) {
throw new \LogicException ( sprintf (
'Downloader "%s" is a %s type downloader and can not be used to download %s' ,
get_class ( $downloader ), $downloader -> getInstallationSource (), $installationSource
));
}
return $downloader ;
}
2011-09-23 23:09:51 +00:00
/**
* Downloads package into target dir .
*
2012-05-22 10:07:08 +00:00
* @ param PackageInterface $package package instance
* @ param string $targetDir target dir
2012-06-23 09:58:18 +00:00
* @ param bool $preferSource prefer installation from source
2011-09-23 23:09:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ throws InvalidArgumentException if package have no urls to download from
2011-09-23 23:09:51 +00:00
*/
2011-09-25 15:30:54 +00:00
public function download ( PackageInterface $package , $targetDir , $preferSource = null )
2011-09-23 23:09:51 +00:00
{
2011-09-25 15:30:54 +00:00
$preferSource = null !== $preferSource ? $preferSource : $this -> preferSource ;
$sourceType = $package -> getSourceType ();
$distType = $package -> getDistType ();
2011-09-23 23:09:51 +00:00
2012-08-31 20:25:17 +00:00
if (( ! $package -> isDev () || $this -> preferDist ) && ! ( $preferSource && $sourceType ) && $distType ) {
2011-09-25 15:30:54 +00:00
$package -> setInstallationSource ( 'dist' );
2011-09-29 01:11:51 +00:00
} elseif ( $sourceType ) {
2011-09-25 15:30:54 +00:00
$package -> setInstallationSource ( 'source' );
2012-08-31 20:25:17 +00:00
} elseif ( $package -> isDev () && $distType ) {
throw new \InvalidArgumentException ( 'Dev package ' . $package . ' should have a source specified because for dev packages dist is used only with --prefer-dist option' );
2011-09-29 01:11:51 +00:00
} else {
2012-02-18 22:21:45 +00:00
throw new \InvalidArgumentException ( 'Package ' . $package . ' must have a source or dist specified' );
2011-09-23 23:09:51 +00:00
}
2011-09-28 22:48:17 +00:00
2012-04-27 09:21:58 +00:00
$this -> filesystem -> ensureDirectoryExists ( $targetDir );
2012-02-09 17:45:28 +00:00
2011-09-29 01:11:51 +00:00
$downloader = $this -> getDownloaderForInstalledPackage ( $package );
$downloader -> download ( $package , $targetDir );
2011-09-23 23:09:51 +00:00
}
/**
* Updates package from initial to target version .
*
2012-05-22 10:07:08 +00:00
* @ param PackageInterface $initial initial package version
* @ param PackageInterface $target target package version
* @ param string $targetDir target dir
2011-09-23 23:09:51 +00:00
*
2012-05-22 10:07:08 +00:00
* @ throws InvalidArgumentException if initial package is not installed
2011-09-23 23:09:51 +00:00
*/
2011-09-25 15:30:54 +00:00
public function update ( PackageInterface $initial , PackageInterface $target , $targetDir )
2011-09-23 23:09:51 +00:00
{
2011-09-29 01:11:51 +00:00
$downloader = $this -> getDownloaderForInstalledPackage ( $initial );
$installationSource = $initial -> getInstallationSource ();
2011-09-28 22:48:17 +00:00
2011-09-29 01:11:51 +00:00
if ( 'dist' === $installationSource ) {
2011-09-25 15:30:54 +00:00
$initialType = $initial -> getDistType ();
$targetType = $target -> getDistType ();
} else {
$initialType = $initial -> getSourceType ();
$targetType = $target -> getSourceType ();
}
2012-04-10 09:53:21 +00:00
// upgrading from a dist stable package to a dev package, force source reinstall
if ( $target -> isDev () && 'dist' === $installationSource ) {
$downloader -> remove ( $initial , $targetDir );
2012-04-10 11:52:53 +00:00
$this -> download ( $target , $targetDir );
2012-05-22 10:07:08 +00:00
2012-04-10 09:53:21 +00:00
return ;
}
2011-09-25 15:30:54 +00:00
if ( $initialType === $targetType ) {
2011-09-29 01:11:51 +00:00
$target -> setInstallationSource ( $installationSource );
$downloader -> update ( $initial , $target , $targetDir );
2011-09-23 23:09:51 +00:00
} else {
2011-09-28 22:48:17 +00:00
$downloader -> remove ( $initial , $targetDir );
2011-09-29 01:11:51 +00:00
$this -> download ( $target , $targetDir , 'source' === $installationSource );
2011-09-23 23:09:51 +00:00
}
}
/**
* Removes package from target dir .
*
2012-05-22 10:07:08 +00:00
* @ param PackageInterface $package package instance
* @ param string $targetDir target dir
2011-09-23 23:09:51 +00:00
*/
2011-09-25 15:30:54 +00:00
public function remove ( PackageInterface $package , $targetDir )
2011-09-23 23:09:51 +00:00
{
2011-09-29 01:11:51 +00:00
$downloader = $this -> getDownloaderForInstalledPackage ( $package );
$downloader -> remove ( $package , $targetDir );
2011-09-23 23:09:51 +00:00
}
}