Page MenuHomePhabricator

D21079.diff
No OneTemporary

D21079.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -213,6 +213,7 @@
'ArcanistGitRevisionHardpointLoader' => 'loader/ArcanistGitRevisionHardpointLoader.php',
'ArcanistGitUpstreamPath' => 'repository/api/ArcanistGitUpstreamPath.php',
'ArcanistGitWorkingCopy' => 'workingcopy/ArcanistGitWorkingCopy.php',
+ 'ArcanistGitWorkingCopyRevisionHardpointQuery' => 'query/ArcanistGitWorkingCopyRevisionHardpointQuery.php',
'ArcanistGlobalVariableXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistGlobalVariableXHPASTLinterRule.php',
'ArcanistGlobalVariableXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistGlobalVariableXHPASTLinterRuleTestCase.php',
'ArcanistGoLintLinter' => 'lint/linter/ArcanistGoLintLinter.php',
@@ -320,6 +321,7 @@
'ArcanistMergeConflictLinter' => 'lint/linter/ArcanistMergeConflictLinter.php',
'ArcanistMergeConflictLinterTestCase' => 'lint/linter/__tests__/ArcanistMergeConflictLinterTestCase.php',
'ArcanistMessageRevisionHardpointLoader' => 'loader/ArcanistMessageRevisionHardpointLoader.php',
+ 'ArcanistMessageRevisionHardpointQuery' => 'query/ArcanistMessageRevisionHardpointQuery.php',
'ArcanistMissingArgumentTerminatorException' => 'exception/ArcanistMissingArgumentTerminatorException.php',
'ArcanistMissingLinterException' => 'lint/linter/exception/ArcanistMissingLinterException.php',
'ArcanistModifierOrderingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistModifierOrderingXHPASTLinterRule.php',
@@ -340,6 +342,7 @@
'ArcanistNoParentScopeXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistNoParentScopeXHPASTLinterRuleTestCase.php',
'ArcanistNoURIConduitException' => 'conduit/ArcanistNoURIConduitException.php',
'ArcanistNoneLintRenderer' => 'lint/renderer/ArcanistNoneLintRenderer.php',
+ 'ArcanistObjectListHardpoint' => 'hardpoint/ArcanistObjectListHardpoint.php',
'ArcanistObjectOperatorSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistObjectOperatorSpacingXHPASTLinterRule.php',
'ArcanistObjectOperatorSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistObjectOperatorSpacingXHPASTLinterRuleTestCase.php',
'ArcanistPEP8Linter' => 'lint/linter/ArcanistPEP8Linter.php',
@@ -403,6 +406,7 @@
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistReusedIteratorXHPASTLinterRuleTestCase.php',
'ArcanistRevertWorkflow' => 'workflow/ArcanistRevertWorkflow.php',
'ArcanistRevisionRef' => 'ref/ArcanistRevisionRef.php',
+ 'ArcanistRevisionRefPro' => 'ref/ArcanistRevisionRefPro.php',
'ArcanistRevisionRefSource' => 'ref/ArcanistRevisionRefSource.php',
'ArcanistRuboCopLinter' => 'lint/linter/ArcanistRuboCopLinter.php',
'ArcanistRuboCopLinterTestCase' => 'lint/linter/__tests__/ArcanistRuboCopLinterTestCase.php',
@@ -498,6 +502,7 @@
'ArcanistWildConfigOption' => 'config/option/ArcanistWildConfigOption.php',
'ArcanistWorkflow' => 'workflow/ArcanistWorkflow.php',
'ArcanistWorkflowArgument' => 'toolset/ArcanistWorkflowArgument.php',
+ 'ArcanistWorkflowGitHardpointQuery' => 'query/ArcanistWorkflowGitHardpointQuery.php',
'ArcanistWorkflowHardpointQuery' => 'toolset/query/ArcanistWorkflowHardpointQuery.php',
'ArcanistWorkflowInformation' => 'toolset/ArcanistWorkflowInformation.php',
'ArcanistWorkingCopy' => 'workingcopy/ArcanistWorkingCopy.php',
@@ -506,6 +511,7 @@
'ArcanistWorkingCopyIdentity' => 'workingcopyidentity/ArcanistWorkingCopyIdentity.php',
'ArcanistWorkingCopyPath' => 'workingcopy/ArcanistWorkingCopyPath.php',
'ArcanistWorkingCopyStateRef' => 'ref/ArcanistWorkingCopyStateRef.php',
+ 'ArcanistWorkingCopyStateRefInspector' => 'inspector/ArcanistWorkingCopyStateRefInspector.php',
'ArcanistWorkingCopyStateRefPro' => 'ref/ArcanistWorkingCopyStateRefPro.php',
'ArcanistXHPASTLintNamingHook' => 'lint/linter/xhpast/ArcanistXHPASTLintNamingHook.php',
'ArcanistXHPASTLintNamingHookTestCase' => 'lint/linter/xhpast/__tests__/ArcanistXHPASTLintNamingHookTestCase.php',
@@ -1175,12 +1181,13 @@
'ArcanistGetConfigWorkflow' => 'ArcanistWorkflow',
'ArcanistGitAPI' => 'ArcanistRepositoryAPI',
'ArcanistGitCommitMessageHardpointLoader' => 'ArcanistGitHardpointLoader',
- 'ArcanistGitCommitMessageHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistGitCommitMessageHardpointQuery' => 'ArcanistWorkflowGitHardpointQuery',
'ArcanistGitHardpointLoader' => 'ArcanistHardpointLoader',
'ArcanistGitLandEngine' => 'ArcanistLandEngine',
'ArcanistGitRevisionHardpointLoader' => 'ArcanistGitHardpointLoader',
'ArcanistGitUpstreamPath' => 'Phobject',
'ArcanistGitWorkingCopy' => 'ArcanistWorkingCopy',
+ 'ArcanistGitWorkingCopyRevisionHardpointQuery' => 'ArcanistWorkflowGitHardpointQuery',
'ArcanistGlobalVariableXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistGlobalVariableXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistGoLintLinter' => 'ArcanistExternalLinter',
@@ -1288,6 +1295,7 @@
'ArcanistMergeConflictLinter' => 'ArcanistLinter',
'ArcanistMergeConflictLinterTestCase' => 'ArcanistLinterTestCase',
'ArcanistMessageRevisionHardpointLoader' => 'ArcanistHardpointLoader',
+ 'ArcanistMessageRevisionHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
'ArcanistMissingArgumentTerminatorException' => 'Exception',
'ArcanistMissingLinterException' => 'Exception',
'ArcanistModifierOrderingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -1308,6 +1316,7 @@
'ArcanistNoParentScopeXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistNoURIConduitException' => 'ArcanistConduitException',
'ArcanistNoneLintRenderer' => 'ArcanistLintRenderer',
+ 'ArcanistObjectListHardpoint' => 'ArcanistHardpoint',
'ArcanistObjectOperatorSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistObjectOperatorSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPEP8Linter' => 'ArcanistExternalLinter',
@@ -1371,6 +1380,7 @@
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
'ArcanistRevisionRef' => 'ArcanistRef',
+ 'ArcanistRevisionRefPro' => 'ArcanistRefPro',
'ArcanistRevisionRefSource' => 'Phobject',
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
@@ -1465,6 +1475,7 @@
'ArcanistWildConfigOption' => 'ArcanistConfigOption',
'ArcanistWorkflow' => 'Phobject',
'ArcanistWorkflowArgument' => 'Phobject',
+ 'ArcanistWorkflowGitHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
'ArcanistWorkflowHardpointQuery' => 'ArcanistHardpointQuery',
'ArcanistWorkflowInformation' => 'Phobject',
'ArcanistWorkingCopy' => 'Phobject',
@@ -1473,6 +1484,7 @@
'ArcanistWorkingCopyIdentity' => 'Phobject',
'ArcanistWorkingCopyPath' => 'Phobject',
'ArcanistWorkingCopyStateRef' => 'ArcanistRef',
+ 'ArcanistWorkingCopyStateRefInspector' => 'ArcanistRefInspector',
'ArcanistWorkingCopyStateRefPro' => 'ArcanistRefPro',
'ArcanistXHPASTLintNamingHook' => 'Phobject',
'ArcanistXHPASTLintNamingHookTestCase' => 'PhutilTestCase',
diff --git a/src/hardpoint/ArcanistHardpointObject.php b/src/hardpoint/ArcanistHardpointObject.php
--- a/src/hardpoint/ArcanistHardpointObject.php
+++ b/src/hardpoint/ArcanistHardpointObject.php
@@ -64,6 +64,14 @@
->setHardpointKey($hardpoint_key);
}
+ final protected function newTemplateHardpoint(
+ $hardpoint_key,
+ ArcanistHardpoint $template) {
+
+ return id(clone $template)
+ ->setHardpointKey($hardpoint_key);
+ }
+
final public function getHardpointList() {
if ($this->hardpointList === null) {
diff --git a/src/hardpoint/ArcanistObjectListHardpoint.php b/src/hardpoint/ArcanistObjectListHardpoint.php
new file mode 100644
--- /dev/null
+++ b/src/hardpoint/ArcanistObjectListHardpoint.php
@@ -0,0 +1,25 @@
+<?php
+
+final class ArcanistObjectListHardpoint
+ extends ArcanistHardpoint {
+
+ public function isVectorHardpoint() {
+ return true;
+ }
+
+ public function mergeHardpointValues(
+ ArcanistHardpointObject $object,
+ $old,
+ $new) {
+
+ foreach ($new as $item) {
+ $phid = $item->getPHID();
+ if (!isset($old[$phid])) {
+ $old[$phid] = $item;
+ }
+ }
+
+ return $old;
+ }
+
+}
diff --git a/src/inspector/ArcanistWorkingCopyStateRefInspector.php b/src/inspector/ArcanistWorkingCopyStateRefInspector.php
new file mode 100644
--- /dev/null
+++ b/src/inspector/ArcanistWorkingCopyStateRefInspector.php
@@ -0,0 +1,26 @@
+<?php
+
+final class ArcanistWorkingCopyStateRefInspector
+ extends ArcanistRefInspector {
+
+ public function getInspectFunctionName() {
+ return 'working-copy';
+ }
+
+ public function newInspectRef(array $argv) {
+ if (count($argv) !== 1) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Expected exactly one argument to "working-copy(...)" with a '.
+ 'commit hash.'));
+ }
+
+ $commit_hash = $argv[0];
+ $commit_ref = id(new ArcanistCommitRefPro())
+ ->setCommitHash($commit_hash);
+
+ return id(new ArcanistWorkingCopyStateRefPro())
+ ->setCommitRef($commit_ref);
+ }
+
+}
diff --git a/src/query/ArcanistGitCommitMessageHardpointQuery.php b/src/query/ArcanistGitCommitMessageHardpointQuery.php
--- a/src/query/ArcanistGitCommitMessageHardpointQuery.php
+++ b/src/query/ArcanistGitCommitMessageHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistGitCommitMessageHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistWorkflowGitHardpointQuery {
public function getHardpoints() {
return array(
@@ -13,11 +13,6 @@
return ($ref instanceof ArcanistCommitRefPro);
}
- protected function canLoadHardpoint() {
- $api = $this->getRepositoryAPI();
- return ($api instanceof ArcanistGitAPI);
- }
-
public function loadHardpoint(array $refs, $hardpoint) {
$api = $this->getRepositoryAPI();
diff --git a/src/query/ArcanistGitWorkingCopyRevisionHardpointQuery.php b/src/query/ArcanistGitWorkingCopyRevisionHardpointQuery.php
new file mode 100644
--- /dev/null
+++ b/src/query/ArcanistGitWorkingCopyRevisionHardpointQuery.php
@@ -0,0 +1,81 @@
+<?php
+
+final class ArcanistGitWorkingCopyRevisionHardpointQuery
+ extends ArcanistWorkflowGitHardpointQuery {
+
+ public function getHardpoints() {
+ return array(
+ ArcanistWorkingCopyStateRefPro::HARDPOINT_REVISIONREFS,
+ );
+ }
+
+ protected function canLoadRef(ArcanistRefPro $ref) {
+ return ($ref instanceof ArcanistWorkingCopyStateRefPro);
+ }
+
+ public function loadHardpoint(array $refs, $hardpoint) {
+ yield $this->yieldRequests(
+ $refs,
+ array(
+ ArcanistWorkingCopyStateRefPro::HARDPOINT_COMMITREF,
+ ));
+
+ $hashes = array();
+ $map = array();
+ foreach ($refs as $ref_key => $ref) {
+ $commit = $ref->getCommitRef();
+
+ $commit_hashes = array();
+
+ $commit_hashes[] = array(
+ 'gtcm',
+ $commit->getCommitHash(),
+ );
+
+ if ($commit->getTreeHash()) {
+ $commit_hashes[] = array(
+ 'gttr',
+ $commit->getTreeHash(),
+ );
+ }
+
+ foreach ($commit_hashes as $hash) {
+ $hashes[] = $hash;
+ $hash_key = $this->getHashKey($hash);
+ $map[$hash_key][$ref_key] = $ref;
+ }
+ }
+
+ $results = array_fill_keys(array_keys($refs), array());
+ if ($hashes) {
+ $revisions = (yield $this->yieldConduit(
+ 'differential.query',
+ array(
+ 'commitHashes' => $hashes,
+ )));
+
+ foreach ($revisions as $dict) {
+ $revision_hashes = idx($dict, 'hashes');
+ if (!$revision_hashes) {
+ continue;
+ }
+
+ $revision_ref = ArcanistRevisionRefPro::newFromConduit($dict);
+ foreach ($revision_hashes as $revision_hash) {
+ $hash_key = $this->getHashKey($revision_hash);
+ $state_refs = idx($map, $hash_key, array());
+ foreach ($state_refs as $ref_key => $state_ref) {
+ $results[$ref_key][] = $revision_ref;
+ }
+ }
+ }
+ }
+
+ yield $this->yieldMap($results);
+ }
+
+ private function getHashKey(array $hash) {
+ return $hash[0].':'.$hash[1];
+ }
+
+}
diff --git a/src/query/ArcanistMessageRevisionHardpointQuery.php b/src/query/ArcanistMessageRevisionHardpointQuery.php
new file mode 100644
--- /dev/null
+++ b/src/query/ArcanistMessageRevisionHardpointQuery.php
@@ -0,0 +1,76 @@
+<?php
+
+final class ArcanistMessageRevisionHardpointQuery
+ extends ArcanistWorkflowHardpointQuery {
+
+ public function getHardpoints() {
+ return array(
+ ArcanistWorkingCopyStateRefPro::HARDPOINT_REVISIONREFS,
+ );
+ }
+
+ protected function canLoadRef(ArcanistRefPro $ref) {
+ return ($ref instanceof ArcanistWorkingCopyStateRefPro);
+ }
+
+ public function loadHardpoint(array $refs, $hardpoint) {
+ yield $this->yieldRequests(
+ $refs,
+ array(
+ ArcanistWorkingCopyStateRefPro::HARDPOINT_COMMITREF,
+ ));
+
+ $commit_refs = array();
+ foreach ($refs as $ref) {
+ $commit_refs[] = $ref->getCommitRef();
+ }
+
+ yield $this->yieldRequests(
+ $commit_refs,
+ array(
+ ArcanistCommitRefPro::HARDPOINT_MESSAGE,
+ ));
+
+ $map = array();
+ foreach ($refs as $ref_key => $ref) {
+ $commit_ref = $ref->getCommitRef();
+ $corpus = $commit_ref->getMessage();
+
+ $id = null;
+ try {
+ $message = ArcanistDifferentialCommitMessage::newFromRawCorpus($corpus);
+ $id = $message->getRevisionID();
+ } catch (ArcanistUsageException $ex) {
+ continue;
+ }
+
+ if (!$id) {
+ continue;
+ }
+
+ $map[$id][$ref_key] = $ref;
+ }
+
+ $results = array();
+ if ($map) {
+ $revisions = (yield $this->yieldConduit(
+ 'differential.query',
+ array(
+ 'ids' => array_keys($map),
+ )));
+
+ foreach ($revisions as $dict) {
+ $revision_ref = ArcanistRevisionRefPro::newFromConduit($dict);
+ $id = $dict['id'];
+
+ $state_refs = idx($map, $id, array());
+ foreach ($state_refs as $ref_key => $state_ref) {
+ $results[$ref_key][] = $revision_ref;
+ }
+ }
+ }
+
+ yield $this->yieldMap($results);
+ }
+
+}
diff --git a/src/query/ArcanistWorkflowGitHardpointQuery.php b/src/query/ArcanistWorkflowGitHardpointQuery.php
new file mode 100644
--- /dev/null
+++ b/src/query/ArcanistWorkflowGitHardpointQuery.php
@@ -0,0 +1,11 @@
+<?php
+
+abstract class ArcanistWorkflowGitHardpointQuery
+ extends ArcanistWorkflowHardpointQuery {
+
+ final protected function canLoadHardpoint() {
+ $api = $this->getRepositoryAPI();
+ return ($api instanceof ArcanistGitAPI);
+ }
+
+}
diff --git a/src/ref/ArcanistRevisionRefPro.php b/src/ref/ArcanistRevisionRefPro.php
new file mode 100644
--- /dev/null
+++ b/src/ref/ArcanistRevisionRefPro.php
@@ -0,0 +1,76 @@
+<?php
+
+final class ArcanistRevisionRefPro
+ extends ArcanistRefPro {
+
+ private $parameters;
+ private $sources = array();
+
+ public function getRefDisplayName() {
+ return pht('Revision %s', $this->getMonogram());
+ }
+
+ public function defineHardpoints() {
+ return array();
+ }
+
+ public static function newFromConduit(array $dict) {
+ $ref = new self();
+ $ref->parameters = $dict;
+ return $ref;
+ }
+
+ public function getMonogram() {
+ return 'D'.$this->getID();
+ }
+
+ public function getStatusDisplayName() {
+ return idx($this->parameters, 'statusName');
+ }
+
+ public function isClosed() {
+ // TODO: This should use sensible constants, not English language
+ // display text.
+ switch ($this->getStatusDisplayName()) {
+ case 'Abandoned':
+ case 'Closed':
+ return true;
+ }
+
+ return false;
+ }
+
+ public function getURI() {
+ return idx($this->parameters, 'uri');
+ }
+
+ public function getFullName() {
+ return pht('%s: %s', $this->getMonogram(), $this->getName());
+ }
+
+ public function getID() {
+ return idx($this->parameters, 'id');
+ }
+
+ public function getPHID() {
+ return idx($this->parameters, 'phid');
+ }
+
+ public function getName() {
+ return idx($this->parameters, 'title');
+ }
+
+ public function getAuthorPHID() {
+ return idx($this->parameters, 'authorPHID');
+ }
+
+ public function addSource(ArcanistRevisionRefSource $source) {
+ $this->sources[] = $source;
+ return $this;
+ }
+
+ public function getSources() {
+ return $this->sources;
+ }
+
+}
diff --git a/src/ref/ArcanistWorkingCopyStateRefPro.php b/src/ref/ArcanistWorkingCopyStateRefPro.php
--- a/src/ref/ArcanistWorkingCopyStateRefPro.php
+++ b/src/ref/ArcanistWorkingCopyStateRefPro.php
@@ -4,7 +4,6 @@
extends ArcanistRefPro {
const HARDPOINT_COMMITREF = 'commitRef';
- const HARDPOINT_BRANCHREF = 'branchRef';
const HARDPOINT_REVISIONREFS = 'revisionRefs';
public function getRefDisplayName() {
@@ -14,22 +13,15 @@
}
protected function newHardpoints() {
+ $object_list = new ArcanistObjectListHardpoint();
return array(
$this->newHardpoint(self::HARDPOINT_COMMITREF),
- $this->newHardpoint(self::HARDPOINT_BRANCHREF),
- $this->newVectorHardpoint(self::HARDPOINT_REVISIONREFS),
+ $this->newTemplateHardpoint(self::HARDPOINT_REVISIONREFS, $object_list),
);
}
- public function attachBranchRef(ArcanistBranchRef $branch_ref) {
- return $this->attachHardpoint(self::HARDPOINT_BRANCHREF, $branch_ref);
- }
-
- public function getBranchRef() {
- return $this->getHardpoint(self::HARDPOINT_BRANCHREF);
- }
-
- public function setCommitRef(ArcanistCommitRef $commit_ref) {
+ // TODO: This should be "attachCommitRef()".
+ public function setCommitRef(ArcanistCommitRefPro $commit_ref) {
return $this->attachHardpoint(self::HARDPOINT_COMMITREF, $commit_ref);
}
diff --git a/src/workflow/ArcanistInspectWorkflow.php b/src/workflow/ArcanistInspectWorkflow.php
--- a/src/workflow/ArcanistInspectWorkflow.php
+++ b/src/workflow/ArcanistInspectWorkflow.php
@@ -54,11 +54,13 @@
$ref_lists = array();
foreach ($objects as $description) {
$matches = null;
- if (!preg_match('/^(\w+)(?:\(([^)]+)\))?\z/', $description, $matches)) {
+ $pattern = '/^([\w-]+)(?:\(([^)]+)\))?\z/';
+ if (!preg_match($pattern, $description, $matches)) {
throw new PhutilArgumentUsageException(
pht(
'Object specification "%s" is unknown, expected a specification '.
- 'like "commit(HEAD)".'));
+ 'like "commit(HEAD)".',
+ $description));
}
$function = $matches[1];
@@ -149,11 +151,21 @@
if ($ref->hasAttachedHardpoint($hardpoint_key)) {
$mode = '*';
$value = $ref->getHardpoint($hardpoint_key);
+
if ($value instanceof ArcanistRefPro) {
$children[] = $value;
+ } else if (is_array($value)) {
+ foreach ($value as $key => $child) {
+ if ($child instanceof ArcanistRefPro) {
+ $children[] = $child;
+ } else {
+ $values[] = $value;
+ }
+ }
} else {
$values[] = $value;
}
+
} else {
$mode = 'o';
}

File Metadata

Mime Type
text/plain
Expires
Fri, Nov 22, 9:34 PM (18 h, 4 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6776017
Default Alt Text
D21079.diff (19 KB)

Event Timeline