|
|
@ -87,30 +87,9 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Get the transport options with default values
|
|
|
|
// Get the transport options with default values
|
|
|
|
$transportOptions = $package->getTransportOptions() + array('symlink' => null, 'relative' => true);
|
|
|
|
$transportOptions = $package->getTransportOptions() + array('relative' => true);
|
|
|
|
|
|
|
|
|
|
|
|
// When symlink transport option is null, both symlink and mirror are allowed
|
|
|
|
list($currentStrategy, $allowedStrategies) = $this->computeAllowedStrategies($transportOptions);
|
|
|
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$mirrorPathRepos = getenv('COMPOSER_MIRROR_PATH_REPOS');
|
|
|
|
|
|
|
|
if ($mirrorPathRepos) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (true === $transportOptions['symlink']) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_SYMLINK);
|
|
|
|
|
|
|
|
} elseif (false === $transportOptions['symlink']) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check we can use junctions safely if we are on Windows
|
|
|
|
|
|
|
|
if (Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !$this->safeJunctions()) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$symfonyFilesystem = new SymfonyFilesystem();
|
|
|
|
$symfonyFilesystem = new SymfonyFilesystem();
|
|
|
|
$this->filesystem->removeDirectory($path);
|
|
|
|
$this->filesystem->removeDirectory($path);
|
|
|
@ -120,11 +99,13 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
$isFallback = false;
|
|
|
|
$isFallback = false;
|
|
|
|
if (self::STRATEGY_SYMLINK == $currentStrategy) {
|
|
|
|
if (self::STRATEGY_SYMLINK === $currentStrategy) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
if (Platform::isWindows()) {
|
|
|
|
if (Platform::isWindows()) {
|
|
|
|
// Implement symlinks as NTFS junctions on Windows
|
|
|
|
// Implement symlinks as NTFS junctions on Windows
|
|
|
|
$this->io->writeError(sprintf('Junctioning from %s', $url), false);
|
|
|
|
if ($output) {
|
|
|
|
|
|
|
|
$this->io->writeError(sprintf('Junctioning from %s', $url), false);
|
|
|
|
|
|
|
|
}
|
|
|
|
$this->filesystem->junction($realUrl, $path);
|
|
|
|
$this->filesystem->junction($realUrl, $path);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
$absolutePath = $path;
|
|
|
|
$absolutePath = $path;
|
|
|
@ -133,7 +114,9 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl);
|
|
|
|
$shortestPath = $this->filesystem->findShortestPath($absolutePath, $realUrl);
|
|
|
|
$path = rtrim($path, "/");
|
|
|
|
$path = rtrim($path, "/");
|
|
|
|
$this->io->writeError(sprintf('Symlinking from %s', $url), false);
|
|
|
|
if ($output) {
|
|
|
|
|
|
|
|
$this->io->writeError(sprintf('Symlinking from %s', $url), false);
|
|
|
|
|
|
|
|
}
|
|
|
|
if ($transportOptions['relative']) {
|
|
|
|
if ($transportOptions['relative']) {
|
|
|
|
$symfonyFilesystem->symlink($shortestPath, $path);
|
|
|
|
$symfonyFilesystem->symlink($shortestPath, $path);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -142,8 +125,10 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException $e) {
|
|
|
|
} catch (IOException $e) {
|
|
|
|
if (in_array(self::STRATEGY_MIRROR, $allowedStrategies)) {
|
|
|
|
if (in_array(self::STRATEGY_MIRROR, $allowedStrategies)) {
|
|
|
|
$this->io->writeError('');
|
|
|
|
if ($output) {
|
|
|
|
$this->io->writeError(' <error>Symlink failed, fallback to use mirroring!</error>');
|
|
|
|
$this->io->writeError('');
|
|
|
|
|
|
|
|
$this->io->writeError(' <error>Symlink failed, fallback to use mirroring!</error>');
|
|
|
|
|
|
|
|
}
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
$isFallback = true;
|
|
|
|
$isFallback = true;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@ -153,10 +138,12 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Fallback if symlink failed or if symlink is not allowed for the package
|
|
|
|
// Fallback if symlink failed or if symlink is not allowed for the package
|
|
|
|
if (self::STRATEGY_MIRROR == $currentStrategy) {
|
|
|
|
if (self::STRATEGY_MIRROR === $currentStrategy) {
|
|
|
|
$realUrl = $this->filesystem->normalizePath($realUrl);
|
|
|
|
$realUrl = $this->filesystem->normalizePath($realUrl);
|
|
|
|
|
|
|
|
|
|
|
|
$this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? ' ' : '', $url), false);
|
|
|
|
if ($output) {
|
|
|
|
|
|
|
|
$this->io->writeError(sprintf('%sMirroring from %s', $isFallback ? ' ' : '', $url), false);
|
|
|
|
|
|
|
|
}
|
|
|
|
$iterator = new ArchivableFilesFinder($realUrl, array());
|
|
|
|
$iterator = new ArchivableFilesFinder($realUrl, array());
|
|
|
|
$symfonyFilesystem->mirror($realUrl, $path, $iterator);
|
|
|
|
$symfonyFilesystem->mirror($realUrl, $path, $iterator);
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -225,7 +212,46 @@ class PathDownloader extends FileDownloader implements VcsCapableDownloaderInter
|
|
|
|
return ': Source already present';
|
|
|
|
return ': Source already present';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return '';
|
|
|
|
list($currentStrategy) = $this->computeAllowedStrategies($package->getTransportOptions());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ($currentStrategy === self::STRATEGY_SYMLINK) {
|
|
|
|
|
|
|
|
if (Platform::isWindows()) {
|
|
|
|
|
|
|
|
return ': Junctioning from '.$package->getDistUrl();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return ': Symlinking from '.$package->getDistUrl();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return ': Mirroring from '.$package->getDistUrl();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function computeAllowedStrategies(array $transportOptions)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// When symlink transport option is null, both symlink and mirror are allowed
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_SYMLINK, self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$mirrorPathRepos = getenv('COMPOSER_MIRROR_PATH_REPOS');
|
|
|
|
|
|
|
|
if ($mirrorPathRepos) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$symlinkOption = isset($transportOptions['symlink']) ? $transportOptions['symlink'] : null;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (true === $symlinkOption) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_SYMLINK;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_SYMLINK);
|
|
|
|
|
|
|
|
} elseif (false === $symlinkOption) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check we can use junctions safely if we are on Windows
|
|
|
|
|
|
|
|
if (Platform::isWindows() && self::STRATEGY_SYMLINK === $currentStrategy && !$this->safeJunctions()) {
|
|
|
|
|
|
|
|
$currentStrategy = self::STRATEGY_MIRROR;
|
|
|
|
|
|
|
|
$allowedStrategies = array(self::STRATEGY_MIRROR);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return array($currentStrategy, $allowedStrategies);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|