1
0
Fork 0

Merge pull request #702 from Seldaek/specify-refs

Specify commit/refs for dev requirements
pull/698/merge
Nils Adermann 2012-05-20 07:01:42 -07:00
commit 81de780533
9 changed files with 178 additions and 34 deletions

View File

@ -1,5 +1,6 @@
* 1.0.0-alpha4
* Schema: Added references for dev versions, requiring 'dev-master#abcdef' for example will force the abcdef commit
* Added caching of GitHub metadata (faster startup time with custom GitHub VCS repos)
* 1.0.0-alpha3 (2012-05-13)

View File

@ -230,6 +230,23 @@ Example:
}
}
`require` and `require-dev` additionally support explicit references (i.e.
commit) for dev versions to make sure they are blocked to a given state, even
when you run update. These only work if you explicitly require a dev version
and append the reference with `#<ref>`. Note that while this is convenient at
times, it should not really be how you use packages in the long term. You
should always try to switch to tagged releases as soon as you can, especially
if the project you work on will not be touched for a while.
Example:
{
"require": {
"monolog/monolog": "dev-master#2eb0c0978d290a1c45346a1955188929cb4e5db7"
"acme/foo": "1.0.x-dev#abc123"
}
}
#### require
Lists packages required by this package. The package will not be installed

View File

@ -294,42 +294,50 @@ class Installer
}
// force dev packages to be updated if we update or install from a (potentially new) lock
if ($this->update || $installFromLock) {
foreach ($localRepo->getPackages() as $package) {
// skip non-dev packages
if (!$package->isDev()) {
continue;
}
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() && $operation->getInitialPackage()->equals($package))
|| ('uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package))
) {
continue 2;
// skip packages that will be updated/uninstalled
foreach ($operations as $operation) {
if (('update' === $operation->getJobType() && $operation->getInitialPackage()->equals($package))
|| ('uninstall' === $operation->getJobType() && $operation->getPackage()->equals($package))
) {
continue 2;
}
}
// force update to locked version if it does not match the installed version
if ($installFromLock) {
$lockData = $this->locker->getLockData();
unset($lockedReference);
foreach ($lockData['packages'] as $lockedPackage) {
if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
$lockedReference = $lockedPackage['source-reference'];
break;
}
}
if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) {
// changing the source ref to update to will be handled in the operations loop below
$operations[] = new UpdateOperation($package, clone $package);
}
} else {
// force update to latest on update
if ($this->update) {
$newPackage = $this->repositoryManager->findPackage($package->getName(), $package->getVersion());
if ($newPackage && $newPackage->getSourceReference() !== $package->getSourceReference()) {
$operations[] = new UpdateOperation($package, $newPackage);
}
} elseif ($installFromLock) {
// force update to locked version if it does not match the installed version
$lockData = $this->locker->getLockData();
unset($lockedReference);
foreach ($lockData['packages'] as $lockedPackage) {
if (!empty($lockedPackage['source-reference']) && strtolower($lockedPackage['package']) === $package->getName()) {
$lockedReference = $lockedPackage['source-reference'];
break;
}
}
if (isset($lockedReference) && $lockedReference !== $package->getSourceReference()) {
// changing the source ref to update to will be handled in the operations loop below
$operations[] = new UpdateOperation($package, $package);
}
}
// force installed package to update to referenced version if it does not match the installed version
$references = $this->package->getReferences();
if (isset($references[$package->getName()]) && $references[$package->getName()] !== $package->getSourceReference()) {
// changing the source ref to update to will be handled in the operations loop below
$operations[] = new UpdateOperation($package, clone $package);
}
}
}
@ -378,7 +386,22 @@ class Installer
}
}
}
} else {
// not installing from lock, force dev packages' references if they're in root package refs
$package = null;
if ('update' === $operation->getJobType()) {
$package = $operation->getTargetPackage();
} elseif ('install' === $operation->getJobType()) {
$package = $operation->getPackage();
}
if ($package && $package->isDev()) {
$references = $this->package->getReferences();
if (isset($references[$package->getName()])) {
$package->setSourceReference($references[$package->getName()]);
}
}
}
$this->installationManager->execute($localRepo, $operation);
$event = 'Composer\Script\ScriptEvents::POST_PACKAGE_'.strtoupper($operation->getJobType());

View File

