|
@@ -25,6 +25,9 @@ use Symfony\Component\Filesystem\Filesystem;
|
|
|
*/
|
|
|
class PathDownloader extends FileDownloader
|
|
|
{
|
|
|
+ const STRATEGY_SYMLINK = 10;
|
|
|
+ const STRATEGY_MIRROR = 20;
|
|
|
+
|
|
|
/**
|
|
|
* {@inheritdoc}
|
|
|
*/
|
|
@@ -45,6 +48,21 @@ class PathDownloader extends FileDownloader
|
|
|
));
|
|
|
}
|
|
|
|
|
|
+ // Get the transport options with default values
|
|
|
+ $transportOptions = $package->getTransportOptions() + array('symlink'=>null);
|
|
|
+
|
|
|
+ // When symlink transport option is null, both symlink and mirror are allowed
|
|
|
+ $currentStrategy = self::STRATEGY_SYMLINK;
|
|
|
+ $allowedStrategies = array(self::STRATEGY_SYMLINK, 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);
|
|
|
+ }
|
|
|
+
|
|
|
$fileSystem = new Filesystem();
|
|
|
$this->filesystem->removeDirectory($path);
|
|
|
|
|
@@ -54,17 +72,29 @@ class PathDownloader extends FileDownloader
|
|
|
$package->getFullPrettyVersion()
|
|
|
));
|
|
|
|
|
|
- try {
|
|
|
- if (Platform::isWindows()) {
|
|
|
- // Implement symlinks as NTFS junctions on Windows
|
|
|
- $this->filesystem->junction($realUrl, $path);
|
|
|
- $this->io->writeError(sprintf(' Junctioned from %s', $url));
|
|
|
- } else {
|
|
|
- $shortestPath = $this->filesystem->findShortestPath($path, $realUrl);
|
|
|
- $fileSystem->symlink($shortestPath, $path);
|
|
|
- $this->io->writeError(sprintf(' Symlinked from %s', $url));
|
|
|
+ if (self::STRATEGY_SYMLINK == $currentStrategy) {
|
|
|
+ try {
|
|
|
+ if (Platform::isWindows()) {
|
|
|
+ // Implement symlinks as NTFS junctions on Windows
|
|
|
+ $this->filesystem->junction($realUrl, $path);
|
|
|
+ $this->io->writeError(sprintf(' Junctioned from %s', $url));
|
|
|
+ } else {
|
|
|
+ $shortestPath = $this->filesystem->findShortestPath($path, $realUrl);
|
|
|
+ $fileSystem->symlink($shortestPath, $path);
|
|
|
+ $this->io->writeError(sprintf(' Symlinked from %s', $url));
|
|
|
+ }
|
|
|
+ } catch (IOException $e) {
|
|
|
+ if (in_array(self::STRATEGY_MIRROR, $allowedStrategies)) {
|
|
|
+ $this->io->writeError(' <error>Symlink failed, fallback to use mirroring!</error>');
|
|
|
+ $currentStrategy = self::STRATEGY_MIRROR;
|
|
|
+ } else {
|
|
|
+ throw new \RuntimeException(sprintf('Symlink from "%s" to "%s" failed!', $realUrl, $path));
|
|
|
+ }
|
|
|
}
|
|
|
- } catch (IOException $e) {
|
|
|
+ }
|
|
|
+
|
|
|
+ // Fallback if symlink failed or if symlink is not allowed for the package
|
|
|
+ if (self::STRATEGY_MIRROR == $currentStrategy) {
|
|
|
$fileSystem->mirror($realUrl, $path);
|
|
|
$this->io->writeError(sprintf(' Mirrored from %s', $url));
|
|
|
}
|