From fb3a43b2f0cdb657ebe0b9ebdd5be56df0f484c7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Thu, 1 Nov 2012 18:02:08 +0100 Subject: [PATCH] Add local cache to dist downloads --- src/Composer/Cache.php | 38 +++++++++++++++++++--- src/Composer/Downloader/FileDownloader.php | 12 ++++++- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/Composer/Cache.php b/src/Composer/Cache.php index 9e14ceaff..7ae277089 100644 --- a/src/Composer/Cache.php +++ b/src/Composer/Cache.php @@ -13,6 +13,7 @@ namespace Composer; use Composer\IO\IOInterface; +use Composer\Util\Filesystem; /** * Reads/writes to a filesystem cache @@ -24,11 +25,15 @@ class Cache private $io; private $root; private $enabled = true; + private $whitelist; + private $filesystem; - public function __construct(IOInterface $io, $cacheDir) + public function __construct(IOInterface $io, $cacheDir, $whitelist = 'a-z0-9.', Filesystem $filesystem = null) { $this->io = $io; $this->root = rtrim($cacheDir, '/\\') . '/'; + $this->whitelist = $whitelist; + $this->filesystem = $filesystem ?: new Filesystem(); if (!is_dir($this->root)) { if (!@mkdir($this->root, 0777, true)) { @@ -44,7 +49,7 @@ class Cache public function read($file) { - $file = preg_replace('{[^a-z0-9.]}i', '-', $file); + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->enabled && file_exists($this->root . $file)) { return file_get_contents($this->root . $file); } @@ -53,14 +58,37 @@ class Cache public function write($file, $contents) { if ($this->enabled) { - $file = preg_replace('{[^a-z0-9.]}i', '-', $file); + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); file_put_contents($this->root . $file, $contents); } } + public function copyFrom($file, $source) + { + if ($this->enabled) { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + $this->filesystem->ensureDirectoryExists(dirname($this->root . $file)); + copy($source, $this->root . $file); + } + } + + public function copyTo($file, $target) + { + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); + if ($this->enabled && file_exists($this->root . $file)) { + touch($this->root . $file); + return copy($this->root . $file, $target); + } + } + + public function gc($expire) + { + // TODO + } + public function sha1($file) { - $file = preg_replace('{[^a-z0-9.]}i', '-', $file); + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->enabled && file_exists($this->root . $file)) { return sha1_file($this->root . $file); } @@ -68,7 +96,7 @@ class Cache public function sha256($file) { - $file = preg_replace('{[^a-z0-9.]}i', '-', $file); + $file = preg_replace('{[^'.$this->whitelist.']}i', '-', $file); if ($this->enabled && file_exists($this->root . $file)) { return hash_file('sha256', $this->root . $file); } diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index b567e5a5c..ab202ab11 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -13,6 +13,7 @@ namespace Composer\Downloader; use Composer\Config; +use Composer\Cache; use Composer\IO\IOInterface; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; @@ -33,6 +34,7 @@ class FileDownloader implements DownloaderInterface protected $config; protected $rfs; protected $filesystem; + protected $cache; /** * Constructor. @@ -48,6 +50,11 @@ class FileDownloader implements DownloaderInterface $this->config = $config; $this->rfs = $rfs ?: new RemoteFilesystem($io); $this->filesystem = $filesystem ?: new Filesystem(); + $this->cache = new Cache($this->io, $config->get('home').'/cache.files/', 'a-z0-9_./'); + + if (!rand(0, 50)) { + $this->cache->gc($config->get('cache-ttl') ?: 86400 * 30); + } } /** @@ -78,7 +85,10 @@ class FileDownloader implements DownloaderInterface try { try { - $this->rfs->copy(parse_url($processUrl, PHP_URL_HOST), $processUrl, $fileName); + if (!$this->cache->copyTo($package->getName().'/'.$package->getVersion().'-'.$package->getDistReference().'.'.$package->getDistType(), $fileName)) { + $this->rfs->copy(parse_url($processUrl, PHP_URL_HOST), $processUrl, $fileName); + $this->cache->copyFrom($package->getName().'/'.$package->getVersion().'-'.$package->getDistReference().'.'.$package->getDistType(), $fileName); + } } catch (TransportException $e) { if (404 === $e->getCode() && 'github.com' === parse_url($processUrl, PHP_URL_HOST)) { $message = "\n".'Could not fetch '.$processUrl.', enter your GitHub credentials to access private repos';