@ -63,17 +63,18 @@ class RootPackageLoader extends ArrayLoader
$aliases = array();
$stabilityFlags = array();
if (isset($config['require'])) {
$aliases = $this->extractAliases($config['require'], $aliases);
$stabilityFlags = $this->extractStabilityFlags($config['require'], $stabilityFlags);
}
if (isset($config['require-dev'])) {
$aliases = $this->extractAliases($config['require-dev'], $aliases);
$stabilityFlags = $this->extractStabilityFlags($config['require-dev'], $stabilityFlags);
$references = array();
foreach (array('require', 'require-dev') as $linkType) {
if (isset($config[$linkType])) {
$aliases = $this->extractAliases($config[$linkType], $aliases);
$stabilityFlags = $this->extractStabilityFlags($config[$linkType], $stabilityFlags);
$references = $this->extractReferences($config[$linkType], $references);
}
}
$package->setAliases($aliases);
$package->setStabilityFlags($stabilityFlags);
$package->setReferences($references);
if (isset($config['minimum-stability'])) {
$package->setMinimumStability(VersionParser::normalizeStability($config['minimum-stability']));
@ -145,4 +146,16 @@ class RootPackageLoader extends ArrayLoader
return $stabilityFlags;
}
private function extractReferences(array $requires, array $references)
{
foreach ($requires as $reqName => $reqVersion) {
if (preg_match('{^[^,\s@]+?#([a-f0-9]+)$}', $reqVersion, $match) && 'dev' === ($stabilityName = VersionParser::parseStability($reqVersion))) {
$name = strtolower($reqName);
$references[$name] = $match[1];
}
}
return $references;
}
}

View File

@ -51,6 +51,7 @@ class MemoryPackage extends BasePackage
// TODO BC change dev to stable end of june?
protected $minimumStability = 'dev';
protected $stabilityFlags = array();
protected $references = array();
protected $requires = array();
protected $conflicts = array();
@ -637,6 +638,24 @@ class MemoryPackage extends BasePackage
return $this->stabilityFlags;
}
/**
* Set the references
*
* @param array $references
*/
public function setReferences(array $references)
{
$this->references = $references;
}
/**
* {@inheritDoc}
*/
public function getReferences()
{
return $this->references;
}
/**
* Set the autoload mapping
*

View File

@ -33,6 +33,8 @@ class VersionParser
*/
static public function parseStability($version)
{
$version = preg_replace('{#[a-f0-9]+$}i', '', $version);
if ('dev-' === substr($version, 0, 4) || '-dev' === substr($version, -4)) {
return 'dev';
}
@ -155,6 +157,10 @@ class VersionParser
$constraints = empty($match[1]) ? '*' : $match[1];
}
if (preg_match('{^(dev-[^,\s@]+?|[^,\s@]+?\.x-dev)#[a-f0-9]+$}i', $constraints, $match)) {
$constraints = $match[1];
}
$constraints = preg_split('{\s*,\s*}', trim($constraints));
if (count($constraints) > 1) {

View File

@ -0,0 +1,21 @@
--TEST--
Installs a dev package forcing it's reference
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{
"name": "a/a", "version": "dev-master",
"source": { "reference": "abc123", "url": "", "type": "git" }
}
]
}
],
"require": {
"a/a": "dev-master#def000"
}
}
--EXPECT--
Installing a/a (dev-master def000)

View File

@ -0,0 +1,28 @@
--TEST--
Updates a dev package forcing it's reference
--COMPOSER--
{
"repositories": [
{
"type": "package",
"package": [
{
"name": "a/a", "version": "dev-master",
"source": { "reference": "abc123", "url": "", "type": "git" }
}
]
}
],
"require": {
"a/a": "dev-master#def000"
}
}
--INSTALLED--
[
{
"name": "a/a", "version": "dev-master",
"source": { "reference": "abc123", "url": "", "type": "git" }
}
]
--EXPECT--
Updating a/a (dev-master abc123) to a/a (dev-master def000)

View File

@ -112,6 +112,21 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
$this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0@dev'));
}
public function testParseConstraintsIgnoresReferenceOnDevVersion()
{
$parser = new VersionParser;
$this->assertSame((string) new VersionConstraint('=', '1.0.9999999.9999999-dev'), (string) $parser->parseConstraints('1.0.x-dev#abcd123'));
}
/**
* @expectedException UnexpectedValueException
*/
public function testParseConstraintsFailsOnBadReference()
{
$parser = new VersionParser;
$this->assertSame((string) new VersionConstraint('=', '1.0.0.0'), (string) $parser->parseConstraints('1.0#abcd123'));
}
/**
* @dataProvider simpleConstraints
*/
@ -213,6 +228,7 @@ class VersionParserTest extends \PHPUnit_Framework_TestCase
return array(
array('stable', '1.0'),
array('dev', 'v2.0.x-dev'),
array('dev', 'v2.0.x-dev#abc123'),
array('RC', '3.0-RC2'),
array('dev', 'dev-master'),
array('dev', '3.1.2-dev'),