Browse Source

Make it clear what is going on when a vcs folder is missing, fixes #2108

Jordi Boggiano 11 years ago
parent
commit
771233a5a0

+ 11 - 9
doc/faqs/should-i-commit-the-dependencies-in-my-vendor-directory.md

@@ -16,14 +16,16 @@ problems:
   submodules. This is problematic because they are not real submodules, and you
   will run into issues.
 
-If you really feel like you must do this, you have three options:
+If you really feel like you must do this, you have a few options:
 
 1. Limit yourself to installing tagged releases (no dev versions), so that you
-  only get zipped installs, and avoid problems with the git "submodules".
-2. Remove the `.git` directory of every dependency after the installation, then
-  you can add them to your git repo. You can do that with `rm -rf vendor/**/.git`
-  but this means you will have to delete those dependencies from disk before
-  running composer update.
-3. Add a .gitignore rule (`vendor/.git`) to ignore all the vendor `.git` folders.
-  This approach does not require that you delete dependencies from disk prior to
-  running a composer update.
+   only get zipped installs, and avoid problems with the git "submodules".
+2. Use --prefer-dist or set `preferred-install` to `dist` in your
+   [config](../04-schema.md#config).
+3. Remove the `.git` directory of every dependency after the installation, then
+   you can add them to your git repo. You can do that with `rm -rf vendor/**/.git`
+   but this means you will have to delete those dependencies from disk before
+   running composer update.
+4. Add a .gitignore rule (`vendor/.git`) to ignore all the vendor `.git` folders.
+   This approach does not require that you delete dependencies from disk prior to
+   running a composer update.

+ 3 - 0
src/Composer/Downloader/GitDownloader.php

@@ -53,6 +53,9 @@ class GitDownloader extends VcsDownloader
     {
         $this->cleanEnv();
         $path = $this->normalizePath($path);
+        if (!is_dir($path.'/.git')) {
+            throw new \RuntimeException('The .git directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information');
+        }
 
         $ref = $target->getSourceReference();
         $this->io->write("    Checking out ".$ref);

+ 5 - 0
src/Composer/Downloader/HgDownloader.php

@@ -45,6 +45,11 @@ class HgDownloader extends VcsDownloader
         $url = escapeshellarg($target->getSourceUrl());
         $ref = escapeshellarg($target->getSourceReference());
         $this->io->write("    Updating to ".$target->getSourceReference());
+
+        if (!is_dir($path.'/.hg')) {
+            throw new \RuntimeException('The .hg directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information');
+        }
+
         $command = sprintf('hg pull %s && hg up %s', $url, $ref);
         if (0 !== $this->process->execute($command, $ignoredOutput, $path)) {
             throw new \RuntimeException('Failed to execute ' . $command . "\n\n" . $this->process->getErrorOutput());

+ 4 - 0
src/Composer/Downloader/SvnDownloader.php

@@ -41,6 +41,10 @@ class SvnDownloader extends VcsDownloader
         $url = $target->getSourceUrl();
         $ref = $target->getSourceReference();
 
+        if (!is_dir($path.'/.svn')) {
+            throw new \RuntimeException('The .svn directory is missing from '.$path.', see http://getcomposer.org/commit-deps for more information');
+        }
+
         $this->io->write("    Checking out " . $ref);
         $this->execute($url, "svn switch", sprintf("%s/%s", $url, $ref), $path);
     }

+ 23 - 7
tests/Composer/Test/Downloader/GitDownloaderTest.php

@@ -221,6 +221,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
     {
         $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer");
 
+        $tmpDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.'test-git-update';
+        if (!is_dir($tmpDir.'/.git')) {
+            mkdir($tmpDir.'/.git', true, 0777);
+        }
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getSourceReference')
@@ -234,23 +238,27 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
         $processExecutor->expects($this->at(0))
             ->method('execute')
-            ->with($this->equalTo($this->winCompat("git remote -v")))
+            ->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
             ->will($this->returnValue(0));
         $processExecutor->expects($this->at(1))
             ->method('execute')
-            ->with($this->equalTo($expectedGitUpdateCommand))
+            ->with($this->equalTo($this->winCompat("git remote -v")))
             ->will($this->returnValue(0));
         $processExecutor->expects($this->at(2))
             ->method('execute')
-            ->with($this->equalTo('git branch -r'))
+            ->with($this->equalTo($expectedGitUpdateCommand))
             ->will($this->returnValue(0));
         $processExecutor->expects($this->at(3))
             ->method('execute')
-            ->with($this->equalTo($this->winCompat("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo($this->winCompat('composerPath')))
+            ->with($this->equalTo('git branch -r'))
+            ->will($this->returnValue(0));
+        $processExecutor->expects($this->at(4))
+            ->method('execute')
+            ->with($this->equalTo($this->winCompat("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo($this->winCompat($tmpDir)))
             ->will($this->returnValue(0));
 
         $downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
-        $downloader->update($packageMock, $packageMock, 'composerPath');
+        $downloader->update($packageMock, $packageMock, $tmpDir);
     }
 
     /**
@@ -260,6 +268,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
     {
         $expectedGitUpdateCommand = $this->winCompat("git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer");
 
+        $tmpDir = sys_get_temp_dir().DIRECTORY_SEPARATOR.'test-git-update';
+        if (!is_dir($tmpDir.'/.git')) {
+            mkdir($tmpDir.'/.git', true, 0777);
+        }
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getSourceReference')
@@ -270,15 +282,19 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
         $processExecutor->expects($this->at(0))
             ->method('execute')
-            ->with($this->equalTo($this->winCompat("git remote -v")))
+            ->with($this->equalTo($this->winCompat("git status --porcelain --untracked-files=no")))
             ->will($this->returnValue(0));
         $processExecutor->expects($this->at(1))
+            ->method('execute')
+            ->with($this->equalTo($this->winCompat("git remote -v")))
+            ->will($this->returnValue(0));
+        $processExecutor->expects($this->at(2))
             ->method('execute')
             ->with($this->equalTo($expectedGitUpdateCommand))
             ->will($this->returnValue(1));
 
         $downloader = $this->getDownloaderMock(null, new Config(), $processExecutor);
-        $downloader->update($packageMock, $packageMock, 'composerPath');
+        $downloader->update($packageMock, $packageMock, $tmpDir);
     }
 
     public function testRemove()

+ 13 - 3
tests/Composer/Test/Downloader/HgDownloaderTest.php

@@ -84,6 +84,11 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase
 
     public function testUpdate()
     {
+        $tmpDir = sys_get_temp_dir().'/test-hg-update';
+        if (!is_dir($tmpDir.'/.hg')) {
+            mkdir($tmpDir.'/.hg', true, 0777);
+        }
+
         $packageMock = $this->getMock('Composer\Package\PackageInterface');
         $packageMock->expects($this->any())
             ->method('getSourceReference')
@@ -93,14 +98,19 @@ class HgDownloaderTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue('https://github.com/l3l0/composer'));
         $processExecutor = $this->getMock('Composer\Util\ProcessExecutor');
 
-        $expectedGitCommand = $this->getCmd("hg pull 'https://github.com/l3l0/composer' && hg up 'ref'");
+        $expectedHgCommand = $this->getCmd("hg st");
         $processExecutor->expects($this->at(0))
             ->method('execute')
-            ->with($this->equalTo($expectedGitCommand))
+            ->with($this->equalTo($expectedHgCommand))
+            ->will($this->returnValue(0));
+        $expectedHgCommand = $this->getCmd("hg pull 'https://github.com/l3l0/composer' && hg up 'ref'");
+        $processExecutor->expects($this->at(1))
+            ->method('execute')
+            ->with($this->equalTo($expectedHgCommand))
             ->will($this->returnValue(0));
 
         $downloader = $this->getDownloaderMock(null, null, $processExecutor);
-        $downloader->update($packageMock, $packageMock, 'composerPath');
+        $downloader->update($packageMock, $packageMock, $tmpDir);
     }
 
     public function testRemove()