From a6ce43817e48ace5058d79d301866055424019d8 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 22 Jan 2012 21:14:56 +0100 Subject: [PATCH] Overhaul VCS downloaders, added base class and uniformized --- src/Composer/Downloader/FileDownloader.php | 1 - src/Composer/Downloader/GitDownloader.php | 50 +++------- src/Composer/Downloader/HgDownloader.php | 50 +++------- src/Composer/Downloader/SvnDownloader.php | 47 ++-------- src/Composer/Downloader/VcsDownloader.php | 103 +++++++++++++++++++++ 5 files changed, 137 insertions(+), 114 deletions(-) create mode 100644 src/Composer/Downloader/VcsDownloader.php diff --git a/src/Composer/Downloader/FileDownloader.php b/src/Composer/Downloader/FileDownloader.php index f74ef89dd..e3ccc1773 100644 --- a/src/Composer/Downloader/FileDownloader.php +++ b/src/Composer/Downloader/FileDownloader.php @@ -119,7 +119,6 @@ abstract class FileDownloader implements DownloaderInterface $this->io->write(' Unpacking archive'); $this->extract($fileName, $path); - $this->io->write(' Cleaning up'); unlink($fileName); diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 4371f9468..170749674 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -18,63 +18,37 @@ use Composer\Util\ProcessExecutor; /** * @author Jordi Boggiano */ -class GitDownloader implements DownloaderInterface +class GitDownloader extends VcsDownloader { - protected $process; - - public function __construct(ProcessExecutor $process = null) - { - $this->process = $process ?: new ProcessExecutor; - } - /** * {@inheritDoc} */ - public function getInstallationSource() + public function doDownload(PackageInterface $package, $path) { - return 'source'; - } - - /** - * {@inheritDoc} - */ - public function download(PackageInterface $package, $path) - { - if (!$package->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - $url = escapeshellarg($package->getSourceUrl()); $ref = escapeshellarg($package->getSourceReference()); - $this->process->execute(sprintf('git clone %s %s && cd %2$s && git checkout %3$s && git reset --hard %3$s', $url, $path, $ref)); + $path = escapeshellarg($path); + $this->io->write(" Cloning ".$package->getSourceReference()); + $this->process->execute(sprintf('git clone %s %s && cd %2$s && git checkout %3$s && git reset --hard %3$s', $url, $path, $ref), $ignoredOutput); } /** * {@inheritDoc} */ - public function update(PackageInterface $initial, PackageInterface $target, $path) + public function doUpdate(PackageInterface $initial, PackageInterface $target, $path) { - if (!$target->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - - $this->enforceCleanDirectory($path); - $this->process->execute(sprintf('cd %s && git fetch && git checkout %2$s && git reset --hard %2$s', $path, $target->getSourceReference())); + $ref = escapeshellarg($target->getSourceReference()); + $path = escapeshellarg($path); + $this->io->write(" Checking out ".$target->getSourceReference()); + $this->process->execute(sprintf('cd %s && git fetch && git checkout %2$s && git reset --hard %2$s', $path, $ref), $ignoredOutput); } /** * {@inheritDoc} */ - public function remove(PackageInterface $package, $path) + protected function enforceCleanDirectory($path) { - $this->enforceCleanDirectory($path); - $fs = new Util\Filesystem(); - $fs->removeDirectory($path); - } - - private function enforceCleanDirectory($path) - { - $this->process->execute(sprintf('cd %s && git status --porcelain', $path), $output); + $this->process->execute(sprintf('cd %s && git status --porcelain', escapeshellarg($path)), $output); if (trim($output)) { throw new \RuntimeException('Source directory has uncommitted changes'); } diff --git a/src/Composer/Downloader/HgDownloader.php b/src/Composer/Downloader/HgDownloader.php index 0dfcbeea6..768280845 100644 --- a/src/Composer/Downloader/HgDownloader.php +++ b/src/Composer/Downloader/HgDownloader.php @@ -18,63 +18,37 @@ use Composer\Util\ProcessExecutor; /** * @author Per Bernhardt */ -class HgDownloader implements DownloaderInterface +class HgDownloader extends VcsDownloader { - protected $process; - - public function __construct(ProcessExecutor $process = null) - { - $this->process = $process ?: new ProcessExecutor; - } - /** * {@inheritDoc} */ - public function getInstallationSource() + public function doDownload(PackageInterface $package, $path) { - return 'source'; - } - - /** - * {@inheritDoc} - */ - public function download(PackageInterface $package, $path) - { - if (!$package->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - $url = escapeshellarg($package->getSourceUrl()); $ref = escapeshellarg($package->getSourceReference()); - $this->process->execute(sprintf('(hg clone %s %s 2> /dev/null) && cd %2$s && hg up %s', $url, $path, $ref)); + $path = escapeshellarg($path); + $this->io->write(" Cloning ".$package->getSourceReference()); + $this->process->execute(sprintf('hg clone %s %s && cd %2$s && hg up %s', $url, $path, $ref), $ignoredOutput); } /** * {@inheritDoc} */ - public function update(PackageInterface $initial, PackageInterface $target, $path) + public function doUpdate(PackageInterface $initial, PackageInterface $target, $path) { - if (!$target->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - - $this->enforceCleanDirectory($path); - $this->process->execute(sprintf('cd %s && hg pull && hg up %s', $path, escapeshellarg($target->getSourceReference()))); + $ref = escapeshellarg($target->getSourceReference()); + $path = escapeshellarg($path); + $this->io->write(" Updating to ".$target->getSourceReference()); + $this->process->execute(sprintf('cd %s && hg pull && hg up %s', $path, $ref), $ignoredOutput); } /** * {@inheritDoc} */ - public function remove(PackageInterface $package, $path) + protected function enforceCleanDirectory($path) { - $this->enforceCleanDirectory($path); - $fs = new Util\Filesystem(); - $fs->removeDirectory($path); - } - - private function enforceCleanDirectory($path) - { - $this->process->execute(sprintf('cd %s && hg st', $path), $output); + $this->process->execute(sprintf('cd %s && hg st', escapeshellarg($path)), $output); if (trim($output)) { throw new \RuntimeException('Source directory has uncommitted changes'); } diff --git a/src/Composer/Downloader/SvnDownloader.php b/src/Composer/Downloader/SvnDownloader.php index 25ddca2cf..e0bb915f6 100644 --- a/src/Composer/Downloader/SvnDownloader.php +++ b/src/Composer/Downloader/SvnDownloader.php @@ -18,65 +18,38 @@ use Composer\Util\ProcessExecutor; /** * @author Ben Bieker */ -class SvnDownloader implements DownloaderInterface +class SvnDownloader extends VcsDownloader { - protected $process; - - public function __construct(ProcessExecutor $process = null) - { - $this->process = $process ?: new ProcessExecutor; - } - /** * {@inheritDoc} */ - public function getInstallationSource() + public function doDownload(PackageInterface $package, $path) { - return 'source'; - } - - /** - * {@inheritDoc} - */ - public function download(PackageInterface $package, $path) - { - if(!$package->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - $url = escapeshellarg($package->getSourceUrl()); $ref = escapeshellarg($package->getSourceReference()); + $path = escapeshellarg($path); + $this->io->write(" Checking out ".$package->getSourceReference()); $this->process->execute(sprintf('svn co %s/%s %s', $url, $ref, $path)); } /** * {@inheritDoc} */ - public function update(PackageInterface $initial, PackageInterface $target, $path) + public function doUpdate(PackageInterface $initial, PackageInterface $target, $path) { - if(!$target->getSourceReference()) { - throw new \InvalidArgumentException('The given package is missing reference information'); - } - - $this->enforceCleanDirectory($path); - $url = escapeshellarg($target->getSourceUrl()); $ref = escapeshellarg($target->getSourceReference()); + $path = escapeshellarg($path); + $url = escapeshellarg($target->getSourceUrl()); + $this->io->write(" Checking out ".$target->getSourceReference()); $this->process->execute(sprintf('cd %s && svn switch %s/%s', $path, $url, $ref)); } /** * {@inheritDoc} */ - public function remove(PackageInterface $package, $path) + protected function enforceCleanDirectory($path) { - $this->enforceCleanDirectory($path); - $fs = new Util\Filesystem(); - $fs->removeDirectory($path); - } - - private function enforceCleanDirectory($path) - { - $this->process->execute(sprintf('cd %s && svn status', $path), $output); + $this->process->execute(sprintf('cd %s && svn status', escapeshellarg($path)), $output); if (trim($output)) { throw new \RuntimeException('Source directory has uncommitted changes'); } diff --git a/src/Composer/Downloader/VcsDownloader.php b/src/Composer/Downloader/VcsDownloader.php new file mode 100644 index 000000000..a4c8239b4 --- /dev/null +++ b/src/Composer/Downloader/VcsDownloader.php @@ -0,0 +1,103 @@ + + * Jordi Boggiano + * + * 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\Util\ProcessExecutor; +use Composer\IO\IOInterface; + +/** + * @author Jordi Boggiano + */ +abstract class VcsDownloader implements DownloaderInterface +{ + protected $io; + protected $process; + + public function __construct(IOInterface $io, ProcessExecutor $process = null) + { + $this->io = $io; + $this->process = $process ?: new ProcessExecutor; + } + + /** + * {@inheritDoc} + */ + public function getInstallationSource() + { + return 'source'; + } + + /** + * {@inheritDoc} + */ + public function download(PackageInterface $package, $path) + { + if (!$package->getSourceReference()) { + throw new \InvalidArgumentException('The given package is missing reference information'); + } + + $this->io->write(" - Package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->doDownload($package, $path); + $this->io->write(''); + } + + /** + * {@inheritDoc} + */ + public function update(PackageInterface $initial, PackageInterface $target, $path) + { + if (!$target->getSourceReference()) { + throw new \InvalidArgumentException('The given package is missing reference information'); + } + + $this->enforceCleanDirectory($path); + $this->io->write(" - Package " . $package->getName() . " (" . $package->getPrettyVersion() . ")"); + $this->doUpdate($initial, $target, $path); + $this->io->write(''); + } + + /** + * {@inheritDoc} + */ + public function remove(PackageInterface $package, $path) + { + $this->enforceCleanDirectory($path); + $fs = new Util\Filesystem(); + $fs->removeDirectory($path); + } + + /** + * Downloads specific package into specific folder. + * + * @param PackageInterface $package package instance + * @param string $path download path + */ + abstract protected function doDownload(PackageInterface $package, $path); + + /** + * Updates specific package in specific folder from initial to target version. + * + * @param PackageInterface $initial initial package + * @param PackageInterface $target updated package + * @param string $path download path + */ + abstract protected function doUpdate(PackageInterface $initial, PackageInterface $target, $path); + + /** + * Checks that no changes have been made to the local copy + * + * @throws \RuntimeException if the directory is not clean + */ + abstract protected function enforceCleanDirectory($path); +} \ No newline at end of file