1
0
Fork 0

Merge pull request #6475 from NamelessCoder/featurebranches

Add support for feature-branches setting
pull/6378/merge
Jordi Boggiano 2017-06-15 15:49:10 +02:00 committed by GitHub
commit cc9234562d
4 changed files with 101 additions and 1 deletions

View File

@ -893,4 +893,47 @@ Then "composer show -s" will give you `versions : * dev-latest-testing`.
Optional.
### feature-branches
If your feature branch names are other than the default names:
* master
* trunk
* default
* develop
You can use this setting to declare the list of branch names which should be considered
feature branches in your package. For example, if you do not use `develop` but rather use
a name like `development` and have no `trunk` or `default` branches, you can change this
setting to:
```json
{
"feature-branches": ["master", "development"]
}
```
And Composer will consider those two branches (plus any numeric branches) as your only
feature branches. This allows Composer to recognise when you create a new branch based
on such a non-standard named feature branch, that your new branch is based on that "version".
In practice this allows you to have `my/package:dev-oddname` in your dependency
section and still have `my/package:dev-branchofoddname` be recognised as compatible.
Without overriding this configuration option, Composer would instead demand that you
explicitly install `my/package:dev-oddname` or change the dependency to the explicit
name `my/package:dev-branchofoddname`.
Particularly useful when combined with local repositories of type `path` where Composer
will read the checked-out branch name to determine the version. Without this setting, if you
used non-standard names, Composer would reject creating a symlink to the path and will
instead force `git clone`. With the setting, symlink creation is allowed when your local
branches are based on such non-standard named feature branches.
Note that this is only the case when your branch names are other than the above mentioned
four default branch names. When you use default names you never need to declare this list -
Composer will then detect your feature branches based on the default set of names.
Optional.
← [Command-line interface](03-cli.md) | [Repositories](05-repositories.md) →

View File

@ -488,6 +488,13 @@
}
}
},
"feature-branches": {
"type": ["array"],
"description": "A set of string or regex patterns for non-numeric branch names that will be handled as feature branches. Overrides default feature branch names \"master\", \"trunk\", \"default\" and \"develop\" when declared.",
"items": {
"type": "string"
}
},
"non-feature-branches": {
"type": ["array"],
"description": "A set of string or regex patterns for non-numeric branch names that will not be handled as feature branches.",

View File

@ -211,6 +211,11 @@ class VersionGuesser
$nonFeatureBranches = implode('|', $packageConfig['non-feature-branches']);
}
$featureBranches = 'master|trunk|default|develop';
if (!empty($packageConfig['feature-branches'])) {
$featureBranches = implode('|', $packageConfig['feature-branches']);
}
foreach ($branches as $candidate) {
// return directly, if branch is configured to be non-feature branch
if ($candidate === $branch && preg_match('{^(' . $nonFeatureBranches . ')$}', $candidate)) {
@ -218,7 +223,7 @@ class VersionGuesser
}
// do not compare against other feature branches
if ($candidate === $branch || !preg_match('{^(master|trunk|default|develop|\d+\..+)$}', $candidate, $match)) {
if ($candidate === $branch || !preg_match('{^(' . $featureBranches . '|\d+\..+)$}', $candidate, $match)) {
continue;
}

View File

@ -126,6 +126,51 @@ class VersionGuesserTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($commitHash, $versionArray['commit']);
}
public function testGuessVersionReadsAndRespectsFeatureBranchesConfigurationForArbitraryNaming()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
$anotherCommitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';
$executor = $this->getMockBuilder('\\Composer\\Util\\ProcessExecutor')
->setMethods(array('execute'))
->disableArgumentCloning()
->disableOriginalConstructor()
->getMock()
;
$self = $this;
$executor
->expects($this->at(0))
->method('execute')
->willReturnCallback(function ($command, &$output) use ($self, $commitHash, $anotherCommitHash) {
$self->assertEquals('git branch --no-color --no-abbrev -v', $command);
$output = " arbitrary $commitHash Commit message\n* current $anotherCommitHash Another message\n";
return 0;
})
;
$executor
->expects($this->at(1))
->method('execute')
->willReturnCallback(function ($command, &$output, $path) use ($self, $anotherCommitHash) {
$self->assertEquals('git rev-list arbitrary..current', $command);
$output = "$anotherCommitHash\n";
return 0;
})
;
$config = new Config;
$config->merge(array('repositories' => array('packagist' => false)));
$guesser = new VersionGuesser($config, $executor, new VersionParser());
$versionArray = $guesser->guessVersion(array('version' => 'self.version', 'feature-branches' => array('arbitrary')), 'dummy/path');
$this->assertEquals("dev-arbitrary", $versionArray['version']);
$this->assertEquals($anotherCommitHash, $versionArray['commit']);
}
public function testDetachedHeadBecomesDevHash()
{
$commitHash = '03a15d220da53c52eddd5f32ffca64a7b3801bea';