Add a DSL for selecting base commits
Summary:
New optional mode. If you set 'base' in local, project or global config or pass '--base' to 'arc diff' or 'arc which', it switches to DSL mode.
In DSL mode, lists of rules from args, local, project and global config are resolved, in that order. Rules can manipulate the rule machine or resolve into actual commits. Provides support for some 'arc' rules (mostly machine manipulation) and 'git' rules (symbolic ref and merge-base).
Test Plan:
Ran unit tests. Also:
```$ arc which --show-base --base 'arc:prompt'
Against which commit? HEAD
HEAD
$ arc which --show-base --base 'git:HEAD'
HEAD
$ arc which --show-base --base 'git:fake'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc which --show-base --base 'git:origin/master'
origin/master
$ arc which --show-base --base 'git:upstream'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc which --show-base --base 'literal:derp'
derp
$ arc which --show-base --base 'arc:halt'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc set-config --local base git:origin/master
Set key 'base' = 'git:origin/master' in local config.
$ arc which --show-base
origin/master
$ arc which --show-base --base 'git:HEAD^'
HEAD^
$ arc which --show-base --base 'arc:yield, git:HEAD^'
origin/master
$ arc which --show-base --base 'arc:global, git:HEAD^'
HEAD^
$ arc which --show-base --base 'arc:global, git:merge-base(origin/master)'
3f4f8992fba8d1f142974da36a82bae900e247c0```
Reviewers: dschleimer, vrana
Reviewed By: dschleimer
CC: aran
Maniphest Tasks: T1233
Differential Revision: https://secure.phabricator.com/D2748
2012-06-15 14:01:28 -07:00
|
|
|
<?php
|
|
|
|
|
2012-09-07 15:16:39 -07:00
|
|
|
final class ArcanistBaseCommitParserTestCase extends ArcanistTestCase {
|
Add a DSL for selecting base commits
Summary:
New optional mode. If you set 'base' in local, project or global config or pass '--base' to 'arc diff' or 'arc which', it switches to DSL mode.
In DSL mode, lists of rules from args, local, project and global config are resolved, in that order. Rules can manipulate the rule machine or resolve into actual commits. Provides support for some 'arc' rules (mostly machine manipulation) and 'git' rules (symbolic ref and merge-base).
Test Plan:
Ran unit tests. Also:
```$ arc which --show-base --base 'arc:prompt'
Against which commit? HEAD
HEAD
$ arc which --show-base --base 'git:HEAD'
HEAD
$ arc which --show-base --base 'git:fake'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc which --show-base --base 'git:origin/master'
origin/master
$ arc which --show-base --base 'git:upstream'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc which --show-base --base 'literal:derp'
derp
$ arc which --show-base --base 'arc:halt'
Usage Exception: None of the rules in your 'base' configuration matched a valid commit. Adjust rules or specify which commit you want to use explicitly.
$ arc set-config --local base git:origin/master
Set key 'base' = 'git:origin/master' in local config.
$ arc which --show-base
origin/master
$ arc which --show-base --base 'git:HEAD^'
HEAD^
$ arc which --show-base --base 'arc:yield, git:HEAD^'
origin/master
$ arc which --show-base --base 'arc:global, git:HEAD^'
HEAD^
$ arc which --show-base --base 'arc:global, git:merge-base(origin/master)'
3f4f8992fba8d1f142974da36a82bae900e247c0```
Reviewers: dschleimer, vrana
Reviewed By: dschleimer
CC: aran
Maniphest Tasks: T1233
Differential Revision: https://secure.phabricator.com/D2748
2012-06-15 14:01:28 -07:00
|
|
|
|
|
|
|
public function testBasics() {
|
|
|
|
|
|
|
|
// Verify that the very basics of base commit resolution work.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Empty Rules',
|
|
|
|
null,
|
|
|
|
array(
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Literal',
|
|
|
|
'xyz',
|
|
|
|
array(
|
|
|
|
'args' => 'literal:xyz',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testResolutionOrder() {
|
|
|
|
|
|
|
|
// Rules should be resolved in order: args, local, project, global. These
|
|
|
|
// test cases intentionally scramble argument order to test that resolution
|
|
|
|
// order is independent of argument order.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Order: Args',
|
|
|
|
'y',
|
|
|
|
array(
|
|
|
|
'local' => 'literal:n',
|
|
|
|
'project' => 'literal:n',
|
|
|
|
'args' => 'literal:y',
|
|
|
|
'global' => 'literal:n',
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Order: Local',
|
|
|
|
'y',
|
|
|
|
array(
|
|
|
|
'project' => 'literal:n',
|
|
|
|
'local' => 'literal:y',
|
|
|
|
'global' => 'literal:n',
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Order: Project',
|
|
|
|
'y',
|
|
|
|
array(
|
|
|
|
'project' => 'literal:y',
|
|
|
|
'global' => 'literal:n',
|
|
|
|
));
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Order: Global',
|
|
|
|
'y',
|
|
|
|
array(
|
|
|
|
'global' => 'literal:y',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testHalt() {
|
|
|
|
|
|
|
|
// 'arc:halt' should halt all processing.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Halt',
|
|
|
|
null,
|
|
|
|
array(
|
|
|
|
'args' => 'arc:halt',
|
|
|
|
'local' => 'literal:xyz',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testYield() {
|
|
|
|
|
|
|
|
// 'arc:yield' should yield to other rulesets.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Yield',
|
|
|
|
'xyz',
|
|
|
|
array(
|
|
|
|
'args' => 'arc:yield, literal:abc',
|
|
|
|
'local' => 'literal:xyz',
|
|
|
|
));
|
|
|
|
|
|
|
|
// This one should return to 'args' after exhausting 'local'.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Yield + Return',
|
|
|
|
'abc',
|
|
|
|
array(
|
|
|
|
'args' => 'arc:yield, literal:abc',
|
|
|
|
'local' => 'arc:skip',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testJump() {
|
|
|
|
|
|
|
|
// This should resolve to 'abc' without hitting any of the halts.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Jump',
|
|
|
|
'abc',
|
|
|
|
array(
|
|
|
|
'args' => 'arc:project, arc:halt',
|
|
|
|
'local' => 'literal:abc',
|
|
|
|
'project' => 'arc:global, arc:halt',
|
|
|
|
'global' => 'arc:local, arc:halt',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testJumpReturn() {
|
|
|
|
|
|
|
|
// After jumping to project, we should return to 'args'.
|
|
|
|
|
|
|
|
$this->assertCommit(
|
|
|
|
'Jump Return',
|
|
|
|
'xyz',
|
|
|
|
array(
|
|
|
|
'args' => 'arc:project, literal:xyz',
|
|
|
|
'local' => 'arc:halt',
|
|
|
|
'project' => '',
|
|
|
|
'global' => 'arc:halt',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
private function assertCommit($desc, $commit, $rules) {
|
|
|
|
$parser = $this->buildParser();
|
|
|
|
$result = $parser->resolveBaseCommit($rules);
|
|
|
|
$this->assertEqual($commit, $result, $desc);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private function buildParser() {
|
|
|
|
// TODO: This is a little hacky beacuse we're using the Arcanist repository
|
|
|
|
// itself to execute tests with, but it should be OK until we get proper
|
|
|
|
// isolation for repository-oriented test cases.
|
|
|
|
|
|
|
|
$root = dirname(phutil_get_library_root('arcanist'));
|
|
|
|
$copy = ArcanistWorkingCopyIdentity::newFromPath($root);
|
|
|
|
$repo = ArcanistRepositoryAPI::newAPIFromWorkingCopyIdentity($copy);
|
|
|
|
|
|
|
|
return new ArcanistBaseCommitParser($repo);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|