Split up steps on VCS downloaders to allow doing network operations before touching the filesystem on GitDownloader, fixes #7903
parent
4dabc17ec1
commit
53d2ab2253
|
@ -165,9 +165,9 @@ class DownloadManager
|
|||
/**
|
||||
* Downloads package into target dir.
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
* @param PackageInterface $prevPackage previous package instance in case of updates
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
||||
*
|
||||
* @return PromiseInterface
|
||||
* @throws \InvalidArgumentException if package have no urls to download from
|
||||
|
@ -182,7 +182,7 @@ class DownloadManager
|
|||
$io = $this->io;
|
||||
$self = $this;
|
||||
|
||||
$download = function ($retry = false) use (&$sources, $io, $package, $self, $targetDir, &$download) {
|
||||
$download = function ($retry = false) use (&$sources, $io, $package, $self, $targetDir, &$download, $prevPackage) {
|
||||
$source = array_shift($sources);
|
||||
if ($retry) {
|
||||
$io->writeError(' <warning>Now trying to download from ' . $source . '</warning>');
|
||||
|
@ -214,7 +214,7 @@ class DownloadManager
|
|||
};
|
||||
|
||||
try {
|
||||
$result = $downloader->download($package, $targetDir);
|
||||
$result = $downloader->download($package, $targetDir, $prevPackage);
|
||||
} catch (\Exception $e) {
|
||||
return $handleError($e);
|
||||
}
|
||||
|
@ -232,12 +232,31 @@ class DownloadManager
|
|||
return $download();
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares an operation execution
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, $targetDir, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$downloader = $this->getDownloaderForPackage($package);
|
||||
if ($downloader) {
|
||||
return $downloader->prepare($type, $package, $targetDir, $prevPackage);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs package into target dir.
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
* @throws \InvalidArgumentException if package have no urls to download from
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
|
@ -245,7 +264,7 @@ class DownloadManager
|
|||
{
|
||||
$downloader = $this->getDownloaderForPackage($package);
|
||||
if ($downloader) {
|
||||
$downloader->install($package, $targetDir);
|
||||
return $downloader->install($package, $targetDir);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,6 +275,7 @@ class DownloadManager
|
|||
* @param PackageInterface $target target package version
|
||||
* @param string $targetDir target dir
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
* @throws \InvalidArgumentException if initial package is not installed
|
||||
*/
|
||||
public function update(PackageInterface $initial, PackageInterface $target, $targetDir)
|
||||
|
@ -270,17 +290,14 @@ class DownloadManager
|
|||
|
||||
// if we have a downloader present before, but not after, the package became a metapackage and its files should be removed
|
||||
if (!$downloader) {
|
||||
$initialDownloader->remove($initial, $targetDir);
|
||||
return;
|
||||
return $initialDownloader->remove($initial, $targetDir);
|
||||
}
|
||||
|
||||
$initialType = $this->getDownloaderType($initialDownloader);
|
||||
$targetType = $this->getDownloaderType($downloader);
|
||||
if ($initialType === $targetType) {
|
||||
try {
|
||||
$downloader->update($initial, $target, $targetDir);
|
||||
|
||||
return;
|
||||
return $downloader->update($initial, $target, $targetDir);
|
||||
} catch (\RuntimeException $e) {
|
||||
if (!$this->io->isInteractive()) {
|
||||
throw $e;
|
||||
|
@ -294,8 +311,15 @@ class DownloadManager
|
|||
|
||||
// if downloader type changed, or update failed and user asks for reinstall,
|
||||
// we wipe the dir and do a new install instead of updating it
|
||||
$initialDownloader->remove($initial, $targetDir);
|
||||
$this->install($target, $targetDir);
|
||||
$promise = $initialDownloader->remove($initial, $targetDir);
|
||||
if ($promise) {
|
||||
$self = $this;
|
||||
return $promise->then(function ($res) use ($self, $target, $targetDir) {
|
||||
return $self->install($target, $targetDir);
|
||||
});
|
||||
}
|
||||
|
||||
return $this->install($target, $targetDir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -303,12 +327,32 @@ class DownloadManager
|
|||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function remove(PackageInterface $package, $targetDir)
|
||||
{
|
||||
$downloader = $this->getDownloaderForPackage($package);
|
||||
if ($downloader) {
|
||||
$downloader->remove($package, $targetDir);
|
||||
return $downloader->remove($package, $targetDir);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleans up a failed operation
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $targetDir target dir
|
||||
* @param PackageInterface|null $prevPackage previous package instance in case of updates
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, $targetDir, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$downloader = $this->getDownloaderForPackage($package);
|
||||
if ($downloader) {
|
||||
return $downloader->cleanup($type, $package, $targetDir, $prevPackage);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,14 +31,30 @@ interface DownloaderInterface
|
|||
public function getInstallationSource();
|
||||
|
||||
/**
|
||||
* This should do any network-related tasks to prepare for install/update
|
||||
* This should do any network-related tasks to prepare for an upcoming install/update
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function download(PackageInterface $package, $path);
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Downloads specific package into specific folder.
|
||||
* Do anything that needs to be done between all downloads have been completed and the actual operation is executed
|
||||
*
|
||||
* All packages get first downloaded, then all together prepared, then all together installed/updated/uninstalled. Therefore
|
||||
* for error recovery it is important to avoid failing during install/update/uninstall as much as possible, and risky things or
|
||||
* user prompts should happen in the prepare step rather. In case of failure, cleanup() will be called so that changes can
|
||||
* be undone as much as possible.
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $path download path
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Installs specific package into specific folder.
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $path download path
|
||||
|
@ -61,4 +77,19 @@ interface DownloaderInterface
|
|||
* @param string $path download path
|
||||
*/
|
||||
public function remove(PackageInterface $package, $path);
|
||||
|
||||
/**
|
||||
* Do anything to cleanup changes applied in the prepare or install/update/uninstall steps
|
||||
*
|
||||
* Note that cleanup will be called for all packages regardless if they failed an operation or not, to give
|
||||
* all installers a change to cleanup things they did previously, so you need to keep track of changes
|
||||
* applied in the installer/downloader themselves.
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $path download path
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null);
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function download(PackageInterface $package, $path, $output = true)
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
||||
{
|
||||
if (!$package->getDistUrl()) {
|
||||
throw new \InvalidArgumentException('The given package is missing url information');
|
||||
|
@ -222,6 +222,20 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
|||
return $download();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -336,7 +350,7 @@ class FileDownloader implements DownloaderInterface, ChangeReportInterface
|
|||
$e = null;
|
||||
|
||||
try {
|
||||
$res = $this->download($package, $targetDir.'_compare', false);
|
||||
$res = $this->download($package, $targetDir.'_compare', null, false);
|
||||
$this->httpDownloader->wait();
|
||||
$res = $this->install($package, $targetDir.'_compare', false);
|
||||
|
||||
|
|
|
@ -23,7 +23,15 @@ class FossilDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doInstall(PackageInterface $package, $path, $url)
|
||||
protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function doInstall(PackageInterface $package, $path, $url)
|
||||
{
|
||||
// Ensure we are allowed to use this URL by config
|
||||
$this->config->prohibitUrlByConfig($url, $this->io);
|
||||
|
@ -49,7 +57,7 @@ class FossilDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
{
|
||||
// Ensure we are allowed to use this URL by config
|
||||
$this->config->prohibitUrlByConfig($url, $this->io);
|
||||
|
|
|
@ -29,6 +29,7 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
|||
private $hasStashedChanges = false;
|
||||
private $hasDiscardedChanges = false;
|
||||
private $gitUtil;
|
||||
private $cachedPackages = array();
|
||||
|
||||
public function __construct(IOInterface $io, Config $config, ProcessExecutor $process = null, Filesystem $fs = null)
|
||||
{
|
||||
|
@ -39,7 +40,28 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doInstall(PackageInterface $package, $path, $url)
|
||||
protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
|
||||
{
|
||||
GitUtil::cleanEnv();
|
||||
|
||||
$cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
|
||||
$gitVersion = $this->gitUtil->getVersion();
|
||||
|
||||
// --dissociate option is only available since git 2.3.0-rc0
|
||||
if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=') && Cache::isUsable($cachePath)) {
|
||||
$this->io->writeError(" - Syncing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>) into cache");
|
||||
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
|
||||
$ref = $package->getSourceReference();
|
||||
if ($this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref) && is_dir($cachePath)) {
|
||||
$this->cachedPackages[$package->getId()][$ref] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function doInstall(PackageInterface $package, $path, $url)
|
||||
{
|
||||
GitUtil::cleanEnv();
|
||||
$path = $this->normalizePath($path);
|
||||
|
@ -47,26 +69,20 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
|||
$ref = $package->getSourceReference();
|
||||
$flag = Platform::isWindows() ? '/D ' : '';
|
||||
|
||||
// --dissociate option is only available since git 2.3.0-rc0
|
||||
$gitVersion = $this->gitUtil->getVersion();
|
||||
$msg = "Cloning ".$this->getShortHash($ref);
|
||||
|
||||
$command = 'git clone --no-checkout %url% %path% && cd '.$flag.'%path% && git remote add composer %url% && git fetch composer';
|
||||
if ($gitVersion && version_compare($gitVersion, '2.3.0-rc0', '>=') && Cache::isUsable($cachePath)) {
|
||||
$this->io->writeError('', true, IOInterface::DEBUG);
|
||||
$this->io->writeError(sprintf(' Cloning to cache at %s', ProcessExecutor::escape($cachePath)), true, IOInterface::DEBUG);
|
||||
try {
|
||||
$this->gitUtil->fetchRefOrSyncMirror($url, $cachePath, $ref);
|
||||
if (is_dir($cachePath)) {
|
||||
$command =
|
||||
'git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath% '
|
||||
. '&& cd '.$flag.'%path% '
|
||||
. '&& git remote set-url origin %url% && git remote add composer %url%';
|
||||
$msg = "Cloning ".$this->getShortHash($ref).' from cache';
|
||||
}
|
||||
} catch (\RuntimeException $e) {
|
||||
if (!empty($this->cachedPackages[$package->getId()][$ref])) {
|
||||
$msg = "Cloning ".$this->getShortHash($ref).' from cache';
|
||||
$command =
|
||||
'git clone --no-checkout %cachePath% %path% --dissociate --reference %cachePath% '
|
||||
. '&& cd '.$flag.'%path% '
|
||||
. '&& git remote set-url origin %url% && git remote add composer %url%';
|
||||
} else {
|
||||
$msg = "Cloning ".$this->getShortHash($ref);
|
||||
$command = 'git clone --no-checkout %url% %path% && cd '.$flag.'%path% && git remote add composer %url% && git fetch composer';
|
||||
if (getenv('COMPOSER_DISABLE_NETWORK')) {
|
||||
throw new \RuntimeException('The required git reference for '.$package->getName().' is not in cache and network is disabled, aborting');
|
||||
}
|
||||
}
|
||||
|
||||
$this->io->writeError($msg);
|
||||
|
||||
$commandCallable = function ($url) use ($path, $command, $cachePath) {
|
||||
|
@ -99,13 +115,51 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
{
|
||||
GitUtil::cleanEnv();
|
||||
$path = $this->normalizePath($path);
|
||||
if (!$this->hasMetadataRepository($path)) {
|
||||
throw new \RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
|
||||
}
|
||||
|
||||
$cachePath = $this->config->get('cache-vcs-dir').'/'.preg_replace('{[^a-z0-9.]}i', '-', $url).'/';
|
||||
$ref = $target->getSourceReference();
|
||||
$flag = Platform::isWindows() ? '/D ' : '';
|
||||
|
||||
if (!empty($this->cachedPackages[$target->getId()][$ref])) {
|
||||
$msg = "Checking out ".$this->getShortHash($ref).' from cache';
|
||||
$command = 'git rev-parse --quiet --verify %ref% || (git remote set-url composer %cachePath% && git fetch composer && git fetch --tags composer); git remote set-url composer %url%';
|
||||
} else {
|
||||
$msg = "Checking out ".$this->getShortHash($ref);
|
||||
$command = 'git remote set-url composer %url% && git rev-parse --quiet --verify %ref% || (git fetch composer && git fetch --tags composer)';
|
||||
if (getenv('COMPOSER_DISABLE_NETWORK')) {
|
||||
throw new \RuntimeException('The required git reference for '.$package->getName().' is not in cache and network is disabled, aborting');
|
||||
}
|
||||
}
|
||||
|
||||
$this->io->writeError($msg);
|
||||
|
||||
$commandCallable = function ($url) use ($ref, $command, $cachePath) {
|
||||
return str_replace(
|
||||
array('%url%', '%ref%', '%cachePath%'),
|
||||
array(
|
||||
ProcessExecutor::escape($url),
|
||||
ProcessExecutor::escape($ref.'^{commit}'),
|
||||
ProcessExecutor::escape($cachePath),
|
||||
),
|
||||
$command
|
||||
);
|
||||
};
|
||||
|
||||
$this->gitUtil->runCommand($commandCallable, $url, $path);
|
||||
if ($newRef = $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) {
|
||||
if ($target->getDistReference() === $target->getSourceReference()) {
|
||||
$target->setDistReference($newRef);
|
||||
}
|
||||
$target->setSourceReference($newRef);
|
||||
}
|
||||
|
||||
$updateOriginUrl = false;
|
||||
if (
|
||||
0 === $this->process->execute('git remote -v', $output, $path)
|
||||
|
@ -116,23 +170,6 @@ class GitDownloader extends VcsDownloader implements DvcsDownloaderInterface
|
|||
$updateOriginUrl = true;
|
||||
}
|
||||
}
|
||||
|
||||
$ref = $target->getSourceReference();
|
||||
$this->io->writeError(" Checking out ".$this->getShortHash($ref));
|
||||
$command = 'git remote set-url composer %s && git rev-parse --quiet --verify %s || (git fetch composer && git fetch --tags composer)';
|
||||
|
||||
$commandCallable = function ($url) use ($command, $ref) {
|
||||
return sprintf($command, ProcessExecutor::escape($url), ProcessExecutor::escape($ref.'^{commit}'));
|
||||
};
|
||||
|
||||
$this->gitUtil->runCommand($commandCallable, $url, $path);
|
||||
if ($newRef = $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate())) {
|
||||
if ($target->getDistReference() === $target->getSourceReference()) {
|
||||
$target->setDistReference($newRef);
|
||||
}
|
||||
$target->setSourceReference($newRef);
|
||||
}
|
||||
|
||||
if ($updateOriginUrl) {
|
||||
$this->updateOriginUrl($path, $target->getSourceUrl());
|
||||
}
|
||||
|
|
|
@ -24,7 +24,15 @@ class HgDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doInstall(PackageInterface $package, $path, $url)
|
||||
protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function doInstall(PackageInterface $package, $path, $url)
|
||||
{
|
||||
$hgUtils = new HgUtils($this->io, $this->config, $this->process);
|
||||
|
||||
|
@ -44,7 +52,7 @@ class HgDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
{
|
||||
$hgUtils = new HgUtils($this->io, $this->config, $this->process);
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function download(PackageInterface $package, $path, $output = true)
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
||||
{
|
||||
$url = $package->getDistUrl();
|
||||
$realUrl = realpath($url);
|
||||
|
|
|
@ -24,6 +24,14 @@ class PerforceDownloader extends VcsDownloader
|
|||
/** @var Perforce */
|
||||
protected $perforce;
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -76,7 +84,7 @@ class PerforceDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
{
|
||||
$this->doInstall($target, $path, $url);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,15 @@ class SvnDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doInstall(PackageInterface $package, $path, $url)
|
||||
protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected function doInstall(PackageInterface $package, $path, $url)
|
||||
{
|
||||
SvnUtil::cleanEnv();
|
||||
$ref = $package->getSourceReference();
|
||||
|
@ -48,7 +56,7 @@ class SvnDownloader extends VcsDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
|
||||
{
|
||||
SvnUtil::cleanEnv();
|
||||
$ref = $target->getSourceReference();
|
||||
|
|
|
@ -54,9 +54,57 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function download(PackageInterface $package, $path)
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null)
|
||||
{
|
||||
// noop for now, ideally we would do a git fetch already here, or make sure the cached git repo is synced, etc.
|
||||
if (!$package->getSourceReference()) {
|
||||
throw new \InvalidArgumentException('Package '.$package->getPrettyName().' is missing reference information');
|
||||
}
|
||||
|
||||
$urls = $this->prepareUrls($package->getSourceUrls());
|
||||
|
||||
while ($url = array_shift($urls)) {
|
||||
try {
|
||||
return $this->doDownload($package, $path, $url, $prevPackage);
|
||||
} catch (\Exception $e) {
|
||||
// rethrow phpunit exceptions to avoid hard to debug bug failures
|
||||
if ($e instanceof \PHPUnit_Framework_Exception) {
|
||||
throw $e;
|
||||
}
|
||||
if ($this->io->isDebug()) {
|
||||
$this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
|
||||
} elseif (count($urls)) {
|
||||
$this->io->writeError(' Failed, trying the next URL');
|
||||
}
|
||||
if (!count($urls)) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
|
||||
{
|
||||
if ($type === 'update') {
|
||||
$this->cleanChanges($prevPackage, $path, true);
|
||||
} elseif ($type === 'install') {
|
||||
$this->filesystem->emptyDirectory($path);
|
||||
} elseif ($type === 'uninstall') {
|
||||
$this->cleanChanges($package, $path, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, $path, PackageInterface $prevPackage = null)
|
||||
{
|
||||
if ($type === 'update') {
|
||||
// TODO keep track of whether prepare was called for this package
|
||||
$this->reapplyChanges($path);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,32 +117,10 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
}
|
||||
|
||||
$this->io->writeError(" - Installing <info>" . $package->getName() . "</info> (<comment>" . $package->getFullPrettyVersion() . "</comment>): ", false);
|
||||
$this->filesystem->emptyDirectory($path);
|
||||
|
||||
$urls = $package->getSourceUrls();
|
||||
$urls = $this->prepareUrls($package->getSourceUrls());
|
||||
while ($url = array_shift($urls)) {
|
||||
try {
|
||||
if (Filesystem::isLocalPath($url)) {
|
||||
// realpath() below will not understand
|
||||
// url that starts with "file://"
|
||||
$needle = 'file://';
|
||||
$isFileProtocol = false;
|
||||
if (0 === strpos($url, $needle)) {
|
||||
$url = substr($url, strlen($needle));
|
||||
$isFileProtocol = true;
|
||||
}
|
||||
|
||||
// realpath() below will not understand %20 spaces etc.
|
||||
if (false !== strpos($url, '%')) {
|
||||
$url = rawurldecode($url);
|
||||
}
|
||||
|
||||
$url = realpath($url);
|
||||
|
||||
if ($isFileProtocol) {
|
||||
$url = $needle . $url;
|
||||
}
|
||||
}
|
||||
$this->doInstall($package, $path, $url);
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
|
@ -141,15 +167,11 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
$actionName = VersionParser::isUpgrade($initial->getVersion(), $target->getVersion()) ? 'Updating' : 'Downgrading';
|
||||
$this->io->writeError(" - " . $actionName . " <info>" . $name . "</info> (<comment>" . $from . "</comment> => <comment>" . $to . "</comment>): ", false);
|
||||
|
||||
$this->cleanChanges($initial, $path, true);
|
||||
$urls = $target->getSourceUrls();
|
||||
$urls = $this->prepareUrls($target->getSourceUrls());
|
||||
|
||||
$exception = null;
|
||||
while ($url = array_shift($urls)) {
|
||||
try {
|
||||
if (Filesystem::isLocalPath($url)) {
|
||||
$url = realpath($url);
|
||||
}
|
||||
$this->doUpdate($initial, $target, $path, $url);
|
||||
|
||||
$exception = null;
|
||||
|
@ -167,8 +189,6 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
}
|
||||
}
|
||||
|
||||
$this->reapplyChanges($path);
|
||||
|
||||
// print the commit logs if in verbose mode and VCS metadata is present
|
||||
// because in case of missing metadata code would trigger another exception
|
||||
if (!$exception && $this->io->isVerbose() && $this->hasMetadataRepository($path)) {
|
||||
|
@ -204,7 +224,6 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
public function remove(PackageInterface $package, $path)
|
||||
{
|
||||
$this->io->writeError(" - Removing <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
|
||||
$this->cleanChanges($package, $path, false);
|
||||
if (!$this->filesystem->removeDirectory($path)) {
|
||||
throw new \RuntimeException('Could not completely delete '.$path.', aborting.');
|
||||
}
|
||||
|
@ -243,7 +262,7 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
}
|
||||
|
||||
/**
|
||||
* Guarantee that no changes have been made to the local copy
|
||||
* Reapply previously stashes changes if applicable, only called after an update (regardless if successful or not)
|
||||
*
|
||||
* @param string $path
|
||||
* @throws \RuntimeException in case the operation must be aborted or the patch does not apply cleanly
|
||||
|
@ -252,12 +271,26 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads data needed to run an install/update later
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $path download path
|
||||
* @param string $url package url
|
||||
* @param PackageInterface|null $prevPackage previous package (in case of an update)
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
abstract protected function doDownload(PackageInterface $package, $path, $url, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Downloads specific package into specific folder.
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param string $path download path
|
||||
* @param string $url package url
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
abstract protected function doInstall(PackageInterface $package, $path, $url);
|
||||
|
||||
|
@ -268,6 +301,8 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
* @param PackageInterface $target updated package
|
||||
* @param string $path download path
|
||||
* @param string $url package url
|
||||
*
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url);
|
||||
|
||||
|
@ -289,4 +324,33 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
|
|||
* @return bool
|
||||
*/
|
||||
abstract protected function hasMetadataRepository($path);
|
||||
|
||||
private function prepareUrls(array $urls)
|
||||
{
|
||||
foreach ($urls as $index => $url) {
|
||||
if (Filesystem::isLocalPath($url)) {
|
||||
// realpath() below will not understand
|
||||
// url that starts with "file://"
|
||||
$fileProtocol = 'file://';
|
||||
$isFileProtocol = false;
|
||||
if (0 === strpos($url, $fileProtocol)) {
|
||||
$url = substr($url, strlen($fileProtocol));
|
||||
$isFileProtocol = true;
|
||||
}
|
||||
|
||||
// realpath() below will not understand %20 spaces etc.
|
||||
if (false !== strpos($url, '%')) {
|
||||
$url = rawurldecode($url);
|
||||
}
|
||||
|
||||
$urls[$index] = realpath($url);
|
||||
|
||||
if ($isFileProtocol) {
|
||||
$urls[$index] = $fileProtocol . $urls[$index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class ZipDownloader extends ArchiveDownloader
|
|||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function download(PackageInterface $package, $path, $output = true)
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
||||
{
|
||||
if (null === self::$hasSystemUnzip) {
|
||||
$finder = new ExecutableFinder;
|
||||
|
@ -76,7 +76,7 @@ class ZipDownloader extends ArchiveDownloader
|
|||
}
|
||||
}
|
||||
|
||||
return parent::download($package, $path, $output);
|
||||
return parent::download($package, $path, $prevPackage, $output);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -177,11 +177,52 @@ class InstallationManager
|
|||
$promise = $installer->download($target, $operation->getInitialPackage());
|
||||
}
|
||||
|
||||
if (isset($promise)) {
|
||||
if (!empty($promise)) {
|
||||
$this->loop->wait(array($promise));
|
||||
}
|
||||
|
||||
$this->$method($repo, $operation);
|
||||
$e = null;
|
||||
try {
|
||||
if ($method === 'install' || $method === 'uninstall') {
|
||||
$package = $operation->getPackage();
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$promise = $installer->prepare($method, $package);
|
||||
} elseif ($method === 'update') {
|
||||
$target = $operation->getTargetPackage();
|
||||
$targetType = $target->getType();
|
||||
$installer = $this->getInstaller($targetType);
|
||||
$promise = $installer->prepare('update', $target, $operation->getInitialPackage());
|
||||
}
|
||||
|
||||
if (!empty($promise)) {
|
||||
$this->loop->wait(array($promise));
|
||||
}
|
||||
|
||||
$promise = $this->$method($repo, $operation);
|
||||
if (!empty($promise)) {
|
||||
$this->loop->wait(array($promise));
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
}
|
||||
|
||||
if ($method === 'install' || $method === 'uninstall') {
|
||||
$package = $operation->getPackage();
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$promise = $installer->cleanup($method, $package);
|
||||
} elseif ($method === 'update') {
|
||||
$target = $operation->getTargetPackage();
|
||||
$targetType = $target->getType();
|
||||
$installer = $this->getInstaller($targetType);
|
||||
$promise = $installer->cleanup('update', $target, $operation->getInitialPackage());
|
||||
}
|
||||
|
||||
if (!empty($promise)) {
|
||||
$this->loop->wait(array($promise));
|
||||
}
|
||||
|
||||
if ($e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -194,8 +235,10 @@ class InstallationManager
|
|||
{
|
||||
$package = $operation->getPackage();
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$installer->install($repo, $package);
|
||||
$promise = $installer->install($repo, $package);
|
||||
$this->markForNotification($package);
|
||||
|
||||
return $promise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -214,13 +257,15 @@ class InstallationManager
|
|||
|
||||
if ($initialType === $targetType) {
|
||||
$installer = $this->getInstaller($initialType);
|
||||
$installer->update($repo, $initial, $target);
|
||||
$promise = $installer->update($repo, $initial, $target);
|
||||
$this->markForNotification($target);
|
||||
} else {
|
||||
$this->getInstaller($initialType)->uninstall($repo, $initial);
|
||||
$installer = $this->getInstaller($targetType);
|
||||
$installer->install($repo, $target);
|
||||
$promise = $installer->install($repo, $target);
|
||||
}
|
||||
|
||||
return $promise;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -233,7 +278,8 @@ class InstallationManager
|
|||
{
|
||||
$package = $operation->getPackage();
|
||||
$installer = $this->getInstaller($package->getType());
|
||||
$installer->uninstall($repo, $package);
|
||||
|
||||
return $installer->uninstall($repo, $package);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -46,26 +46,43 @@ interface InstallerInterface
|
|||
/**
|
||||
* Downloads the files needed to later install the given package.
|
||||
*
|
||||
* @param PackageInterface $package package instance
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @param PackageInterface $package package instance
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function download(PackageInterface $package, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Do anything that needs to be done between all downloads have been completed and the actual operation is executed
|
||||
*
|
||||
* All packages get first downloaded, then all together prepared, then all together installed/updated/uninstalled. Therefore
|
||||
* for error recovery it is important to avoid failing during install/update/uninstall as much as possible, and risky things or
|
||||
* user prompts should happen in the prepare step rather. In case of failure, cleanup() will be called so that changes can
|
||||
* be undone as much as possible.
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Installs specific package.
|
||||
*
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $package package instance
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $package package instance
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function install(InstalledRepositoryInterface $repo, PackageInterface $package);
|
||||
|
||||
/**
|
||||
* Updates specific package.
|
||||
*
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $initial already installed package version
|
||||
* @param PackageInterface $target updated version
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $initial already installed package version
|
||||
* @param PackageInterface $target updated version
|
||||
* @return PromiseInterface|null
|
||||
*
|
||||
* @throws InvalidArgumentException if $initial package is not installed
|
||||
*/
|
||||
|
@ -74,11 +91,26 @@ interface InstallerInterface
|
|||
/**
|
||||
* Uninstalls specific package.
|
||||
*
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $package package instance
|
||||
* @param InstalledRepositoryInterface $repo repository in which to check
|
||||
* @param PackageInterface $package package instance
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function uninstall(InstalledRepositoryInterface $repo, PackageInterface $package);
|
||||
|
||||
/**
|
||||
* Do anything to cleanup changes applied in the prepare or install/update/uninstall steps
|
||||
*
|
||||
* Note that cleanup will be called for all packages regardless if they failed an operation or not, to give
|
||||
* all installers a change to cleanup things they did previously, so you need to keep track of changes
|
||||
* applied in the installer/downloader themselves.
|
||||
*
|
||||
* @param string $type one of install/update/uninstall
|
||||
* @param PackageInterface $package package instance
|
||||
* @param PackageInterface $prevPackage previous package instance in case of an update
|
||||
* @return PromiseInterface|null
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null);
|
||||
|
||||
/**
|
||||
* Returns the installation path of a package
|
||||
*
|
||||
|
|
|
@ -85,6 +85,9 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
|
|||
return (Platform::isWindows() && $this->filesystem->isJunction($installPath)) || is_link($installPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function download(PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$this->initializeVendorDir();
|
||||
|
@ -93,6 +96,28 @@ class LibraryInstaller implements InstallerInterface, BinaryPresenceInterface
|
|||
return $this->downloadManager->download($package, $downloadPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$this->initializeVendorDir();
|
||||
$downloadPath = $this->getInstallPath($package);
|
||||
|
||||
return $this->downloadManager->prepare($type, $package, $downloadPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$this->initializeVendorDir();
|
||||
$downloadPath = $this->getInstallPath($package);
|
||||
|
||||
return $this->downloadManager->cleanup($type, $package, $downloadPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -55,6 +55,22 @@ class MetapackageInstaller implements InstallerInterface
|
|||
// noop
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
// noop
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -47,6 +47,20 @@ class NoopInstaller implements InstallerInterface
|
|||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -71,6 +71,22 @@ class ProjectInstaller implements InstallerInterface
|
|||
return $this->downloadManager->download($package, $installPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function prepare($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$this->downloadManager->prepare($type, $package, $this->installPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
public function cleanup($type, PackageInterface $package, PackageInterface $prevPackage = null)
|
||||
{
|
||||
$this->downloadManager->cleanup($type, $package, $this->installPath, $prevPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
|
|
@ -224,6 +224,10 @@ class Git
|
|||
|
||||
public function syncMirror($url, $dir)
|
||||
{
|
||||
if (getenv('COMPOSER_DISABLE_NETWORK')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// update the repo if it is a valid git repository
|
||||
if (is_dir($dir) && 0 === $this->process->execute('git rev-parse --git-dir', $output, $dir) && trim($output) === '.') {
|
||||
try {
|
||||
|
@ -260,9 +264,7 @@ class Git
|
|||
}
|
||||
}
|
||||
|
||||
$this->syncMirror($url, $dir);
|
||||
|
||||
return false;
|
||||
return $this->syncMirror($url, $dir);
|
||||
}
|
||||
|
||||
private function isAuthenticationFailure($url, &$match)
|
||||
|
|
|
@ -48,7 +48,7 @@ class FossilDownloaderTest extends TestCase
|
|||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
*/
|
||||
public function testDownloadForPackageWithoutSourceReference()
|
||||
public function testInstallForPackageWithoutSourceReference()
|
||||
{
|
||||
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
$packageMock->expects($this->once())
|
||||
|
@ -59,7 +59,7 @@ class FossilDownloaderTest extends TestCase
|
|||
$downloader->install($packageMock, '/path');
|
||||
}
|
||||
|
||||
public function testDownload()
|
||||
public function testInstall()
|
||||
{
|
||||
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
$packageMock->expects($this->any())
|
||||
|
@ -104,7 +104,9 @@ class FossilDownloaderTest extends TestCase
|
|||
->will($this->returnValue(null));
|
||||
|
||||
$downloader = $this->getDownloaderMock();
|
||||
$downloader->prepare('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
$downloader->update($initialPackageMock, $sourcePackageMock, '/path');
|
||||
$downloader->cleanup('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
|
@ -140,7 +142,9 @@ class FossilDownloaderTest extends TestCase
|
|||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
|
|
|
@ -17,6 +17,7 @@ use Composer\Config;
|
|||
use Composer\Test\TestCase;
|
||||
use Composer\Util\Filesystem;
|
||||
use Composer\Util\Platform;
|
||||
use Prophecy\Argument;
|
||||
|
||||
class GitDownloaderTest extends TestCase
|
||||
{
|
||||
|
@ -79,7 +80,10 @@ class GitDownloaderTest extends TestCase
|
|||
->will($this->returnValue(null));
|
||||
|
||||
$downloader = $this->getDownloaderMock();
|
||||
$downloader->download($packageMock, '/path');
|
||||
$downloader->prepare('install', $packageMock, '/path');
|
||||
$downloader->install($packageMock, '/path');
|
||||
$downloader->cleanup('install', $packageMock, '/path');
|
||||
}
|
||||
|
||||
public function testDownload()
|
||||
|
@ -130,7 +134,10 @@ class GitDownloaderTest extends TestCase
|
|||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
$downloader->prepare('install', $packageMock, 'composerPath');
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
$downloader->cleanup('install', $packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
public function testDownloadWithCache()
|
||||
|
@ -195,7 +202,10 @@ class GitDownloaderTest extends TestCase
|
|||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, $config, $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
$downloader->prepare('install', $packageMock, 'composerPath');
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
$downloader->cleanup('install', $packageMock, 'composerPath');
|
||||
@rmdir($cachePath);
|
||||
}
|
||||
|
||||
|
@ -265,7 +275,10 @@ class GitDownloaderTest extends TestCase
|
|||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
$downloader->prepare('install', $packageMock, 'composerPath');
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
$downloader->cleanup('install', $packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
public function pushUrlProvider()
|
||||
|
@ -329,12 +342,12 @@ class GitDownloaderTest extends TestCase
|
|||
$config->merge(array('config' => array('github-protocols' => $protocols)));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, $config, $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
$downloader->prepare('install', $packageMock, 'composerPath');
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
$downloader->cleanup('install', $packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testDownloadThrowsRuntimeExceptionIfGitCommandFails()
|
||||
{
|
||||
$expectedGitCommand = $this->winCompat("git clone --no-checkout 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer");
|
||||
|
@ -359,8 +372,20 @@ class GitDownloaderTest extends TestCase
|
|||
->with($this->equalTo($expectedGitCommand))
|
||||
->will($this->returnValue(1));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor);
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
// not using PHPUnit's expected exception because Prophecy exceptions extend from RuntimeException too so it is not safe
|
||||
try {
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor);
|
||||
$downloader->download($packageMock, 'composerPath');
|
||||
$downloader->prepare('install', $packageMock, 'composerPath');
|
||||
$downloader->install($packageMock, 'composerPath');
|
||||
$downloader->cleanup('install', $packageMock, 'composerPath');
|
||||
$this->fail('This test should throw');
|
||||
} catch (\RuntimeException $e) {
|
||||
if ('RuntimeException' !== get_class($e)) {
|
||||
throw $e;
|
||||
}
|
||||
$this->assertEquals('RuntimeException', get_class($e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -375,7 +400,10 @@ class GitDownloaderTest extends TestCase
|
|||
->will($this->returnValue(null));
|
||||
|
||||
$downloader = $this->getDownloaderMock();
|
||||
$downloader->download($sourcePackageMock, '/path', $initialPackageMock);
|
||||
$downloader->prepare('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
$downloader->update($initialPackageMock, $sourcePackageMock, '/path');
|
||||
$downloader->cleanup('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
|
@ -392,39 +420,22 @@ class GitDownloaderTest extends TestCase
|
|||
$packageMock->expects($this->any())
|
||||
->method('getVersion')
|
||||
->will($this->returnValue('1.0.0.0'));
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git show-ref --head -d")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(2))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(4))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat($expectedGitUpdateCommand)), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(5))
|
||||
->method('execute')
|
||||
->with($this->equalTo('git branch -r'))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(6))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --")), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$process = $this->prophesize('Composer\Util\ProcessExecutor');
|
||||
$process->execute($this->winCompat('git --version'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git show-ref --head -d'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git status --porcelain --untracked-files=no'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git remote -v'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git branch -r'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($expectedGitUpdateCommand, null, $this->winCompat($this->workingDir))->willReturn(0)->shouldBeCalled();
|
||||
$process->execute($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --"), null, $this->winCompat($this->workingDir))->willReturn(0)->shouldBeCalled();
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $process->reveal());
|
||||
$downloader->download($packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
}
|
||||
|
||||
public function testUpdateWithNewRepoUrl()
|
||||
|
@ -444,27 +455,20 @@ class GitDownloaderTest extends TestCase
|
|||
$packageMock->expects($this->any())
|
||||
->method('getVersion')
|
||||
->will($this->returnValue('1.0.0.0'));
|
||||
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git show-ref --head -d")))
|
||||
->with($this->equalTo($this->winCompat("git --version")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
|
||||
->with($this->equalTo($this->winCompat("git show-ref --head -d")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(2))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnCallback(function ($cmd, &$output, $cwd) {
|
||||
$output = 'origin https://github.com/old/url (fetch)
|
||||
origin https://github.com/old/url (push)
|
||||
composer https://github.com/old/url (fetch)
|
||||
composer https://github.com/old/url (push)
|
||||
';
|
||||
|
||||
return 0;
|
||||
}));
|
||||
->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
|
@ -482,26 +486,41 @@ composer https://github.com/old/url (push)
|
|||
->with($this->equalTo($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --")), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(7))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnCallback(function ($cmd, &$output, $cwd) {
|
||||
$output = 'origin https://github.com/old/url (fetch)
|
||||
origin https://github.com/old/url (push)
|
||||
composer https://github.com/old/url (fetch)
|
||||
composer https://github.com/old/url (push)
|
||||
';
|
||||
|
||||
return 0;
|
||||
}));
|
||||
$processExecutor->expects($this->at(8))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote set-url origin 'https://github.com/composer/composer'")), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(8))
|
||||
$processExecutor->expects($this->at(9))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote set-url --push origin 'git@github.com:composer/composer.git'")), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
|
||||
$downloader->download($packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
}
|
||||
|
||||
/**
|
||||
* @group failing
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testUpdateThrowsRuntimeExceptionIfGitCommandFails()
|
||||
{
|
||||
$expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)");
|
||||
$expectedGitUpdateCommand2 = $this->winCompat("git remote set-url composer 'git@github.com:composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)");
|
||||
|
||||
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
$packageMock->expects($this->any())
|
||||
|
@ -513,36 +532,38 @@ composer https://github.com/old/url (push)
|
|||
$packageMock->expects($this->any())
|
||||
->method('getVersion')
|
||||
->will($this->returnValue('1.0.0.0'));
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git show-ref --head -d")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(2))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(4))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedGitUpdateCommand))
|
||||
->will($this->returnValue(1));
|
||||
|
||||
$process = $this->prophesize('Composer\Util\ProcessExecutor');
|
||||
$process->execute($this->winCompat('git --version'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git show-ref --head -d'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git status --porcelain --untracked-files=no'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git remote -v'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git branch -r'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($expectedGitUpdateCommand, null, $this->winCompat($this->workingDir))->willReturn(1)->shouldBeCalled();
|
||||
$process->execute($expectedGitUpdateCommand2, null, $this->winCompat($this->workingDir))->willReturn(1)->shouldBeCalled();
|
||||
$process->getErrorOutput()->willReturn('');
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
|
||||
// not using PHPUnit's expected exception because Prophecy exceptions extend from RuntimeException too so it is not safe
|
||||
try {
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $process->reveal());
|
||||
$downloader->download($packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$this->fail('This test should throw');
|
||||
} catch (\RuntimeException $e) {
|
||||
if ('RuntimeException' !== get_class($e)) {
|
||||
throw $e;
|
||||
}
|
||||
$this->assertEquals('RuntimeException', get_class($e));
|
||||
}
|
||||
}
|
||||
|
||||
public function testUpdateDoesntThrowsRuntimeExceptionIfGitCommandFailsAtFirstButIsAbleToRecover()
|
||||
{
|
||||
$expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)");
|
||||
$expectedFirstGitUpdateCommand = $this->winCompat("git remote set-url composer '".(Platform::isWindows() ? 'C:\\' : '/')."' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)");
|
||||
$expectedSecondGitUpdateCommand = $this->winCompat("git remote set-url composer 'https://github.com/composer/composer' && git rev-parse --quiet --verify 'ref^{commit}' || (git fetch composer && git fetch --tags composer)");
|
||||
|
||||
$packageMock = $this->getMockBuilder('Composer\Package\PackageInterface')->getMock();
|
||||
|
@ -554,52 +575,24 @@ composer https://github.com/old/url (push)
|
|||
->will($this->returnValue('1.0.0.0'));
|
||||
$packageMock->expects($this->any())
|
||||
->method('getSourceUrls')
|
||||
->will($this->returnValue(array('/foo/bar', 'https://github.com/composer/composer')));
|
||||
$processExecutor = $this->getMockBuilder('Composer\Util\ProcessExecutor')->getMock();
|
||||
$processExecutor->expects($this->at(0))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git show-ref --head -d")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(1))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(2))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(3))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(4))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedFirstGitUpdateCommand))
|
||||
->will($this->returnValue(1));
|
||||
$processExecutor->expects($this->at(6))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git --version")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(7))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(8))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git remote -v")))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(9))
|
||||
->method('execute')
|
||||
->with($this->equalTo($expectedSecondGitUpdateCommand))
|
||||
->will($this->returnValue(0));
|
||||
$processExecutor->expects($this->at(11))
|
||||
->method('execute')
|
||||
->with($this->equalTo($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --")), $this->equalTo(null), $this->equalTo($this->winCompat($this->workingDir)))
|
||||
->will($this->returnValue(0));
|
||||
->will($this->returnValue(array(Platform::isWindows() ? 'C:\\' : '/', 'https://github.com/composer/composer')));
|
||||
|
||||
$process = $this->prophesize('Composer\Util\ProcessExecutor');
|
||||
$process->execute($this->winCompat('git --version'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git show-ref --head -d'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git status --porcelain --untracked-files=no'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git remote -v'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($this->winCompat('git branch -r'), Argument::cetera())->willReturn(0);
|
||||
$process->execute($expectedFirstGitUpdateCommand, Argument::cetera())->willReturn(1)->shouldBeCalled();
|
||||
$process->execute($expectedSecondGitUpdateCommand, Argument::cetera())->willReturn(0)->shouldBeCalled();
|
||||
$process->execute($this->winCompat("git checkout 'ref' -- && git reset --hard 'ref' --"), null, $this->winCompat($this->workingDir))->willReturn(0)->shouldBeCalled();
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
|
||||
$downloader = $this->getDownloaderMock(null, new Config(), $process->reveal());
|
||||
$downloader->download($packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
}
|
||||
|
||||
public function testDowngradeShowsAppropriateMessage()
|
||||
|
@ -644,7 +637,10 @@ composer https://github.com/old/url (push)
|
|||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock($ioMock, null, $processExecutor);
|
||||
$downloader->download($newPackage, $this->workingDir, $oldPackage);
|
||||
$downloader->prepare('update', $newPackage, $this->workingDir, $oldPackage);
|
||||
$downloader->update($oldPackage, $newPackage, $this->workingDir);
|
||||
$downloader->cleanup('update', $newPackage, $this->workingDir, $oldPackage);
|
||||
}
|
||||
|
||||
public function testNotUsingDowngradingWithReferences()
|
||||
|
@ -679,11 +675,14 @@ composer https://github.com/old/url (push)
|
|||
$ioMock = $this->getMockBuilder('Composer\IO\IOInterface')->getMock();
|
||||
$ioMock->expects($this->at(0))
|
||||
->method('writeError')
|
||||
->with($this->stringContains('updating'));
|
||||
->with($this->stringContains('Updating'));
|
||||
|
||||
$this->fs->ensureDirectoryExists($this->workingDir.'/.git');
|
||||
$downloader = $this->getDownloaderMock($ioMock, null, $processExecutor);
|
||||
$downloader->download($newPackage, $this->workingDir, $oldPackage);
|
||||
$downloader->prepare('update', $newPackage, $this->workingDir, $oldPackage);
|
||||
$downloader->update($oldPackage, $newPackage, $this->workingDir);
|
||||
$downloader->cleanup('update', $newPackage, $this->workingDir, $oldPackage);
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
|
@ -703,7 +702,9 @@ composer https://github.com/old/url (push)
|
|||
->will($this->returnValue(true));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor, $filesystem);
|
||||
$downloader->prepare('uninstall', $packageMock, 'composerPath');
|
||||
$downloader->remove($packageMock, 'composerPath');
|
||||
$downloader->cleanup('uninstall', $packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
public function testGetInstallationSource()
|
||||
|
|
|
@ -98,7 +98,9 @@ class HgDownloaderTest extends TestCase
|
|||
->will($this->returnValue(null));
|
||||
|
||||
$downloader = $this->getDownloaderMock();
|
||||
$downloader->prepare('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
$downloader->update($initialPackageMock, $sourcePackageMock, '/path');
|
||||
$downloader->cleanup('update', $sourcePackageMock, '/path', $initialPackageMock);
|
||||
}
|
||||
|
||||
public function testUpdate()
|
||||
|
@ -129,7 +131,9 @@ class HgDownloaderTest extends TestCase
|
|||
->will($this->returnValue(0));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor);
|
||||
$downloader->prepare('update', $packageMock, $this->workingDir, $packageMock);
|
||||
$downloader->update($packageMock, $packageMock, $this->workingDir);
|
||||
$downloader->cleanup('update', $packageMock, $this->workingDir, $packageMock);
|
||||
}
|
||||
|
||||
public function testRemove()
|
||||
|
@ -148,7 +152,9 @@ class HgDownloaderTest extends TestCase
|
|||
->will($this->returnValue(true));
|
||||
|
||||
$downloader = $this->getDownloaderMock(null, null, $processExecutor, $filesystem);
|
||||
$downloader->prepare('uninstall', $packageMock, 'composerPath');
|
||||
$downloader->remove($packageMock, 'composerPath');
|
||||
$downloader->cleanup('uninstall', $packageMock, 'composerPath');
|
||||
}
|
||||
|
||||
public function testGetInstallationSource()
|
||||
|
|
|
@ -338,7 +338,7 @@ class ZipDownloaderTest extends TestCase
|
|||
|
||||
class MockedZipDownloader extends ZipDownloader
|
||||
{
|
||||
public function download(PackageInterface $package, $path, $output = true)
|
||||
public function download(PackageInterface $package, $path, PackageInterface $prevPackage = null, $output = true)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue