mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-25 08:12:40 +01:00
Add a "RevisionSymbolRef", revision commit messages, and make "--explore" recursive
Summary: Ref T13490. - Support resolution of revision symbols into revision objects. - Align commit inspection better against commit symbols. - Make "arc inspect --explore" recursively load all object hardpoints. - Add a "commit message" hardpoint to "RevisionRef". Test Plan: Used "arc inspect" to resolve commits and revisions. Used "--explore" to see the whole tree. Maniphest Tasks: T13490 Differential Revision: https://secure.phabricator.com/D21091
This commit is contained in:
parent
4cc05c377d
commit
1f18f25fa5
14 changed files with 286 additions and 85 deletions
|
@ -102,10 +102,9 @@ phutil_register_library_map(array(
|
||||||
'ArcanistCommentSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCommentSpacingXHPASTLinterRule.php',
|
'ArcanistCommentSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCommentSpacingXHPASTLinterRule.php',
|
||||||
'ArcanistCommentStyleXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCommentStyleXHPASTLinterRule.php',
|
'ArcanistCommentStyleXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistCommentStyleXHPASTLinterRule.php',
|
||||||
'ArcanistCommentStyleXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistCommentStyleXHPASTLinterRuleTestCase.php',
|
'ArcanistCommentStyleXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistCommentStyleXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistCommitRef' => 'ref/ArcanistCommitRef.php',
|
'ArcanistCommitRef' => 'ref/commit/ArcanistCommitRef.php',
|
||||||
'ArcanistCommitRefInspector' => 'inspector/ArcanistCommitRefInspector.php',
|
'ArcanistCommitSymbolRef' => 'ref/commit/ArcanistCommitSymbolRef.php',
|
||||||
'ArcanistCommitSymbolRef' => 'ref/commitsymbol/ArcanistCommitSymbolRef.php',
|
'ArcanistCommitSymbolRefInspector' => 'ref/commit/ArcanistCommitSymbolRefInspector.php',
|
||||||
'ArcanistCommitSymbolRefInspector' => 'ref/commitsymbol/ArcanistCommitSymbolRefInspector.php',
|
|
||||||
'ArcanistCommitUpstreamHardpointQuery' => 'query/ArcanistCommitUpstreamHardpointQuery.php',
|
'ArcanistCommitUpstreamHardpointQuery' => 'query/ArcanistCommitUpstreamHardpointQuery.php',
|
||||||
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
|
'ArcanistCommitWorkflow' => 'workflow/ArcanistCommitWorkflow.php',
|
||||||
'ArcanistCompilerLintRenderer' => 'lint/renderer/ArcanistCompilerLintRenderer.php',
|
'ArcanistCompilerLintRenderer' => 'lint/renderer/ArcanistCompilerLintRenderer.php',
|
||||||
|
@ -208,7 +207,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistGetConfigWorkflow' => 'workflow/ArcanistGetConfigWorkflow.php',
|
'ArcanistGetConfigWorkflow' => 'workflow/ArcanistGetConfigWorkflow.php',
|
||||||
'ArcanistGitAPI' => 'repository/api/ArcanistGitAPI.php',
|
'ArcanistGitAPI' => 'repository/api/ArcanistGitAPI.php',
|
||||||
'ArcanistGitCommitMessageHardpointQuery' => 'query/ArcanistGitCommitMessageHardpointQuery.php',
|
'ArcanistGitCommitMessageHardpointQuery' => 'query/ArcanistGitCommitMessageHardpointQuery.php',
|
||||||
'ArcanistGitCommitSymbolCommitHardpointQuery' => 'ref/commitsymbol/ArcanistGitCommitSymbolCommitHardpointQuery.php',
|
'ArcanistGitCommitSymbolCommitHardpointQuery' => 'ref/commit/ArcanistGitCommitSymbolCommitHardpointQuery.php',
|
||||||
'ArcanistGitLandEngine' => 'land/ArcanistGitLandEngine.php',
|
'ArcanistGitLandEngine' => 'land/ArcanistGitLandEngine.php',
|
||||||
'ArcanistGitUpstreamPath' => 'repository/api/ArcanistGitUpstreamPath.php',
|
'ArcanistGitUpstreamPath' => 'repository/api/ArcanistGitUpstreamPath.php',
|
||||||
'ArcanistGitWorkingCopy' => 'workingcopy/ArcanistGitWorkingCopy.php',
|
'ArcanistGitWorkingCopy' => 'workingcopy/ArcanistGitWorkingCopy.php',
|
||||||
|
@ -398,8 +397,12 @@ phutil_register_library_map(array(
|
||||||
'ArcanistReusedIteratorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistReusedIteratorXHPASTLinterRule.php',
|
'ArcanistReusedIteratorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistReusedIteratorXHPASTLinterRule.php',
|
||||||
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistReusedIteratorXHPASTLinterRuleTestCase.php',
|
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistReusedIteratorXHPASTLinterRuleTestCase.php',
|
||||||
'ArcanistRevertWorkflow' => 'workflow/ArcanistRevertWorkflow.php',
|
'ArcanistRevertWorkflow' => 'workflow/ArcanistRevertWorkflow.php',
|
||||||
'ArcanistRevisionRef' => 'ref/ArcanistRevisionRef.php',
|
'ArcanistRevisionCommitMessageHardpointQuery' => 'ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php',
|
||||||
|
'ArcanistRevisionRef' => 'ref/revision/ArcanistRevisionRef.php',
|
||||||
'ArcanistRevisionRefSource' => 'ref/ArcanistRevisionRefSource.php',
|
'ArcanistRevisionRefSource' => 'ref/ArcanistRevisionRefSource.php',
|
||||||
|
'ArcanistRevisionSymbolHardpointQuery' => 'ref/revision/ArcanistRevisionSymbolHardpointQuery.php',
|
||||||
|
'ArcanistRevisionSymbolRef' => 'ref/revision/ArcanistRevisionSymbolRef.php',
|
||||||
|
'ArcanistRevisionSymbolRefInspector' => 'ref/revision/ArcanistRevisionSymbolRefInspector.php',
|
||||||
'ArcanistRuboCopLinter' => 'lint/linter/ArcanistRuboCopLinter.php',
|
'ArcanistRuboCopLinter' => 'lint/linter/ArcanistRuboCopLinter.php',
|
||||||
'ArcanistRuboCopLinterTestCase' => 'lint/linter/__tests__/ArcanistRuboCopLinterTestCase.php',
|
'ArcanistRuboCopLinterTestCase' => 'lint/linter/__tests__/ArcanistRuboCopLinterTestCase.php',
|
||||||
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
|
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
|
||||||
|
@ -432,6 +435,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
|
'ArcanistSubversionAPI' => 'repository/api/ArcanistSubversionAPI.php',
|
||||||
'ArcanistSubversionWorkingCopy' => 'workingcopy/ArcanistSubversionWorkingCopy.php',
|
'ArcanistSubversionWorkingCopy' => 'workingcopy/ArcanistSubversionWorkingCopy.php',
|
||||||
'ArcanistSummaryLintRenderer' => 'lint/renderer/ArcanistSummaryLintRenderer.php',
|
'ArcanistSummaryLintRenderer' => 'lint/renderer/ArcanistSummaryLintRenderer.php',
|
||||||
|
'ArcanistSymbolRef' => 'ref/symbol/ArcanistSymbolRef.php',
|
||||||
'ArcanistSyntaxErrorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSyntaxErrorXHPASTLinterRule.php',
|
'ArcanistSyntaxErrorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSyntaxErrorXHPASTLinterRule.php',
|
||||||
'ArcanistSystemConfigurationSource' => 'config/source/ArcanistSystemConfigurationSource.php',
|
'ArcanistSystemConfigurationSource' => 'config/source/ArcanistSystemConfigurationSource.php',
|
||||||
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
|
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
|
||||||
|
@ -1068,8 +1072,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistCommentStyleXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistCommentStyleXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistCommentStyleXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistCommentStyleXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistCommitRef' => 'ArcanistRef',
|
'ArcanistCommitRef' => 'ArcanistRef',
|
||||||
'ArcanistCommitRefInspector' => 'ArcanistRefInspector',
|
'ArcanistCommitSymbolRef' => 'ArcanistSymbolRef',
|
||||||
'ArcanistCommitSymbolRef' => 'ArcanistRef',
|
|
||||||
'ArcanistCommitSymbolRefInspector' => 'ArcanistRefInspector',
|
'ArcanistCommitSymbolRefInspector' => 'ArcanistRefInspector',
|
||||||
'ArcanistCommitUpstreamHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
|
'ArcanistCommitUpstreamHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
|
||||||
'ArcanistCommitWorkflow' => 'ArcanistWorkflow',
|
'ArcanistCommitWorkflow' => 'ArcanistWorkflow',
|
||||||
|
@ -1363,8 +1366,12 @@ phutil_register_library_map(array(
|
||||||
'ArcanistReusedIteratorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistReusedIteratorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||||
'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
|
'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
|
||||||
|
'ArcanistRevisionCommitMessageHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
|
||||||
'ArcanistRevisionRef' => 'ArcanistRef',
|
'ArcanistRevisionRef' => 'ArcanistRef',
|
||||||
'ArcanistRevisionRefSource' => 'Phobject',
|
'ArcanistRevisionRefSource' => 'Phobject',
|
||||||
|
'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
|
||||||
|
'ArcanistRevisionSymbolRef' => 'ArcanistSymbolRef',
|
||||||
|
'ArcanistRevisionSymbolRefInspector' => 'ArcanistRefInspector',
|
||||||
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
|
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
|
||||||
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
|
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
|
||||||
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
|
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
|
||||||
|
@ -1396,6 +1403,7 @@ phutil_register_library_map(array(
|
||||||
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
|
'ArcanistSubversionAPI' => 'ArcanistRepositoryAPI',
|
||||||
'ArcanistSubversionWorkingCopy' => 'ArcanistWorkingCopy',
|
'ArcanistSubversionWorkingCopy' => 'ArcanistWorkingCopy',
|
||||||
'ArcanistSummaryLintRenderer' => 'ArcanistLintRenderer',
|
'ArcanistSummaryLintRenderer' => 'ArcanistLintRenderer',
|
||||||
|
'ArcanistSymbolRef' => 'ArcanistRef',
|
||||||
'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||||
'ArcanistSystemConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
'ArcanistSystemConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
||||||
'ArcanistTasksWorkflow' => 'ArcanistWorkflow',
|
'ArcanistTasksWorkflow' => 'ArcanistWorkflow',
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ArcanistCommitRefInspector
|
|
||||||
extends ArcanistRefInspector {
|
|
||||||
|
|
||||||
public function getInspectFunctionName() {
|
|
||||||
return 'commit';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function newInspectRef(array $argv) {
|
|
||||||
if (count($argv) !== 1) {
|
|
||||||
throw new PhutilArgumentUsageException(
|
|
||||||
pht(
|
|
||||||
'Expected exactly one argument to "commit(...)" with a '.
|
|
||||||
'commit hash.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return id(new ArcanistCommitRef())
|
|
||||||
->setCommitHash($argv[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
10
src/ref/commit/ArcanistCommitSymbolRef.php
Normal file
10
src/ref/commit/ArcanistCommitSymbolRef.php
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistCommitSymbolRef
|
||||||
|
extends ArcanistSymbolRef {
|
||||||
|
|
||||||
|
public function getRefDisplayName() {
|
||||||
|
return pht('Commit Symbol "%s"', $this->getSymbol());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,14 +4,14 @@ final class ArcanistCommitSymbolRefInspector
|
||||||
extends ArcanistRefInspector {
|
extends ArcanistRefInspector {
|
||||||
|
|
||||||
public function getInspectFunctionName() {
|
public function getInspectFunctionName() {
|
||||||
return 'symbol';
|
return 'commit';
|
||||||
}
|
}
|
||||||
|
|
||||||
public function newInspectRef(array $argv) {
|
public function newInspectRef(array $argv) {
|
||||||
if (count($argv) !== 1) {
|
if (count($argv) !== 1) {
|
||||||
throw new PhutilArgumentUsageException(
|
throw new PhutilArgumentUsageException(
|
||||||
pht(
|
pht(
|
||||||
'Expected exactly one argument to "symbol(...)" with a '.
|
'Expected exactly one argument to "commit(...)" with a '.
|
||||||
'commit symbol.'));
|
'commit symbol.'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ final class ArcanistGitCommitSymbolCommitHardpointQuery
|
||||||
|
|
||||||
public function getHardpoints() {
|
public function getHardpoints() {
|
||||||
return array(
|
return array(
|
||||||
ArcanistCommitSymbolRef::HARDPOINT_COMMIT,
|
ArcanistCommitSymbolRef::HARDPOINT_OBJECT,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ArcanistCommitSymbolRef
|
|
||||||
extends ArcanistRef {
|
|
||||||
|
|
||||||
private $symbol;
|
|
||||||
|
|
||||||
const HARDPOINT_COMMIT = 'ref.commit-symbol';
|
|
||||||
|
|
||||||
public function getRefDisplayName() {
|
|
||||||
return pht('Commit Symbol "%s"', $this->getSymbol());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function newHardpoints() {
|
|
||||||
return array(
|
|
||||||
$this->newHardpoint(self::HARDPOINT_COMMIT),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setSymbol($symbol) {
|
|
||||||
$this->symbol = $symbol;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSymbol() {
|
|
||||||
return $this->symbol;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function attachCommit(ArcanistCommitRef $commit) {
|
|
||||||
return $this->attachHardpoint(self::HARDPOINT_COMMIT, $commit);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getCommit() {
|
|
||||||
return $this->getHardpoint(self::HARDPOINT_COMMIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistRevisionCommitMessageHardpointQuery
|
||||||
|
extends ArcanistWorkflowHardpointQuery {
|
||||||
|
|
||||||
|
public function getHardpoints() {
|
||||||
|
return array(
|
||||||
|
ArcanistRevisionRef::HARDPOINT_COMMITMESSAGE,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function canLoadRef(ArcanistRef $ref) {
|
||||||
|
return ($ref instanceof ArcanistRevisionRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHardpoint(array $refs, $hardpoint) {
|
||||||
|
$api = $this->getRepositoryAPI();
|
||||||
|
|
||||||
|
// NOTE: This is not efficient, but no bulk API exists at time of
|
||||||
|
// writing and no callers bulk-load this data.
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($refs as $key => $ref) {
|
||||||
|
$message = (yield $this->yieldConduit(
|
||||||
|
'differential.getcommitmessage',
|
||||||
|
array(
|
||||||
|
'revision_id' => $ref->getID(),
|
||||||
|
'edit' => false,
|
||||||
|
)));
|
||||||
|
|
||||||
|
$results[$key] = $message;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield $this->yieldMap($results);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,6 +3,8 @@
|
||||||
final class ArcanistRevisionRef
|
final class ArcanistRevisionRef
|
||||||
extends ArcanistRef {
|
extends ArcanistRef {
|
||||||
|
|
||||||
|
const HARDPOINT_COMMITMESSAGE = 'ref.revision.commitmessage';
|
||||||
|
|
||||||
private $parameters;
|
private $parameters;
|
||||||
private $sources = array();
|
private $sources = array();
|
||||||
|
|
||||||
|
@ -10,6 +12,12 @@ final class ArcanistRevisionRef
|
||||||
return pht('Revision %s', $this->getMonogram());
|
return pht('Revision %s', $this->getMonogram());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function newHardpoints() {
|
||||||
|
return array(
|
||||||
|
$this->newHardpoint(self::HARDPOINT_COMMITMESSAGE),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public static function newFromConduit(array $dict) {
|
public static function newFromConduit(array $dict) {
|
||||||
$ref = new self();
|
$ref = new self();
|
||||||
$ref->parameters = $dict;
|
$ref->parameters = $dict;
|
||||||
|
@ -45,7 +53,7 @@ final class ArcanistRevisionRef
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getID() {
|
public function getID() {
|
||||||
return idx($this->parameters, 'id');
|
return (int)idx($this->parameters, 'id');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getPHID() {
|
public function getPHID() {
|
40
src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
Normal file
40
src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistRevisionSymbolHardpointQuery
|
||||||
|
extends ArcanistWorkflowHardpointQuery {
|
||||||
|
|
||||||
|
public function getHardpoints() {
|
||||||
|
return array(
|
||||||
|
ArcanistRevisionSymbolRef::HARDPOINT_OBJECT,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function canLoadRef(ArcanistRef $ref) {
|
||||||
|
return ($ref instanceof ArcanistRevisionSymbolRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function loadHardpoint(array $refs, $hardpoint) {
|
||||||
|
$id_map = mpull($refs, 'getSymbol');
|
||||||
|
$id_set = array_fuse($id_map);
|
||||||
|
|
||||||
|
$revisions = (yield $this->yieldConduit(
|
||||||
|
'differential.query',
|
||||||
|
array(
|
||||||
|
'ids' => $id_set,
|
||||||
|
)));
|
||||||
|
|
||||||
|
$refs = array();
|
||||||
|
foreach ($revisions as $revision) {
|
||||||
|
$ref = ArcanistRevisionRef::newFromConduit($revision);
|
||||||
|
$refs[$ref->getID()] = $ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = array();
|
||||||
|
foreach ($id_map as $key => $id) {
|
||||||
|
$results[$key] = idx($refs, $id);
|
||||||
|
}
|
||||||
|
|
||||||
|
yield $this->yieldMap($results);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
25
src/ref/revision/ArcanistRevisionSymbolRef.php
Normal file
25
src/ref/revision/ArcanistRevisionSymbolRef.php
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistRevisionSymbolRef
|
||||||
|
extends ArcanistSymbolRef {
|
||||||
|
|
||||||
|
public function getRefDisplayName() {
|
||||||
|
return pht('Revision Symbol "%s"', $this->getSymbol());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function resolveSymbol($symbol) {
|
||||||
|
$matches = null;
|
||||||
|
|
||||||
|
if (!preg_match('/^[Dd]?([1-9]\d*)\z/', $symbol, $matches)) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'The format of revision symbol "%s" is unrecognized. '.
|
||||||
|
'Expected a revision monogram like "D123", or a '.
|
||||||
|
'revision ID like "123".',
|
||||||
|
$symbol));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int)$matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/ref/revision/ArcanistRevisionSymbolRefInspector.php
Normal file
22
src/ref/revision/ArcanistRevisionSymbolRefInspector.php
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class ArcanistRevisionSymbolRefInspector
|
||||||
|
extends ArcanistRefInspector {
|
||||||
|
|
||||||
|
public function getInspectFunctionName() {
|
||||||
|
return 'revision';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function newInspectRef(array $argv) {
|
||||||
|
if (count($argv) !== 1) {
|
||||||
|
throw new PhutilArgumentUsageException(
|
||||||
|
pht(
|
||||||
|
'Expected exactly one argument to "revision(...)" with a '.
|
||||||
|
'revision symbol.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
return id(new ArcanistRevisionSymbolRef())
|
||||||
|
->setSymbol($argv[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
src/ref/symbol/ArcanistSymbolRef.php
Normal file
39
src/ref/symbol/ArcanistSymbolRef.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
abstract class ArcanistSymbolRef
|
||||||
|
extends ArcanistRef {
|
||||||
|
|
||||||
|
private $symbol;
|
||||||
|
|
||||||
|
const HARDPOINT_OBJECT = 'ref.symbol.object';
|
||||||
|
|
||||||
|
protected function newHardpoints() {
|
||||||
|
return array(
|
||||||
|
$this->newHardpoint(self::HARDPOINT_OBJECT),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function setSymbol($symbol) {
|
||||||
|
$symbol = $this->resolveSymbol($symbol);
|
||||||
|
|
||||||
|
$this->symbol = $symbol;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getSymbol() {
|
||||||
|
return $this->symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function attachObject(ArcanistRef $object) {
|
||||||
|
return $this->attachHardpoint(self::HARDPOINT_OBJECT, $object);
|
||||||
|
}
|
||||||
|
|
||||||
|
final public function getObject() {
|
||||||
|
return $this->getHardpoint(self::HARDPOINT_OBJECT);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function resolveSymbol($symbol) {
|
||||||
|
return $symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -51,7 +51,6 @@ EOTEXT
|
||||||
}
|
}
|
||||||
|
|
||||||
$all_refs = array();
|
$all_refs = array();
|
||||||
$ref_lists = array();
|
|
||||||
foreach ($objects as $description) {
|
foreach ($objects as $description) {
|
||||||
$matches = null;
|
$matches = null;
|
||||||
$pattern = '/^([\w-]+)(?:\(([^)]+)\))?\z/';
|
$pattern = '/^([\w-]+)(?:\(([^)]+)\))?\z/';
|
||||||
|
@ -84,23 +83,11 @@ EOTEXT
|
||||||
|
|
||||||
$ref = $inspector->newInspectRef($arguments);
|
$ref = $inspector->newInspectRef($arguments);
|
||||||
|
|
||||||
$ref_lists[get_class($ref)][] = $ref;
|
|
||||||
$all_refs[] = $ref;
|
$all_refs[] = $ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($is_explore) {
|
if ($is_explore) {
|
||||||
foreach ($ref_lists as $ref_class => $refs) {
|
$this->exploreRefs($all_refs);
|
||||||
$ref = head($refs);
|
|
||||||
|
|
||||||
$hardpoint_list = $ref->getHardpointList();
|
|
||||||
$hardpoints = $hardpoint_list->getHardpoints();
|
|
||||||
|
|
||||||
if ($hardpoints) {
|
|
||||||
$hardpoint_keys = mpull($hardpoints, 'getHardpointKey');
|
|
||||||
|
|
||||||
$this->loadHardpoints($refs, $hardpoint_keys);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$list = array();
|
$list = array();
|
||||||
|
@ -214,4 +201,88 @@ EOTEXT
|
||||||
return $out;
|
return $out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function exploreRefs(array $refs) {
|
||||||
|
$seen = array();
|
||||||
|
$look = $refs;
|
||||||
|
|
||||||
|
while ($look) {
|
||||||
|
$ref_map = $this->getRefsByClass($look);
|
||||||
|
$look = array();
|
||||||
|
|
||||||
|
$children = $this->inspectHardpoints($ref_map);
|
||||||
|
|
||||||
|
foreach ($children as $child) {
|
||||||
|
$hash = spl_object_hash($child);
|
||||||
|
|
||||||
|
if (isset($seen[$hash])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$seen[$hash] = true;
|
||||||
|
$look[] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRefsByClass(array $refs) {
|
||||||
|
$ref_lists = array();
|
||||||
|
foreach ($refs as $ref) {
|
||||||
|
$ref_lists[get_class($ref)][] = $ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($ref_lists as $ref_class => $refs) {
|
||||||
|
$typical_ref = head($refs);
|
||||||
|
|
||||||
|
$hardpoint_list = $typical_ref->getHardpointList();
|
||||||
|
$hardpoints = $hardpoint_list->getHardpoints();
|
||||||
|
|
||||||
|
if (!$hardpoints) {
|
||||||
|
unset($ref_lists[$ref_class]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$hardpoint_keys = mpull($hardpoints, 'getHardpointKey');
|
||||||
|
|
||||||
|
$ref_lists[$ref_class] = array(
|
||||||
|
'keys' => $hardpoint_keys,
|
||||||
|
'refs' => $refs,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ref_lists;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function inspectHardpoints(array $ref_lists) {
|
||||||
|
foreach ($ref_lists as $ref_class => $spec) {
|
||||||
|
$refs = $spec['refs'];
|
||||||
|
$keys = $spec['keys'];
|
||||||
|
|
||||||
|
$this->loadHardpoints($refs, $keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
$child_refs = array();
|
||||||
|
|
||||||
|
foreach ($ref_lists as $ref_class => $spec) {
|
||||||
|
$refs = $spec['refs'];
|
||||||
|
$keys = $spec['keys'];
|
||||||
|
foreach ($refs as $ref) {
|
||||||
|
foreach ($keys as $key) {
|
||||||
|
$value = $ref->getHardpoint($key);
|
||||||
|
|
||||||
|
if (!is_array($value)) {
|
||||||
|
$value = array($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($value as $child) {
|
||||||
|
if ($child instanceof ArcanistRef) {
|
||||||
|
$child_refs[] = $child;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $child_refs;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue