diff --git a/src/Composer/Downloader/GitDownloader.php b/src/Composer/Downloader/GitDownloader.php index 9d8e53070..22baff7fd 100644 --- a/src/Composer/Downloader/GitDownloader.php +++ b/src/Composer/Downloader/GitDownloader.php @@ -35,7 +35,7 @@ class GitDownloader extends VcsDownloader $this->runCommand($commandCallable, $package->getSourceUrl(), $path); $this->setPushUrl($package, $path); - $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate()->format('U')); + $this->updateToCommit($path, $ref, $package->getPrettyVersion(), $package->getReleaseDate()); } /** @@ -58,7 +58,7 @@ class GitDownloader extends VcsDownloader }; $this->runCommand($commandCallable, $target->getSourceUrl()); - $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate()->format('U')); + $this->updateToCommit($path, $ref, $target->getPrettyVersion(), $target->getReleaseDate()); } protected function updateToCommit($path, $reference, $branch, $date) @@ -71,8 +71,9 @@ class GitDownloader extends VcsDownloader } // reference was not found (prints "fatal: reference is not a tree: $ref") - if (false !== strpos($this->process->getErrorOutput(), $reference)) { + if ($date && false !== strpos($this->process->getErrorOutput(), $reference)) { $branch = preg_replace('{(?:^dev-|(?:\.x)?-dev$)}i', '', $branch); + $date = $date->format('U'); $command = 'git branch -r'; if (1 === $this->process->execute($command, $output, $path)) { diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index a619c45e6..1f64209a8 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -223,8 +223,7 @@ class Locker if ($package->isDev() && !$alias) { $spec['source-reference'] = $package->getSourceReference(); - if ('git' === $package->getSourceType()) { - $path = $this->installationManager->getInstallPath($package); + if ('git' === $package->getSourceType() && $path = $this->installationManager->getInstallPath($package)) { $process = new ProcessExecutor(); if (0 === $process->execute('git log -n1 --pretty=%ct '.escapeshellarg($package->getSourceReference()), $output, $path)) { $spec['commit-date'] = trim($output); diff --git a/tests/Composer/Test/Downloader/GitDownloaderTest.php b/tests/Composer/Test/Downloader/GitDownloaderTest.php index 81a7172e3..639913498 100644 --- a/tests/Composer/Test/Downloader/GitDownloaderTest.php +++ b/tests/Composer/Test/Downloader/GitDownloaderTest.php @@ -50,12 +50,17 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('https://example.com/composer/composer')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); - $expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref' && git remote add composer 'https://example.com/composer/composer'"); - $processExecutor->expects($this->once()) + $expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer"); + $processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedGitCommand)) ->will($this->returnValue(0)); + $processExecutor->expects($this->at(1)) + ->method('execute') + ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) + ->will($this->returnValue(0)); + $downloader = $this->getDownloaderMock(null, $processExecutor); $downloader->download($packageMock, 'composerPath'); } @@ -71,19 +76,19 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('https://github.com/composer/composer')); $processExecutor = $this->getMock('Composer\Util\ProcessExecutor'); - $expectedGitCommand = $this->getCmd("git clone 'git://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref' && git remote add composer 'git://github.com/composer/composer'"); + $expectedGitCommand = $this->getCmd("git clone 'git://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'git://github.com/composer/composer' && git fetch composer"); $processExecutor->expects($this->at(0)) ->method('execute') ->with($this->equalTo($expectedGitCommand)) ->will($this->returnValue(1)); - $expectedGitCommand = $this->getCmd("git clone 'https://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref' && git remote add composer 'https://github.com/composer/composer'"); + $expectedGitCommand = $this->getCmd("git clone 'https://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://github.com/composer/composer' && git fetch composer"); $processExecutor->expects($this->at(2)) ->method('execute') ->with($this->equalTo($expectedGitCommand)) ->will($this->returnValue(1)); - $expectedGitCommand = $this->getCmd("git clone 'http://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref' && git remote add composer 'http://github.com/composer/composer'"); + $expectedGitCommand = $this->getCmd("git clone 'http://github.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'http://github.com/composer/composer' && git fetch composer"); $processExecutor->expects($this->at(4)) ->method('execute') ->with($this->equalTo($expectedGitCommand)) @@ -95,6 +100,11 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->with($this->equalTo($expectedGitCommand), $this->equalTo(null), $this->equalTo('composerPath')) ->will($this->returnValue(0)); + $processExecutor->expects($this->at(6)) + ->method('execute') + ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) + ->will($this->returnValue(0)); + $downloader = $this->getDownloaderMock(null, $processExecutor); $downloader->download($packageMock, 'composerPath'); } @@ -104,7 +114,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase */ public function testDownloadThrowsRuntimeExceptionIfGitCommandFails() { - $expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git checkout 'ref' && git reset --hard 'ref' && git remote add composer 'https://example.com/composer/composer'"); + $expectedGitCommand = $this->getCmd("git clone 'https://example.com/composer/composer' 'composerPath' && cd 'composerPath' && git remote add composer 'https://example.com/composer/composer' && git fetch composer"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); $packageMock->expects($this->any()) ->method('getSourceReference') @@ -139,7 +149,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase public function testUpdate() { - $expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer && git checkout 'ref' && git reset --hard 'ref'"); + $expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer"); $expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain --untracked-files=no"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); @@ -162,6 +172,10 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase ->method('execute') ->with($this->equalTo($expectedGitUpdateCommand)) ->will($this->returnValue(0)); + $processExecutor->expects($this->at(3)) + ->method('execute') + ->with($this->equalTo($this->getCmd("git checkout 'ref' && git reset --hard 'ref'")), $this->equalTo(null), $this->equalTo('composerPath')) + ->will($this->returnValue(0)); $downloader = $this->getDownloaderMock(null, $processExecutor); $downloader->update($packageMock, $packageMock, 'composerPath'); @@ -172,7 +186,7 @@ class GitDownloaderTest extends \PHPUnit_Framework_TestCase */ public function testUpdateThrowsRuntimeExceptionIfGitCommandFails() { - $expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer && git checkout 'ref' && git reset --hard 'ref'"); + $expectedGitUpdateCommand = $this->getCmd("cd 'composerPath' && git remote set-url composer 'git://github.com/composer/composer' && git fetch composer && git fetch --tags composer"); $expectedGitResetCommand = $this->getCmd("cd 'composerPath' && git status --porcelain --untracked-files=no"); $packageMock = $this->getMock('Composer\Package\PackageInterface'); diff --git a/tests/Composer/Test/InstallerTest.php b/tests/Composer/Test/InstallerTest.php index 8361af192..0dfff7b0b 100644 --- a/tests/Composer/Test/InstallerTest.php +++ b/tests/Composer/Test/InstallerTest.php @@ -170,7 +170,7 @@ class InstallerTest extends TestCase ->method('exists') ->will($this->returnValue(true)); - $locker = new Locker($lockJsonMock, $repositoryManager, md5(json_encode($composerConfig))); + $locker = new Locker($lockJsonMock, $repositoryManager, $composer->getInstallationManager(), md5(json_encode($composerConfig))); $composer->setLocker($locker); $autoloadGenerator = $this->getMock('Composer\Autoload\AutoloadGenerator'); diff --git a/tests/Composer/Test/Mock/InstallationManagerMock.php b/tests/Composer/Test/Mock/InstallationManagerMock.php index cc587a6f9..4bccc63f8 100644 --- a/tests/Composer/Test/Mock/InstallationManagerMock.php +++ b/tests/Composer/Test/Mock/InstallationManagerMock.php @@ -13,6 +13,7 @@ namespace Composer\Test\Mock; use Composer\Installer\InstallationManager; use Composer\Repository\RepositoryInterface; +use Composer\Package\PackageInterface; use Composer\DependencyResolver\Operation\InstallOperation; use Composer\DependencyResolver\Operation\UpdateOperation; use Composer\DependencyResolver\Operation\UninstallOperation; @@ -26,6 +27,11 @@ class InstallationManagerMock extends InstallationManager private $uninstalled = array(); private $trace = array(); + public function getInstallPath(PackageInterface $package) + { + return ''; + } + public function install(RepositoryInterface $repo, InstallOperation $operation) { $this->installed[] = $operation->getPackage(); diff --git a/tests/Composer/Test/Package/LockerTest.php b/tests/Composer/Test/Package/LockerTest.php index a67beb277..2f93d77e2 100644 --- a/tests/Composer/Test/Package/LockerTest.php +++ b/tests/Composer/Test/Package/LockerTest.php @@ -19,7 +19,7 @@ class LockerTest extends \PHPUnit_Framework_TestCase public function testIsLocked() { $json = $this->createJsonFileMock(); - $locker = new Locker($json, $this->createRepositoryManagerMock(), 'md5'); + $locker = new Locker($json, $this->createRepositoryManagerMock(), $this->createInstallationManagerMock(), 'md5'); $json ->expects($this->any()) @@ -37,8 +37,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $json ->expects($this->once()) @@ -54,8 +55,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $json ->expects($this->once()) @@ -87,8 +89,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $json ->expects($this->once()) @@ -122,8 +125,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $package1 = $this->createPackageMock(); $package2 = $this->createPackageMock(); @@ -168,8 +172,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $package1 = $this->createPackageMock(); $package1 @@ -186,8 +191,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $json ->expects($this->once()) @@ -201,8 +207,9 @@ class LockerTest extends \PHPUnit_Framework_TestCase { $json = $this->createJsonFileMock(); $repo = $this->createRepositoryManagerMock(); + $inst = $this->createInstallationManagerMock(); - $locker = new Locker($json, $repo, 'md5'); + $locker = new Locker($json, $repo, $inst, 'md5'); $json ->expects($this->once()) @@ -232,6 +239,15 @@ class LockerTest extends \PHPUnit_Framework_TestCase return $mock; } + private function createInstallationManagerMock() + { + $mock = $this->getMockBuilder('Composer\Installer\InstallationManager') + ->disableOriginalConstructor() + ->getMock(); + + return $mock; + } + private function createPackageMock() { return $this->getMockBuilder('Composer\Package\PackageInterface')