瀏覽代碼

Overhaul VCS downloaders, added base class and uniformized

Jordi Boggiano 13 年之前
父節點
當前提交
a6ce43817e

+ 0 - 1
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);
 

+ 12 - 38
src/Composer/Downloader/GitDownloader.php

@@ -18,63 +18,37 @@ use Composer\Util\ProcessExecutor;
 /**
  * @author Jordi Boggiano <j.boggiano@seld.be>
  */
-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)
-    {
-        $this->enforceCleanDirectory($path);
-        $fs = new Util\Filesystem();
-        $fs->removeDirectory($path);
-    }
-
-    private function enforceCleanDirectory($path)
+    protected 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');
         }

+ 12 - 38
src/Composer/Downloader/HgDownloader.php

@@ -18,63 +18,37 @@ use Composer\Util\ProcessExecutor;
 /**
  * @author Per Bernhardt <plb@webfactory.de>
  */
-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)
-    {
-        $this->enforceCleanDirectory($path);
-        $fs = new Util\Filesystem();
-        $fs->removeDirectory($path);
-    }
-
-    private function enforceCleanDirectory($path)
+    protected 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');
         }

+ 10 - 37
src/Composer/Downloader/SvnDownloader.php

@@ -18,65 +18,38 @@ use Composer\Util\ProcessExecutor;
 /**
  * @author Ben Bieker <mail@ben-bieker.de>
  */
-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()
-    {
-        return 'source';
-    }
-
     /**
      * {@inheritDoc}
      */
-    public function download(PackageInterface $package, $path)
+    public function doDownload(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)
-    {
-        $this->enforceCleanDirectory($path);
-        $fs = new Util\Filesystem();
-        $fs->removeDirectory($path);
-    }
-
-    private function enforceCleanDirectory($path)
+    protected 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');
         }

+ 103 - 0
src/Composer/Downloader/VcsDownloader.php

@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of Composer.
+ *
+ * (c) Nils Adermann <naderman@naderman.de>
+ *     Jordi Boggiano <j.boggiano@seld.be>
+ *
+ * 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 <j.boggiano@seld.be>
+ */
+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 <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
+        $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 <info>" . $package->getName() . "</info> (<comment>" . $package->getPrettyVersion() . "</comment>)");
+        $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);
+}