From a175ebed339efa7ab13164d24acee1da411cbfc2 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 17:06:30 +0100 Subject: [PATCH 01/15] Add failing test for new dev behavior --- .../Test/Repository/VcsRepositoryTest.php | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 tests/Composer/Test/Repository/VcsRepositoryTest.php diff --git a/tests/Composer/Test/Repository/VcsRepositoryTest.php b/tests/Composer/Test/Repository/VcsRepositoryTest.php new file mode 100644 index 000000000..0071d3f7d --- /dev/null +++ b/tests/Composer/Test/Repository/VcsRepositoryTest.php @@ -0,0 +1,140 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Test\Json; + +use Symfony\Component\Process\ExecutableFinder; +use Composer\Package\Dumper\ArrayDumper; +use Composer\Repository\VcsRepository; +use Composer\Repository\Vcs\GitDriver; +use Composer\Util\Filesystem; +use Composer\Util\ProcessExecutor; +use Composer\IO\NullIO; + +class VcsRepositoryTest extends \PHPUnit_Framework_TestCase +{ + private static $gitRepo; + private static $skipped; + + public static function setUpBeforeClass() + { + $oldCwd = getcwd(); + self::$gitRepo = sys_get_temp_dir() . '/composer-git-'.rand().'/'; + + $locator = new ExecutableFinder(); + if (!$locator->find('git')) { + self::$skipped = 'This test needs a git binary in the PATH to be able to run'; + return; + } + if (!mkdir(self::$gitRepo) || !chdir(self::$gitRepo)) { + self::$skipped = 'Could not create and move into the temp git repo '.self::$gitRepo; + return; + } + + // init + $process = new ProcessExecutor; + $process->execute('git init', $null); + touch('foo'); + $process->execute('git add foo', $null); + $process->execute('git commit -m init', $null); + + // non-composed tag & branch + $process->execute('git tag 0.5.0', $null); + $process->execute('git branch oldbranch', $null); + + // add composed tag & master branch + $composer = array('name' => 'a/b'); + file_put_contents('composer.json', json_encode($composer)); + $process->execute('git add composer.json', $null); + $process->execute('git commit -m addcomposer', $null); + $process->execute('git tag 0.6.0', $null); + + // add feature-a branch + $process->execute('git checkout -b feature-a', $null); + file_put_contents('foo', 'bar feature'); + $process->execute('git add foo', $null); + $process->execute('git commit -m change-a', $null); + + // add version to composer.json + $process->execute('git checkout master', $null); + $composer['version'] = '1.0.0'; + file_put_contents('composer.json', json_encode($composer)); + $process->execute('git add composer.json', $null); + $process->execute('git commit -m addversion', $null); + + // create tag with wrong version in it + $process->execute('git tag 0.9.0', $null); + // create tag with correct version in it + $process->execute('git tag 1.0.0', $null); + + // add feature-b branch + $process->execute('git checkout -b feature-b', $null); + file_put_contents('foo', 'baz feature'); + $process->execute('git add foo', $null); + $process->execute('git commit -m change-b', $null); + + // add 1.0 branch + $process->execute('git checkout master', $null); + $process->execute('git branch 1.0', $null); + + // update master to 2.0 + $composer['version'] = '2.0.0'; + file_put_contents('composer.json', json_encode($composer)); + $process->execute('git add composer.json', $null); + $process->execute('git commit -m bump-version', $null); + + chdir($oldCwd); + } + + public function setUp() + { + if (self::$skipped) { + $this->markTestSkipped(self::$skipped); + } + } + + public static function tearDownAfterClass() + { + $fs = new Filesystem; + $fs->removeDirectory(self::$gitRepo); + } + + public function testLoadVersions() + { + $expected = array( + '0.6.0' => true, + '0.9.0' => true, + '1.0.0' => true, + 'dev-feature-b' => true, + 'dev-feature-a' => true, + 'dev-master' => true, + ); + + $repo = new VcsRepository(array('url' => self::$gitRepo), new NullIO); + $packages = $repo->getPackages(); + $dumper = new ArrayDumper(); + + foreach ($packages as $package) { + if (isset($expected[$package->getPrettyVersion()])) { + unset($expected[$package->getPrettyVersion()]); + } else { + $this->fail('Unexpected version '.$package->getPrettyVersion().' in '.json_encode($dumper->dump($package))); + } + } + + if ($expected) { + $this->fail('Missing versions: '.implode(', ', $expected)); + } + + $this->pass(); + } +} From 882496b926288ba82ea7f732da76f825b96375c7 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 17:43:12 +0100 Subject: [PATCH 02/15] Adjust version parser tests --- .../Test/Package/Version/VersionParserTest.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index faca00dc9..74e787bde 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -49,9 +49,10 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'parses datetime' => array('20100102-203040', '20100102-203040'), 'parses dt+number' => array('20100102203040-10', '20100102203040-10'), 'parses dt+patch' => array('20100102-203040-p1', '20100102-203040-patch1'), - 'parses master' => array('master', '9999999-dev'), - 'parses trunk' => array('trunk', '9999999-dev'), - 'parses trunk/2' => array('trunk-dev', '9999999-dev'), + 'parses master' => array('dev-master', '9999999-dev'), + 'parses trunk' => array('dev-trunk', '9999999-dev'), + 'parses arbitrary' => array('dev-feature-foo', 'dev-feature-foo'), + 'parses arbitrary2' => array('dev-foobar', 'dev-foobar'), ); } @@ -72,6 +73,7 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'invalid chars' => array('a'), 'invalid type' => array('1.0.0-meh'), 'too many bits' => array('1.0.0.0.0'), + 'non-dev arbitrary' => array('feature-foo'), ); } @@ -97,6 +99,8 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'parses long digits/2' => array('2.4.4', '2.4.4.9999999-dev'), 'parses master' => array('master', '9999999-dev'), 'parses trunk' => array('trunk', '9999999-dev'), + 'parses arbitrary' => array('feature-a', 'dev-feature-a'), + 'parses arbitrary/2' => array('foobar', 'dev-foobar'), ); } From ae7107fc223b0d82327d54c23241c4127a03fb39 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 19:00:40 +0100 Subject: [PATCH 03/15] Add more test requirements --- .../Test/Package/Version/VersionParserTest.php | 7 ++++--- tests/Composer/Test/Repository/VcsRepositoryTest.php | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tests/Composer/Test/Package/Version/VersionParserTest.php b/tests/Composer/Test/Package/Version/VersionParserTest.php index 74e787bde..64a3e79f4 100644 --- a/tests/Composer/Test/Package/Version/VersionParserTest.php +++ b/tests/Composer/Test/Package/Version/VersionParserTest.php @@ -52,7 +52,7 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'parses master' => array('dev-master', '9999999-dev'), 'parses trunk' => array('dev-trunk', '9999999-dev'), 'parses arbitrary' => array('dev-feature-foo', 'dev-feature-foo'), - 'parses arbitrary2' => array('dev-foobar', 'dev-foobar'), + 'parses arbitrary2' => array('DEV-FOOBAR', 'dev-foobar'), ); } @@ -125,8 +125,9 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase 'no op means eq' => array('1.2.3', new VersionConstraint('=', '1.2.3.0')), 'completes version' => array('=1.0', new VersionConstraint('=', '1.0.0.0')), 'accepts spaces' => array('>= 1.2.3', new VersionConstraint('>=', '1.2.3.0')), - 'accepts master' => array('>=master-dev', new VersionConstraint('>=', '9999999-dev')), - 'accepts master/2' => array('master-dev', new VersionConstraint('=', '9999999-dev')), + 'accepts master' => array('>=dev-master', new VersionConstraint('>=', '9999999-dev')), + 'accepts master/2' => array('dev-master', new VersionConstraint('=', '9999999-dev')), + 'accepts arbitrary' => array('dev-feature-a', new VersionConstraint('=', 'dev-feature-a')), ); } diff --git a/tests/Composer/Test/Repository/VcsRepositoryTest.php b/tests/Composer/Test/Repository/VcsRepositoryTest.php index 0071d3f7d..4ea24725b 100644 --- a/tests/Composer/Test/Repository/VcsRepositoryTest.php +++ b/tests/Composer/Test/Repository/VcsRepositoryTest.php @@ -86,6 +86,9 @@ class VcsRepositoryTest extends \PHPUnit_Framework_TestCase $process->execute('git checkout master', $null); $process->execute('git branch 1.0', $null); + // add 1.0.x branch + $process->execute('git branch 1.0.x', $null); + // update master to 2.0 $composer['version'] = '2.0.0'; file_put_contents('composer.json', json_encode($composer)); @@ -112,8 +115,9 @@ class VcsRepositoryTest extends \PHPUnit_Framework_TestCase { $expected = array( '0.6.0' => true, - '0.9.0' => true, '1.0.0' => true, + '1.0-dev' => true, + '1.0.x-dev' => true, 'dev-feature-b' => true, 'dev-feature-a' => true, 'dev-master' => true, @@ -131,10 +135,6 @@ class VcsRepositoryTest extends \PHPUnit_Framework_TestCase } } - if ($expected) { - $this->fail('Missing versions: '.implode(', ', $expected)); - } - - $this->pass(); + $this->assertEmpty($expected, 'Missing versions: '.implode(', ', array_keys($expected))); } } From 3e6176eccf73ac0c89612b0243aa871a6a41299b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 19:08:44 +0100 Subject: [PATCH 04/15] Update version parser to support any branch name --- src/Composer/Package/Version/VersionParser.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Composer/Package/Version/VersionParser.php b/src/Composer/Package/Version/VersionParser.php index 7bd941d93..716c24731 100644 --- a/src/Composer/Package/Version/VersionParser.php +++ b/src/Composer/Package/Version/VersionParser.php @@ -34,10 +34,15 @@ class VersionParser { $version = trim($version); - if (preg_match('{^(?:master|trunk|default)(?:[.-]?dev)?$}i', $version)) { + // match master-like branches + if (preg_match('{^(?:dev-)?(?:master|trunk|default)$}i', $version)) { return '9999999-dev'; } + if ('dev-' === strtolower(substr($version, 0, 4))) { + return strtolower($version); + } + // match classical versioning if (preg_match('{^v?(\d{1,3})(\.\d+)?(\.\d+)?(\.\d+)?'.$this->modifierRegex.'$}i', $version, $matches)) { $version = $matches[1] @@ -53,7 +58,7 @@ class VersionParser // add version modifiers if a version was matched if (isset($index)) { if (!empty($matches[$index])) { - $mod = array('{^pl?$}', '{^rc$}'); + $mod = array('{^pl?$}i', '{^rc$}i'); $modNormalized = array('patch', 'RC'); $version .= '-'.preg_replace($mod, $modNormalized, strtolower($matches[$index])) . (!empty($matches[$index+1]) ? $matches[$index+1] : ''); @@ -97,7 +102,7 @@ class VersionParser return str_replace('x', '9999999', $version).'-dev'; } - throw new \UnexpectedValueException('Invalid branch name '.$name); + return 'dev-'.$name; } /** From f73c08043f8b01628ad198a831091ccf02f612ba Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 19:26:43 +0100 Subject: [PATCH 05/15] Refactor VcsRepo to follow new dev model --- src/Composer/Repository/VcsRepository.php | 42 +++++++---------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index a2506d2df..115baad47 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -82,14 +82,10 @@ class VcsRepository extends ArrayRepository try { $data = $driver->getComposerInformation($identifier); } catch (\Exception $e) { - if (strpos($e->getMessage(), 'JSON Parse Error') !== false) { - if ($debug) { - $this->io->write('Skipped tag '.$tag.', '.$e->getMessage()); - } - continue; - } else { - throw $e; + if ($debug) { + $this->io->write('Skipped tag '.$tag.', '.$e->getMessage()); } + continue; } // manually versioned package @@ -103,7 +99,7 @@ class VcsRepository extends ArrayRepository // make sure tag packages have no -dev flag $data['version'] = preg_replace('{[.-]?dev$}i', '', $data['version']); - $data['version_normalized'] = preg_replace('{[.-]?dev$}i', '', $data['version_normalized']); + $data['version_normalized'] = preg_replace('{(^dev-|[.-]?dev$)}i', '', $data['version_normalized']); // broken package, version doesn't match tag if ($data['version_normalized'] !== $parsedTag) { @@ -131,34 +127,22 @@ class VcsRepository extends ArrayRepository if ($driver->hasComposerFile($identifier)) { $data = $driver->getComposerInformation($identifier); - // manually versioned package - if (isset($data['version'])) { - $data['version_normalized'] = $versionParser->normalize($data['version']); - } elseif ($parsedBranch) { - // auto-versionned package, read value from branch name - $data['version'] = $branch; - $data['version_normalized'] = $parsedBranch; - } else { + if (!$parsedBranch) { if ($debug) { $this->io->write('Skipped branch '.$branch.', invalid name and no composer file was found'); } continue; } - // make sure branch packages have a -dev flag - $normalizedStableVersion = preg_replace('{[.-]?dev$}i', '', $data['version_normalized']); - $data['version'] = preg_replace('{[.-]?dev$}i', '', $data['version']) . '-dev'; - $data['version_normalized'] = $normalizedStableVersion . '-dev'; + // branches are always auto-versionned, read value from branch name + $data['version'] = $branch; + $data['version_normalized'] = $parsedBranch; - // Skip branches that contain a version that has been tagged already - foreach ($this->getPackages() as $package) { - if ($normalizedStableVersion === $package->getVersion()) { - if ($debug) { - $this->io->write('Skipped branch '.$branch.', already tagged'); - } - - continue 2; - } + // make sure branch packages have a dev flag + if ('dev-' === substr($parsedBranch, 0, 4) || '9999999-dev' === $parsedBranch) { + $data['version'] = 'dev-' . $data['version']; + } else { + $data['version'] = $data['version'] . '-dev'; } if ($debug) { From 3fe87b1e35c60db74483f2c8acc4154dd9efbf5f Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 23:21:45 +0100 Subject: [PATCH 06/15] Force dev packages to be installed from source --- src/Composer/Downloader/DownloadManager.php | 8 ++++---- src/Composer/Installer/LibraryInstaller.php | 4 +++- src/Composer/Package/MemoryPackage.php | 11 +++++++++++ src/Composer/Package/PackageInterface.php | 7 +++++++ .../Test/Installer/InstallerInstallerTest.php | 8 ++++---- .../Composer/Test/Installer/LibraryInstallerTest.php | 5 ++--- 6 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/Composer/Downloader/DownloadManager.php b/src/Composer/Downloader/DownloadManager.php index e466bbb09..e1441f182 100644 --- a/src/Composer/Downloader/DownloadManager.php +++ b/src/Composer/Downloader/DownloadManager.php @@ -125,14 +125,14 @@ class DownloadManager $sourceType = $package->getSourceType(); $distType = $package->getDistType(); - if (!($preferSource && $sourceType) && $distType) { + if (!$package->isDev() && !($preferSource && $sourceType) && $distType) { $package->setInstallationSource('dist'); } elseif ($sourceType) { $package->setInstallationSource('source'); + } elseif ($package->isDev()) { + throw new \InvalidArgumentException('Dev package '.$package.' must have a source specified'); } else { - throw new \InvalidArgumentException( - 'Package '.$package.' should have source or dist specified' - ); + throw new \InvalidArgumentException('Package '.$package.' must have a source or dist specified'); } $fs = new Filesystem(); diff --git a/src/Composer/Installer/LibraryInstaller.php b/src/Composer/Installer/LibraryInstaller.php index a3f0b2b74..8eef0d7ed 100644 --- a/src/Composer/Installer/LibraryInstaller.php +++ b/src/Composer/Installer/LibraryInstaller.php @@ -109,7 +109,9 @@ class LibraryInstaller implements InstallerInterface $this->downloadManager->update($initial, $target, $downloadPath); $this->installBinaries($target); $this->repository->removePackage($initial); - $this->repository->addPackage(clone $target); + if (!$this->repository->hasPackage($target)) { + $this->repository->addPackage(clone $target); + } } /** diff --git a/src/Composer/Package/MemoryPackage.php b/src/Composer/Package/MemoryPackage.php index d1e63e102..a57f2b6f6 100644 --- a/src/Composer/Package/MemoryPackage.php +++ b/src/Composer/Package/MemoryPackage.php @@ -41,6 +41,7 @@ class MemoryPackage extends BasePackage protected $extra = array(); protected $binaries = array(); protected $scripts = array(); + protected $dev; protected $requires = array(); protected $conflicts = array(); @@ -63,6 +64,16 @@ class MemoryPackage extends BasePackage $this->version = $version; $this->prettyVersion = $prettyVersion; + + $this->dev = 'dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4); + } + + /** + * {@inheritDoc} + */ + public function isDev() + { + return $this->dev; } /** diff --git a/src/Composer/Package/PackageInterface.php b/src/Composer/Package/PackageInterface.php index c8f92b581..1f19a835f 100644 --- a/src/Composer/Package/PackageInterface.php +++ b/src/Composer/Package/PackageInterface.php @@ -68,6 +68,13 @@ interface PackageInterface */ function matches($name, LinkConstraintInterface $constraint); + /** + * Returns whether the package is a development virtual package or a concrete one + * + * @return Boolean + */ + function isDev(); + /** * Returns the package type, e.g. library * diff --git a/tests/Composer/Test/Installer/InstallerInstallerTest.php b/tests/Composer/Test/Installer/InstallerInstallerTest.php index 4e2f8c732..eab2d948a 100644 --- a/tests/Composer/Test/Installer/InstallerInstallerTest.php +++ b/tests/Composer/Test/Installer/InstallerInstallerTest.php @@ -67,9 +67,9 @@ class InstallerInstallerTest extends \PHPUnit_Framework_TestCase ->method('getPackages') ->will($this->returnValue(array($this->packages[0]))); $this->repository - ->expects($this->once()) + ->expects($this->exactly(2)) ->method('hasPackage') - ->will($this->returnValue(true)); + ->will($this->onConsecutiveCalls(true, false)); $installer = new InstallerInstallerMock(__DIR__.'/Fixtures/', __DIR__.'/Fixtures/bin', $this->dm, $this->repository, $this->io, $this->im); $test = $this; @@ -90,9 +90,9 @@ class InstallerInstallerTest extends \PHPUnit_Framework_TestCase ->method('getPackages') ->will($this->returnValue(array($this->packages[1]))); $this->repository - ->expects($this->once()) + ->expects($this->exactly(2)) ->method('hasPackage') - ->will($this->returnValue(true)); + ->will($this->onConsecutiveCalls(true, false)); $installer = new InstallerInstallerMock(__DIR__.'/Fixtures/', __DIR__.'/Fixtures/bin', $this->dm, $this->repository, $this->io, $this->im); $test = $this; diff --git a/tests/Composer/Test/Installer/LibraryInstallerTest.php b/tests/Composer/Test/Installer/LibraryInstallerTest.php index 3399345f0..ba86954e3 100644 --- a/tests/Composer/Test/Installer/LibraryInstallerTest.php +++ b/tests/Composer/Test/Installer/LibraryInstallerTest.php @@ -128,10 +128,9 @@ class LibraryInstallerTest extends \PHPUnit_Framework_TestCase ->will($this->returnValue('package1')); $this->repository - ->expects($this->exactly(2)) + ->expects($this->exactly(3)) ->method('hasPackage') - ->with($initial) - ->will($this->onConsecutiveCalls(true, false)); + ->will($this->onConsecutiveCalls(true, false, false)); $this->dm ->expects($this->once()) From c1baa20feca5f645c420bf91094e3dcb9705d3d4 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sat, 18 Feb 2012 23:48:12 +0100 Subject: [PATCH 07/15] Lock reference of dev packages --- src/Composer/Package/Locker.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 21e09eaf3..09a187313 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -116,7 +116,13 @@ class Locker )); } - $lock['packages'][] = array('package' => $name, 'version' => $version); + $spec = array('package' => $name, 'version' => $version); + + if ($package->isDev()) { + $spec['reference'] = $package->getSourceReference(); + } + + $lock['packages'][] = $spec; } $this->lockFile->write($lock); From 496188f71415ddd87a144f7752eeeff45d2e4799 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 00:13:51 +0100 Subject: [PATCH 08/15] Force installs from lock to reinstall dev packages from the exact locked reference --- src/Composer/Command/InstallCommand.php | 20 ++++++++++++++++++++ src/Composer/Package/Locker.php | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index d656ad5d1..86552362b 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -113,6 +113,7 @@ EOT } // creating requirements request + $installFromLock = false; $request = new Request($pool); if ($update) { $io->write('Updating dependencies'); @@ -130,6 +131,7 @@ EOT $request->install($link->getTarget(), $link->getConstraint()); } } elseif ($composer->getLocker()->isLocked()) { + $installFromLock = true; $io->write('Installing from lock file'); if (!$composer->getLocker()->isFresh()) { @@ -196,7 +198,25 @@ EOT } if (!$dryRun) { $eventDispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::PRE_PACKAGE_'.strtoupper($operation->getJobType())), $operation); + + // if installing from lock, restore dev packages' references to their locked state + if ($installFromLock) { + $package = null; + if ('update' === $operation->getJobType()) { + $package = $operation->getTargetPackage(); + } elseif ('install' === $operation->getJobType()) { + $package = $operation->getPackage(); + } + if ($package && $package->isDev()) { + foreach ($composer->getLocker()->getLockedPackages() as $lockedPackage) { + if (!empty($lockedPackage['source_reference']) && strtolower($lockedPackage['package']) === $package->getName()) { + $package->setSourceReference($lockedPackage['source_reference']); + } + } + } + } $installationManager->execute($operation); + $eventDispatcher->dispatchPackageEvent(constant('Composer\Script\ScriptEvents::POST_PACKAGE_'.strtoupper($operation->getJobType())), $operation); } } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 09a187313..39a299873 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -119,7 +119,7 @@ class Locker $spec = array('package' => $name, 'version' => $version); if ($package->isDev()) { - $spec['reference'] = $package->getSourceReference(); + $spec['source_reference'] = $package->getSourceReference(); } $lock['packages'][] = $spec; From 88b018068cdcde719489a4e59d0bb223ee88f4d4 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 00:51:13 +0100 Subject: [PATCH 09/15] Force dev packages to update to latest ref on update --- src/Composer/Command/InstallCommand.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 86552362b..e2dcb6a38 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -30,6 +30,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Composer\DependencyResolver\Operation\InstallOperation; +use Composer\DependencyResolver\Operation\UpdateOperation; use Composer\DependencyResolver\Solver; use Composer\IO\IOInterface; @@ -192,6 +193,28 @@ EOT if (!$operations) { $io->write('Nothing to install/update'); } + + // force dev packages to be updated to latest reference on update + if ($update) { + foreach ($installedPackages as $package) { + if (!$package->isDev()) { + continue; + } + foreach ($operations as $operation) { + if (('update' === $operation->getJobType() && $package === $operation->getInitialPackage()) + || ('uninstall' === $operation->getJobType() && $package === $operation->getPackage()) + ) { + continue 2; + } + } + + // force update + $newPackage = $composer->getRepositoryManager()->findPackage($package->getName(), $package->getVersion()); + $operation = new UpdateOperation($package, $newPackage); + $operations[] = $operation; + } + } + foreach ($operations as $operation) { if ($verbose) { $io->write((string) $operation); From d7350b66d52c228ed6151ee771e0ca17e0f7792e Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 12:05:09 +0100 Subject: [PATCH 10/15] Ensure dev packages have a source --- src/Composer/Package/Loader/ArrayLoader.php | 2 ++ src/Composer/Package/Loader/RootPackageLoader.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Composer/Package/Loader/ArrayLoader.php b/src/Composer/Package/Loader/ArrayLoader.php index 6d6f4f15d..7c992392c 100644 --- a/src/Composer/Package/Loader/ArrayLoader.php +++ b/src/Composer/Package/Loader/ArrayLoader.php @@ -122,6 +122,8 @@ class ArrayLoader $package->setSourceType($config['source']['type']); $package->setSourceUrl($config['source']['url']); $package->setSourceReference($config['source']['reference']); + } elseif ($package->isDev()) { + throw new \UnexpectedValueException('Dev package '.$package.' must have a source specified'); } if (isset($config['dist'])) { diff --git a/src/Composer/Package/Loader/RootPackageLoader.php b/src/Composer/Package/Loader/RootPackageLoader.php index 294dd3f42..208bc4fcf 100644 --- a/src/Composer/Package/Loader/RootPackageLoader.php +++ b/src/Composer/Package/Loader/RootPackageLoader.php @@ -38,7 +38,7 @@ class RootPackageLoader extends ArrayLoader $config['name'] = '__root__'; } if (!isset($config['version'])) { - $config['version'] = '1.0.0-dev'; + $config['version'] = '1.0.0'; } $package = parent::load($config); From c12dccd3d42f998b99d79d754b240dda51bf7029 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 13:48:42 +0100 Subject: [PATCH 11/15] Restore quality of debug output --- src/Composer/Repository/VcsRepository.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Composer/Repository/VcsRepository.php b/src/Composer/Repository/VcsRepository.php index 115baad47..2c4175fa0 100644 --- a/src/Composer/Repository/VcsRepository.php +++ b/src/Composer/Repository/VcsRepository.php @@ -76,7 +76,13 @@ class VcsRepository extends ArrayRepository } foreach ($driver->getTags() as $tag => $identifier) { - $this->io->overwrite('Get composer of ' . $this->packageName . ' (' . $tag . ')', false); + $msg = 'Get composer info for ' . $this->packageName . ' (' . $tag . ')'; + if ($debug) { + $this->io->write($msg); + } else { + $this->io->overwrite($msg, false); + } + $parsedTag = $this->validateTag($versionParser, $tag); if ($parsedTag && $driver->hasComposerFile($identifier)) { try { @@ -122,7 +128,13 @@ class VcsRepository extends ArrayRepository $this->io->overwrite('', false); foreach ($driver->getBranches() as $branch => $identifier) { - $this->io->overwrite('Get composer of ' . $this->packageName . ' (' . $branch . ')', false); + $msg = 'Get composer info for ' . $this->packageName . ' (' . $branch . ')'; + if ($debug) { + $this->io->write($msg); + } else { + $this->io->overwrite($msg, false); + } + $parsedBranch = $this->validateBranch($versionParser, $branch); if ($driver->hasComposerFile($identifier)) { $data = $driver->getComposerInformation($identifier); From 646d01658a8aa7dfcc467e8be4197045bc429747 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 15:20:03 +0100 Subject: [PATCH 12/15] Rename source_ref to source-ref --- src/Composer/Command/InstallCommand.php | 4 ++-- src/Composer/Package/Locker.php | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index e2dcb6a38..937393a1c 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -232,8 +232,8 @@ EOT } if ($package && $package->isDev()) { foreach ($composer->getLocker()->getLockedPackages() as $lockedPackage) { - if (!empty($lockedPackage['source_reference']) && strtolower($lockedPackage['package']) === $package->getName()) { - $package->setSourceReference($lockedPackage['source_reference']); + if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) { + $package->setSourceReference($lockedPackage['source-reference']); } } } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 39a299873..255835ec3 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -119,7 +119,7 @@ class Locker $spec = array('package' => $name, 'version' => $version); if ($package->isDev()) { - $spec['source_reference'] = $package->getSourceReference(); + $spec['source-reference'] = $package->getSourceReference(); } $lock['packages'][] = $spec; From 4233a4823d7316e6d363c5bd0daad066d2a6cd73 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 16:33:19 +0100 Subject: [PATCH 13/15] Skip platform repo and only force-update packages that have a new source ref --- src/Composer/Command/InstallCommand.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 937393a1c..760c14e8f 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -196,10 +196,13 @@ EOT // force dev packages to be updated to latest reference on update if ($update) { - foreach ($installedPackages as $package) { + foreach ($localRepo->getPackages() as $package) { + // skip non-dev packages if (!$package->isDev()) { continue; } + + // skip packages that will be updated/uninstalled foreach ($operations as $operation) { if (('update' === $operation->getJobType() && $package === $operation->getInitialPackage()) || ('uninstall' === $operation->getJobType() && $package === $operation->getPackage()) @@ -210,8 +213,10 @@ EOT // force update $newPackage = $composer->getRepositoryManager()->findPackage($package->getName(), $package->getVersion()); - $operation = new UpdateOperation($package, $newPackage); - $operations[] = $operation; + if ($newPackage->getSourceReference() !== $package->getSourceReference()) { + $operation = new UpdateOperation($package, $newPackage); + $operations[] = $operation; + } } } From c95b4d05fdf45c8d48268fa64dc59f63e9ada27b Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Sun, 19 Feb 2012 16:34:35 +0100 Subject: [PATCH 14/15] Fix forcing of the source-ref from lock file --- src/Composer/Command/InstallCommand.php | 4 +++- src/Composer/Package/Locker.php | 15 ++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 760c14e8f..5fe2e64db 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -236,9 +236,11 @@ EOT $package = $operation->getPackage(); } if ($package && $package->isDev()) { - foreach ($composer->getLocker()->getLockedPackages() as $lockedPackage) { + $lockData = $composer->getLocker()->getLockData(); + foreach ($lockData['packages'] as $lockedPackage) { if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) { $package->setSourceReference($lockedPackage['source-reference']); + break; } } } diff --git a/src/Composer/Package/Locker.php b/src/Composer/Package/Locker.php index 255835ec3..24aafae8f 100644 --- a/src/Composer/Package/Locker.php +++ b/src/Composer/Package/Locker.php @@ -69,11 +69,7 @@ class Locker */ public function getLockedPackages() { - if (!$this->isLocked()) { - throw new \LogicException('No lockfile found. Unable to read locked packages'); - } - - $lockList = $this->lockFile->read(); + $lockList = $this->getLockData(); $packages = array(); foreach ($lockList['packages'] as $info) { $package = $this->repositoryManager->getLocalRepository()->findPackage($info['package'], $info['version']); @@ -95,6 +91,15 @@ class Locker return $packages; } + public function getLockData() + { + if (!$this->isLocked()) { + throw new \LogicException('No lockfile found. Unable to read locked packages'); + } + + return $this->lockFile->read(); + } + /** * Locks provided packages into lockfile. * From 2976bd82b05905965676e4eb02fa47050467f252 Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Mon, 20 Feb 2012 09:50:02 +0100 Subject: [PATCH 15/15] Simplify code --- src/Composer/Command/InstallCommand.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Composer/Command/InstallCommand.php b/src/Composer/Command/InstallCommand.php index 5fe2e64db..60250d0d0 100644 --- a/src/Composer/Command/InstallCommand.php +++ b/src/Composer/Command/InstallCommand.php @@ -214,8 +214,7 @@ EOT // force update $newPackage = $composer->getRepositoryManager()->findPackage($package->getName(), $package->getVersion()); if ($newPackage->getSourceReference() !== $package->getSourceReference()) { - $operation = new UpdateOperation($package, $newPackage); - $operations[] = $operation; + $operations[] = new UpdateOperation($package, $newPackage); } } }