Browse Source

Merge remote-tracking branch 'bozerkins/force-to-reinstall-package-when-missing-vcs-metadata'

Jordi Boggiano 9 years ago
parent
commit
e4ede0c582

+ 11 - 4
src/Composer/Downloader/DownloadManager.php

@@ -250,11 +250,18 @@ class DownloadManager
 
         if ($initialType === $targetType) {
             $target->setInstallationSource($installationSource);
-            $downloader->update($initial, $target, $targetDir);
-        } else {
-            $downloader->remove($initial, $targetDir);
-            $this->download($target, $targetDir, 'source' === $installationSource);
+            try {
+                $downloader->update($initial, $target, $targetDir);
+                return;
+            } catch (\RuntimeException $ex) {
+                if (!$this->io->isInteractive() ||
+                    !$this->io->askConfirmation('    Updating failed. Would you like to try reinstalling instead [<comment>yes</comment>]? ', true)) {
+                    throw $ex;
+                }
+            }
         }
+        $downloader->remove($initial, $targetDir);
+        $this->download($target, $targetDir, 'source' === $installationSource);
     }
 
     /**

+ 15 - 4
src/Composer/Downloader/GitDownloader.php

@@ -73,8 +73,7 @@ class GitDownloader extends VcsDownloader
     public function doUpdate(PackageInterface $initial, PackageInterface $target, $path, $url)
     {
         GitUtil::cleanEnv();
-        $path = $this->normalizePath($path);
-        if (!is_dir($path.'/.git')) {
+        if (!$this->hasMetadataRepository($path)) {
             throw new \RuntimeException('The .git directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
         }
 
@@ -101,8 +100,7 @@ class GitDownloader extends VcsDownloader
     public function getLocalChanges(PackageInterface $package, $path)
     {
         GitUtil::cleanEnv();
-        $path = $this->normalizePath($path);
-        if (!is_dir($path.'/.git')) {
+        if (!$this->hasMetadataRepository($path)) {
             return;
         }
 
@@ -372,4 +370,17 @@ class GitDownloader extends VcsDownloader
 
         return $path;
     }
+
+    /**
+     * Checks if VCS metadata repository has been initialized
+     * repository example: .git|.svn|.hg
+     *
+     * @param string $path
+     * @return bool
+     */
+    protected function hasMetadataRepository($path)
+    {
+        $path = $this->normalizePath($path);
+        return is_dir($path.'/.git');
+    }
 }

+ 13 - 1
src/Composer/Downloader/HgDownloader.php

@@ -47,7 +47,7 @@ class HgDownloader extends VcsDownloader
         $ref = ProcessExecutor::escape($target->getSourceReference());
         $this->io->writeError("    Updating to ".$target->getSourceReference());
 
-        if (!is_dir($path.'/.hg')) {
+        if (!$this->hasMetadataRepository($path)) {
             throw new \RuntimeException('The .hg directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
         }
 
@@ -84,4 +84,16 @@ class HgDownloader extends VcsDownloader
 
         return $output;
     }
+
+    /**
+     * Checks if VCS metadata repository has been initialized
+     * repository example: .git|.svn|.hg
+     *
+     * @param string $path
+     * @return bool
+     */
+    protected function hasMetadataRepository($path)
+    {
+        return is_dir($path . '/.hg');
+    }
 }

+ 12 - 0
src/Composer/Downloader/PerforceDownloader.php

@@ -104,4 +104,16 @@ class PerforceDownloader extends VcsDownloader
     {
         $this->perforce = $perforce;
     }
+
+    /**
+     * Checks if VCS metadata repository has been initialized
+     * repository example: .git|.svn|.hg
+     *
+     * @param string $path
+     * @return bool
+     */
+    protected function hasMetadataRepository($path)
+    {
+        return true;
+    }
 }

+ 14 - 2
src/Composer/Downloader/SvnDownloader.php

@@ -52,7 +52,7 @@ class SvnDownloader extends VcsDownloader
         SvnUtil::cleanEnv();
         $ref = $target->getSourceReference();
 
-        if (!is_dir($path.'/.svn')) {
+        if (!$this->hasMetadataRepository($path)) {
             throw new \RuntimeException('The .svn directory is missing from '.$path.', see https://getcomposer.org/commit-deps for more information');
         }
 
@@ -72,7 +72,7 @@ class SvnDownloader extends VcsDownloader
      */
     public function getLocalChanges(PackageInterface $package, $path)
     {
-        if (!is_dir($path.'/.svn')) {
+        if (!$this->hasMetadataRepository($path)) {
             return;
         }
 
@@ -188,4 +188,16 @@ class SvnDownloader extends VcsDownloader
             throw new \RuntimeException("Could not reset changes\n\n:".$this->process->getErrorOutput());
         }
     }
+
+    /**
+     * Checks if VCS metadata repository has been initialized
+     * repository example: .git|.svn|.hg
+     *
+     * @param string $path
+     * @return bool
+     */
+    protected function hasMetadataRepository($path)
+    {
+        return is_dir($path.'/.svn');
+    }
 }

+ 20 - 9
src/Composer/Downloader/VcsDownloader.php

@@ -111,6 +111,8 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
 
         $this->cleanChanges($initial, $path, true);
         $urls = $target->getSourceUrls();
+
+        $exception = null;
         while ($url = array_shift($urls)) {
             try {
                 if (Filesystem::isLocalPath($url)) {
@@ -118,24 +120,20 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
                 }
                 $this->doUpdate($initial, $target, $path, $url);
                 break;
-            } catch (\Exception $e) {
+            } catch (\Exception $exception) {
                 if ($this->io->isDebug()) {
-                    $this->io->writeError('Failed: ['.get_class($e).'] '.$e->getMessage());
+                    $this->io->writeError('Failed: ['.get_class($exception).'] '.$exception->getMessage());
                 } elseif (count($urls)) {
                     $this->io->writeError('    Failed, trying the next URL');
-                } else {
-                    // in case of failed update, try to reapply the changes before aborting
-                    $this->reapplyChanges($path);
-
-                    throw $e;
                 }
             }
         }
 
         $this->reapplyChanges($path);
 
-        // print the commit logs if in verbose mode
-        if ($this->io->isVerbose()) {
+        // print the commit logs if in verbose mode and VCS metadata is present
+        // because in case of missing metadata code would trigger another exception
+        if ($this->io->isVerbose() && $this->hasMetadataRepository($path)) {
             $message = 'Pulling in changes:';
             $logs = $this->getCommitLogs($initial->getSourceReference(), $target->getSourceReference(), $path);
 
@@ -157,6 +155,10 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
             }
         }
 
+        if (!$urls && $exception) {
+            throw $exception;
+        }
+
         $this->io->writeError('');
     }
 
@@ -236,4 +238,13 @@ abstract class VcsDownloader implements DownloaderInterface, ChangeReportInterfa
      * @return string
      */
     abstract protected function getCommitLogs($fromReference, $toReference, $path);
+
+    /**
+     * Checks if VCS metadata repository has been initialized
+     * repository example: .git|.svn|.hg
+     *
+     * @param string $path
+     * @return bool
+     */
+    abstract protected function hasMetadataRepository($path);
 }