Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14843818
D21095.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
38 KB
Referenced Files
None
Subscribers
None
D21095.diff
View Options
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
@@ -411,6 +411,7 @@
'ArcanistRubyLinterTestCase' => 'lint/linter/__tests__/ArcanistRubyLinterTestCase.php',
'ArcanistRuntime' => 'runtime/ArcanistRuntime.php',
'ArcanistRuntimeConfigurationSource' => 'config/source/ArcanistRuntimeConfigurationSource.php',
+ 'ArcanistRuntimeHardpointQuery' => 'toolset/query/ArcanistRuntimeHardpointQuery.php',
'ArcanistScalarConfigOption' => 'config/option/ArcanistScalarConfigOption.php',
'ArcanistScalarHardpoint' => 'hardpoint/ArcanistScalarHardpoint.php',
'ArcanistScriptAndRegexLinter' => 'lint/linter/ArcanistScriptAndRegexLinter.php',
@@ -507,7 +508,6 @@
'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',
'ArcanistWorkingCopyCommitHardpointQuery' => 'query/ArcanistWorkingCopyCommitHardpointQuery.php',
@@ -1006,7 +1006,7 @@
'ArcanistAliasFunctionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistAliasWorkflow' => 'ArcanistWorkflow',
'ArcanistAliasesConfigOption' => 'ArcanistListConfigOption',
- 'ArcanistAmendWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistAmendWorkflow' => 'ArcanistArcWorkflow',
'ArcanistAnoidWorkflow' => 'ArcanistArcWorkflow',
'ArcanistArcConfigurationEngineExtension' => 'ArcanistConfigurationEngineExtension',
'ArcanistArcToolset' => 'ArcanistToolset',
@@ -1035,14 +1035,14 @@
'ArcanistBraceFormattingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistBranchRef' => 'ArcanistRef',
'ArcanistBranchWorkflow' => 'ArcanistFeatureBaseWorkflow',
- 'ArcanistBrowseCommitHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistBrowseCommitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistBrowseCommitURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
'ArcanistBrowseObjectNameURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
'ArcanistBrowsePathURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
'ArcanistBrowseRef' => 'ArcanistRef',
'ArcanistBrowseRefInspector' => 'ArcanistRefInspector',
'ArcanistBrowseRevisionURIHardpointQuery' => 'ArcanistBrowseURIHardpointQuery',
- 'ArcanistBrowseURIHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistBrowseURIHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistBrowseURIRef' => 'ArcanistRef',
'ArcanistBrowseWorkflow' => 'ArcanistArcWorkflow',
'ArcanistBuildPlanRef' => 'Phobject',
@@ -1085,7 +1085,7 @@
'ArcanistCommitRef' => 'ArcanistRef',
'ArcanistCommitSymbolRef' => 'ArcanistSymbolRef',
'ArcanistCommitSymbolRefInspector' => 'ArcanistRefInspector',
- 'ArcanistCommitUpstreamHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistCommitUpstreamHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistCommitWorkflow' => 'ArcanistWorkflow',
'ArcanistCompilerLintRenderer' => 'ArcanistLintRenderer',
'ArcanistComposerLinter' => 'ArcanistLinter',
@@ -1298,7 +1298,7 @@
'ArcanistMercurialWorkingCopy' => 'ArcanistWorkingCopy',
'ArcanistMergeConflictLinter' => 'ArcanistLinter',
'ArcanistMergeConflictLinterTestCase' => 'ArcanistLinterTestCase',
- 'ArcanistMessageRevisionHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistMessageRevisionHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistMissingArgumentTerminatorException' => 'Exception',
'ArcanistMissingLinterException' => 'Exception',
'ArcanistModifierOrderingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -1381,13 +1381,13 @@
'ArcanistReusedIteratorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistReusedIteratorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistRevertWorkflow' => 'ArcanistWorkflow',
- 'ArcanistRevisionCommitMessageHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistRevisionCommitMessageHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistRevisionRef' => array(
'ArcanistRef',
'ArcanistDisplayRefInterface',
),
'ArcanistRevisionRefSource' => 'Phobject',
- 'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistRevisionSymbolRef' => 'ArcanistSymbolRef',
'ArcanistRevisionSymbolRefInspector' => 'ArcanistRefInspector',
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
@@ -1395,6 +1395,7 @@
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
'ArcanistRubyLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistRuntimeConfigurationSource' => 'ArcanistDictionaryConfigurationSource',
+ 'ArcanistRuntimeHardpointQuery' => 'ArcanistHardpointQuery',
'ArcanistScalarConfigOption' => 'ArcanistConfigOption',
'ArcanistScalarHardpoint' => 'ArcanistHardpoint',
'ArcanistScriptAndRegexLinter' => 'ArcanistLinter',
@@ -1478,7 +1479,7 @@
'ArcanistRef',
'ArcanistDisplayRefInterface',
),
- 'ArcanistUserSymbolHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistUserSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistUserSymbolRef' => 'ArcanistSymbolRef',
'ArcanistUserSymbolRefInspector' => 'ArcanistRefInspector',
'ArcanistVariableReferenceSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -1492,11 +1493,10 @@
'ArcanistWildConfigOption' => 'ArcanistConfigOption',
'ArcanistWorkflow' => 'Phobject',
'ArcanistWorkflowArgument' => 'Phobject',
- 'ArcanistWorkflowGitHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
- 'ArcanistWorkflowHardpointQuery' => 'ArcanistHardpointQuery',
+ 'ArcanistWorkflowGitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistWorkflowInformation' => 'Phobject',
'ArcanistWorkingCopy' => 'Phobject',
- 'ArcanistWorkingCopyCommitHardpointQuery' => 'ArcanistWorkflowHardpointQuery',
+ 'ArcanistWorkingCopyCommitHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
'ArcanistWorkingCopyConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
'ArcanistWorkingCopyIdentity' => 'Phobject',
'ArcanistWorkingCopyPath' => 'Phobject',
diff --git a/src/browse/query/ArcanistBrowseCommitHardpointQuery.php b/src/browse/query/ArcanistBrowseCommitHardpointQuery.php
--- a/src/browse/query/ArcanistBrowseCommitHardpointQuery.php
+++ b/src/browse/query/ArcanistBrowseCommitHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistBrowseCommitHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/browse/query/ArcanistBrowseURIHardpointQuery.php b/src/browse/query/ArcanistBrowseURIHardpointQuery.php
--- a/src/browse/query/ArcanistBrowseURIHardpointQuery.php
+++ b/src/browse/query/ArcanistBrowseURIHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
abstract class ArcanistBrowseURIHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getSupportedBrowseType() {
return $this->getPhobjectClassConstant('BROWSETYPE', 32);
diff --git a/src/query/ArcanistCommitUpstreamHardpointQuery.php b/src/query/ArcanistCommitUpstreamHardpointQuery.php
--- a/src/query/ArcanistCommitUpstreamHardpointQuery.php
+++ b/src/query/ArcanistCommitUpstreamHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistCommitUpstreamHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/query/ArcanistMessageRevisionHardpointQuery.php b/src/query/ArcanistMessageRevisionHardpointQuery.php
--- a/src/query/ArcanistMessageRevisionHardpointQuery.php
+++ b/src/query/ArcanistMessageRevisionHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistMessageRevisionHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/query/ArcanistWorkflowGitHardpointQuery.php b/src/query/ArcanistWorkflowGitHardpointQuery.php
--- a/src/query/ArcanistWorkflowGitHardpointQuery.php
+++ b/src/query/ArcanistWorkflowGitHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
abstract class ArcanistWorkflowGitHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
final protected function canLoadHardpoint() {
$api = $this->getRepositoryAPI();
diff --git a/src/query/ArcanistWorkingCopyCommitHardpointQuery.php b/src/query/ArcanistWorkingCopyCommitHardpointQuery.php
--- a/src/query/ArcanistWorkingCopyCommitHardpointQuery.php
+++ b/src/query/ArcanistWorkingCopyCommitHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistWorkingCopyCommitHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php b/src/ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php
--- a/src/ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php
+++ b/src/ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistRevisionCommitMessageHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/ref/revision/ArcanistRevisionRef.php b/src/ref/revision/ArcanistRevisionRef.php
--- a/src/ref/revision/ArcanistRevisionRef.php
+++ b/src/ref/revision/ArcanistRevisionRef.php
@@ -79,6 +79,10 @@
return $this->sources;
}
+ public function getCommitMessage() {
+ return $this->getHardpoint(self::HARDPOINT_COMMITMESSAGE);
+ }
+
public function getDisplayRefObjectName() {
return $this->getMonogram();
}
diff --git a/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php b/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
--- a/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
+++ b/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistRevisionSymbolHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/ref/user/ArcanistUserRef.php b/src/ref/user/ArcanistUserRef.php
--- a/src/ref/user/ArcanistUserRef.php
+++ b/src/ref/user/ArcanistUserRef.php
@@ -8,7 +8,7 @@
private $parameters;
public function getRefDisplayName() {
- return pht('User "%s"', $this->getUsername());
+ return pht('User "%s"', $this->getMonogram());
}
public static function newFromConduit(array $parameters) {
@@ -29,6 +29,18 @@
return self::newFromConduit($parameters);
}
+ public function getID() {
+ return idx($this->parameters, 'id');
+ }
+
+ public function getPHID() {
+ return idx($this->parameters, 'phid');
+ }
+
+ public function getMonogram() {
+ return '@'.$this->getUsername();
+ }
+
public function getUsername() {
return idxv($this->parameters, array('fields', 'username'));
}
@@ -38,7 +50,7 @@
}
public function getDisplayRefObjectName() {
- return '@'.$this->getUsername();
+ return $this->getMonogram();
}
public function getDisplayRefTitle() {
diff --git a/src/ref/user/ArcanistUserSymbolHardpointQuery.php b/src/ref/user/ArcanistUserSymbolHardpointQuery.php
--- a/src/ref/user/ArcanistUserSymbolHardpointQuery.php
+++ b/src/ref/user/ArcanistUserSymbolHardpointQuery.php
@@ -1,7 +1,7 @@
<?php
final class ArcanistUserSymbolHardpointQuery
- extends ArcanistWorkflowHardpointQuery {
+ extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
return array(
diff --git a/src/repository/api/ArcanistGitAPI.php b/src/repository/api/ArcanistGitAPI.php
--- a/src/repository/api/ArcanistGitAPI.php
+++ b/src/repository/api/ArcanistGitAPI.php
@@ -1687,4 +1687,8 @@
return null;
}
+ protected function newCurrentCommitSymbol() {
+ return 'HEAD';
+ }
+
}
diff --git a/src/repository/api/ArcanistRepositoryAPI.php b/src/repository/api/ArcanistRepositoryAPI.php
--- a/src/repository/api/ArcanistRepositoryAPI.php
+++ b/src/repository/api/ArcanistRepositoryAPI.php
@@ -39,6 +39,10 @@
private $symbolicBaseCommit;
private $resolvedBaseCommit;
+ private $runtime;
+ private $currentWorkingCopyStateRef = false;
+ private $currentCommitRef = false;
+
abstract public function getSourceControlSystemName();
public function getDiffLinesOfContext() {
@@ -665,48 +669,69 @@
return null;
}
- final public function newCommitRef() {
- return new ArcanistCommitRef();
- }
-
- final public function newBranchRef() {
- return new ArcanistBranchRef();
- }
-
- final public function getCurrentCommitRef() {
- $commit_hash = $this->newCurrentCommitHash();
- return $this->newCommitRef()
- ->setCommitHash($commit_hash);
+ final public function newFuture($pattern /* , ... */) {
+ $args = func_get_args();
+ return $this->buildLocalFuture($args)
+ ->setResolveOnError(false);
}
- protected function newCurrentCommitRef() {
- $commit_hash = $this->newCurrentCommitHash();
- return $this->newCommitRefForSymbol($commit_hash);
+ final public function setRuntime(ArcanistRuntime $runtime) {
+ $this->runtime = $runtime;
+ return $this;
}
- protected function newCommitRefForSymbol() {
- throw new ArcanistCapabilityNotSupportedException($this);
+ final public function getRuntime() {
+ return $this->runtime;
}
- protected function newCurrentCommitHash() {
- throw new ArcanistCapabilityNotSupportedException($this);
+ final protected function getSymbolEngine() {
+ return $this->getRuntime()->getSymbolEngine();
}
final public function getCurrentWorkingCopyStateRef() {
- return $this->newCurrentWorkingCopyStateRef();
+ if ($this->currentWorkingCopyStateRef === false) {
+ $ref = $this->newCurrentWorkingCopyStateRef();
+ $this->currentWorkingCopyStateRef = $ref;
+ }
+
+ return $this->currentWorkingCopyStateRef;
}
protected function newCurrentWorkingCopyStateRef() {
$commit_ref = $this->getCurrentCommitRef();
+ if (!$commit_ref) {
+ return null;
+ }
+
return id(new ArcanistWorkingCopyStateRef())
->setCommitRef($commit_ref);
}
- final public function newFuture($pattern /* , ... */) {
- $args = func_get_args();
- return $this->buildLocalFuture($args)
- ->setResolveOnError(false);
+ final public function getCurrentCommitRef() {
+ if ($this->currentCommitRef === false) {
+ $this->currentCommitRef = $this->newCurrentCommitRef();
+ }
+ return $this->currentCommitRef;
+ }
+
+ protected function newCurrentCommitRef() {
+ $symbols = $this->getSymbolEngine();
+
+ $commit_symbol = $this->newCurrentCommitSymbol();
+
+ return $symbols->loadCommitForSymbol($commit_symbol);
}
+ protected function newCurrentCommitSymbol() {
+ throw new ArcanistCapabilityNotSupportedException($this);
+ }
+
+ final public function newCommitRef() {
+ return new ArcanistCommitRef();
+ }
+
+ final public function newBranchRef() {
+ return new ArcanistBranchRef();
+ }
}
diff --git a/src/runtime/ArcanistRuntime.php b/src/runtime/ArcanistRuntime.php
--- a/src/runtime/ArcanistRuntime.php
+++ b/src/runtime/ArcanistRuntime.php
@@ -8,6 +8,12 @@
private $stack = array();
+ private $viewer;
+ private $hardpointEngine;
+ private $symbolEngine;
+ private $conduitEngine;
+ private $workingCopy;
+
public function execute(array $argv) {
try {
@@ -108,6 +114,7 @@
$this->workflows = $workflows;
$conduit_engine = $this->newConduitEngine($config);
+ $this->conduitEngine = $conduit_engine;
$phutil_workflows = array();
foreach ($workflows as $key => $workflow) {
@@ -301,9 +308,14 @@
->setArguments($args);
$working_copy = ArcanistWorkingCopy::newFromWorkingDirectory(getcwd());
- if ($working_copy) {
- $engine->setWorkingCopy($working_copy);
- }
+
+ $engine->setWorkingCopy($working_copy);
+
+ $this->workingCopy = $working_copy;
+
+ $working_copy
+ ->getRepositoryAPI()
+ ->setRuntime($this);
return $engine;
}
@@ -682,6 +694,10 @@
return $this->stack;
}
+ public function getCurrentWorkflow() {
+ return last($this->stack);
+ }
+
private function newConduitEngine(ArcanistConfigurationSourceList $config) {
$conduit_uri = $config->getConfig('phabricator.uri');
@@ -744,4 +760,81 @@
return phutil_passthru('%Ls', $effect->getArguments());
}
+ public function getSymbolEngine() {
+ if ($this->symbolEngine === null) {
+ $this->symbolEngine = $this->newSymbolEngine();
+ }
+ return $this->symbolEngine;
+ }
+
+ private function newSymbolEngine() {
+ return id(new ArcanistSymbolEngine())
+ ->setWorkflow($this);
+ }
+
+ public function getHardpointEngine() {
+ if ($this->hardpointEngine === null) {
+ $this->hardpointEngine = $this->newHardpointEngine();
+ }
+ return $this->hardpointEngine;
+ }
+
+ private function newHardpointEngine() {
+ $engine = new ArcanistHardpointEngine();
+
+ $queries = ArcanistRuntimeHardpointQuery::getAllQueries();
+
+ foreach ($queries as $key => $query) {
+ $queries[$key] = id(clone $query)
+ ->setRuntime($this);
+ }
+
+ $engine->setQueries($queries);
+
+ return $engine;
+ }
+
+ public function getViewer() {
+ if (!$this->viewer) {
+ $viewer = $this->getSymbolEngine()
+ ->loadUserForSymbol('viewer()');
+
+ // TODO: Deal with anonymous stuff.
+ if (!$viewer) {
+ throw new Exception(pht('No viewer!'));
+ }
+
+ $this->viewer = $viewer;
+ }
+
+ return $this->viewer;
+ }
+
+ public function loadHardpoints($objects, $requests) {
+ if (!is_array($objects)) {
+ $objects = array($objects);
+ }
+
+ if (!is_array($requests)) {
+ $requests = array($requests);
+ }
+
+ $engine = $this->getHardpointEngine();
+
+ $requests = $engine->requestHardpoints(
+ $objects,
+ $requests);
+
+ // TODO: Wait for only the required requests.
+ $engine->waitForRequests(array());
+ }
+
+ public function getWorkingCopy() {
+ return $this->workingCopy;
+ }
+
+ public function getConduitEngine() {
+ return $this->conduitEngine;
+ }
+
}
diff --git a/src/toolset/query/ArcanistWorkflowHardpointQuery.php b/src/toolset/query/ArcanistRuntimeHardpointQuery.php
rename from src/toolset/query/ArcanistWorkflowHardpointQuery.php
rename to src/toolset/query/ArcanistRuntimeHardpointQuery.php
--- a/src/toolset/query/ArcanistWorkflowHardpointQuery.php
+++ b/src/toolset/query/ArcanistRuntimeHardpointQuery.php
@@ -1,22 +1,22 @@
<?php
-abstract class ArcanistWorkflowHardpointQuery
+abstract class ArcanistRuntimeHardpointQuery
extends ArcanistHardpointQuery {
- private $workflow;
+ private $runtime;
private $canLoadHardpoint;
- final public function setWorkflow(ArcanistWorkflow $workflow) {
- $this->workflow = $workflow;
+ final public function setRuntime(ArcanistRuntime $runtime) {
+ $this->runtime = $runtime;
return $this;
}
- final public function getWorkflow() {
- return $this->workflow;
+ final public function getRuntime() {
+ return $this->runtime;
}
final public function getWorkingCopy() {
- return $this->getWorkflow()->getWorkingCopy();
+ return $this->getRuntime()->getWorkingCopy();
}
final public function getRepositoryAPI() {
@@ -52,7 +52,7 @@
abstract protected function canLoadRef(ArcanistRef $ref);
final public function newConduitSearch($method, $constraints) {
- $conduit_engine = $this->getWorkflow()
+ $conduit_engine = $this->getRuntime()
->getConduitEngine();
$conduit_future = id(new ConduitSearchFuture())
@@ -69,7 +69,7 @@
}
final public function newConduit($method, $parameters) {
- $conduit_engine = $this->getWorkflow()
+ $conduit_engine = $this->getRuntime()
->getConduitEngine();
$call_object = $conduit_engine->newCall($method, $parameters);
@@ -84,7 +84,10 @@
}
final public function yieldRepositoryRef() {
- $workflow = $this->getWorkflow();
+ // TODO: This should probably move to Runtime.
+
+ $runtime = $this->getRuntime();
+ $workflow = $runtime->getCurrentWorkflow();
// TODO: This is currently a blocking request, but should yield to the
// hardpoint engine in the future.
diff --git a/src/workflow/ArcanistAmendWorkflow.php b/src/workflow/ArcanistAmendWorkflow.php
--- a/src/workflow/ArcanistAmendWorkflow.php
+++ b/src/workflow/ArcanistAmendWorkflow.php
@@ -1,210 +1,278 @@
<?php
-/**
- * Synchronizes commit messages from Differential.
- */
-final class ArcanistAmendWorkflow extends ArcanistWorkflow {
+final class ArcanistAmendWorkflow
+ extends ArcanistArcWorkflow {
public function getWorkflowName() {
return 'amend';
}
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **amend** [--revision __revision_id__] [--show]
-EOTEXT
- );
- }
+ public function getWorkflowInformation() {
+ $help = pht(<<<EOTEXT
+Amend the working copy, synchronizing the local commit message from
+Differential.
- public function getCommandHelp() {
- return phutil_console_format(<<<EOTEXT
- Supports: git, hg
- Amend the working copy, synchronizing the local commit message from
- Differential.
-
- Supported in Mercurial 2.2 and newer.
+Supported in Mercurial 2.2 and newer.
EOTEXT
);
- }
- public function requiresWorkingCopy() {
- return true;
+ return $this->newWorkflowInformation()
+ ->setSynopsis(
+ pht('Amend the working copy, synchronizing the local commit message.'))
+ ->addExample('**amend** [options] -- ')
+ ->setHelp($help);
}
- public function requiresConduit() {
- return true;
- }
-
- public function requiresAuthentication() {
- return true;
- }
-
- public function requiresRepositoryAPI() {
- return true;
+ public function getWorkflowArguments() {
+ return array(
+ $this->newWorkflowArgument('show')
+ ->setHelp(
+ pht(
+ 'Show the amended commit message, without modifying the '.
+ 'working copy.')),
+ $this->newWorkflowArgument('revision')
+ ->setParameter('id')
+ ->setHelp(
+ pht(
+ 'Use the message from a specific revision. If you do not specify '.
+ 'a revision, arc will guess which revision is in the working '.
+ 'copy.')),
+ );
}
- public function getArguments() {
+ protected function newPrompts() {
return array(
- 'show' => array(
- 'help' => pht(
- 'Show the amended commit message, without modifying the '.
- 'working copy.'),
- ),
- 'revision' => array(
- 'param' => 'revision_id',
- 'help' => pht(
- 'Use the message from a specific revision. If you do not specify '.
- 'a revision, arc will guess which revision is in the working '.
- 'copy.'),
- ),
+ $this->newPrompt('arc.amend.unrelated')
+ ->setDescription(
+ pht(
+ 'Confirms use of a revision that does not appear to be '.
+ 'present in the working copy.')),
+ $this->newPrompt('arc.amend.author')
+ ->setDescription(
+ pht(
+ 'Confirms use of a revision that you are not the author '.
+ 'of.')),
+ $this->newPrompt('arc.amend.immutable')
+ ->setDescription(
+ pht(
+ 'Confirms history mutation in a working copy marked as '.
+ 'immutable.')),
);
}
- public function run() {
+ public function runWorkflow() {
+ $symbols = $this->getSymbolEngine();
+
$is_show = $this->getArgument('show');
$repository_api = $this->getRepositoryAPI();
if (!$is_show) {
- if (!$repository_api->supportsAmend()) {
- throw new ArcanistUsageException(
- pht(
- "You may only run '%s' in a git or hg ".
- "(version 2.2 or newer) working copy.",
- 'arc amend'));
- }
+ $this->requireAmendSupport($repository_api);
+ }
- if ($this->isHistoryImmutable()) {
- throw new ArcanistUsageException(
- pht(
- 'This project is marked as adhering to a conservative history '.
- 'mutability doctrine (having an immutable local history), which '.
- 'precludes amending commit messages.'));
- }
+ $revision_symbol = $this->getArgument('revision');
+
+ // We only care about the local working copy state if we need it to
+ // figure out which revision we're operating on, or we're planning to
+ // mutate it. If the caller is running "arc amend --show --revision X",
+ // the local state does not matter.
+
+ $need_state =
+ ($revision_symbol === null) ||
+ (!$is_show);
+
+ if ($need_state) {
+ $state_ref = $repository_api->getCurrentWorkingCopyStateRef();
+
+ $this->loadHardpoints(
+ $state_ref,
+ ArcanistWorkingCopyStateRef::HARDPOINT_REVISIONREFS);
+
+ $revision_refs = $state_ref->getRevisionRefs();
+ }
- if ($repository_api->getUncommittedChanges()) {
- throw new ArcanistUsageException(
+ if ($revision_symbol === null) {
+ $revision_ref = $this->selectRevisionRef($revision_refs);
+ } else {
+ $revision_ref = $symbols->loadRevisionForSymbol($revision_symbol);
+ if (!$revision_ref) {
+ throw new PhutilArgumentUsageException(
pht(
- 'You have uncommitted changes in this branch. Stage and commit '.
- '(or revert) them before proceeding.'));
+ 'Revision "%s" does not exist, or you do not have permission '.
+ 'to see it.',
+ $revision_symbol));
}
}
- $revision_id = null;
- if ($this->getArgument('revision')) {
- $revision_id = $this->normalizeRevisionID($this->getArgument('revision'));
+ if (!$is_show) {
+ echo tsprintf(
+ "%s\n\n%s\n",
+ pht('Amending commit message to reflect revision:'),
+ $revision_ref->newDisplayRef());
+
+ $this->confirmAmendAuthor($revision_ref);
+ $this->confirmAmendNotFound($revision_ref, $state_ref);
}
- $repository_api->setBaseCommitArgumentRules('arc:this');
- $in_working_copy = $repository_api->loadWorkingCopyDifferentialRevisions(
- $this->getConduit(),
- array(
- 'status' => 'status-any',
- ));
- $in_working_copy = ipull($in_working_copy, null, 'id');
+ $this->loadHardpoints(
+ $revision_ref,
+ ArcanistRevisionRef::HARDPOINT_COMMITMESSAGE);
+
+ $message = $revision_ref->getCommitMessage();
+
+ if ($is_show) {
+ echo tsprintf(
+ "%B\n",
+ $message);
+ } else {
+ $repository_api->amendCommit($message);
+ }
- if (!$revision_id) {
- if (count($in_working_copy) == 0) {
- throw new ArcanistUsageException(
+ return 0;
+ }
+
+ private function requireAmendSupport(ArcanistRepositoryAPI $api) {
+ if (!$api->supportsAmend()) {
+ if ($api instanceof ArcanistMercurialAPI) {
+ throw new PhutilArgumentUsageException(
pht(
- "No revision specified with '%s', and no revisions found ".
- "in the working copy. Use '%s' to specify which revision ".
- "you want to amend.",
- '--revision',
- '--revision <id>'));
- } else if (count($in_working_copy) > 1) {
- $message = pht(
- "More than one revision was found in the working copy:\n%s\n".
- "Use '%s' to specify which revision you want to amend.",
- $this->renderRevisionList($in_working_copy),
- '--revision <id>');
- throw new ArcanistUsageException($message);
- } else {
- $revision_id = key($in_working_copy);
- $revision = $in_working_copy[$revision_id];
- if ($revision['authorPHID'] != $this->getUserPHID()) {
- $other_author = $this->getConduit()->callMethodSynchronous(
- 'user.query',
- array(
- 'phids' => array($revision['authorPHID']),
- ));
- $other_author = ipull($other_author, 'userName', 'phid');
- $other_author = $other_author[$revision['authorPHID']];
- $rev_title = $revision['title'];
- $ok = phutil_console_confirm(
- pht(
- "You are amending the revision '%s' but you are not ".
- "the author. Amend this revision by %s?",
- "D{$revision_id}: {$rev_title}",
- $other_author));
- if (!$ok) {
- throw new ArcanistUserAbortException();
- }
- }
+ '"arc amend" is only supported under Mercurial 2.2 or newer. '.
+ 'Older versions of Mercurial do not support the "--amend" flag '.
+ 'to "hg commit ...", which this workflow requires.'));
}
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ '"arc amend" must be run from inside a working copy of a '.
+ 'repository using a version control system that supports '.
+ 'amending commits, like Git or Mercurial.'));
}
- $conduit = $this->getConduit();
- try {
- $message = $conduit->callMethodSynchronous(
- 'differential.getcommitmessage',
- array(
- 'revision_id' => $revision_id,
- 'edit' => false,
- ));
- } catch (ConduitClientException $ex) {
- if (strpos($ex->getMessage(), 'ERR_NOT_FOUND') === false) {
- throw $ex;
- } else {
- throw new ArcanistUsageException(
- pht("Revision '%s' does not exist.", "D{$revision_id}")
- );
- }
+ if ($this->isHistoryImmutable()) {
+ echo tsprintf(
+ "%!\n\n%W\n",
+ pht('IMMUTABLE WORKING COPY'),
+ pht(
+ 'This working copy is configured to have an immutable local '.
+ 'history, using the "history.immutable" configuration option. '.
+ 'Amending the working copy will mutate local history.'));
+
+ $prompt = pht('Are you sure you want to mutate history?');
+
+ $this->getPrompt('arc.amend.immutable')
+ ->setQuery($prompt)
+ ->execute();
}
- $revision = $conduit->callMethodSynchronous(
- 'differential.query',
- array(
- 'ids' => array($revision_id),
- ));
- if (empty($revision)) {
- throw new Exception(
- pht("Failed to lookup information for '%s'!", "D{$revision_id}"));
+ return;
+
+ if ($api->getUncommittedChanges()) {
+ // TODO: Make this class of error show the uncommitted changes.
+
+ // TODO: This only needs to check for staged-but-uncommitted changes.
+ // We can safely amend with untracked and unstaged changes.
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'You have uncommitted changes in this working copy. Commit or '.
+ 'revert them before proceeding.'));
}
- $revision = head($revision);
- $revision_title = $revision['title'];
+ }
- if (!$is_show) {
- if ($revision_id && empty($in_working_copy[$revision_id])) {
- $ok = phutil_console_confirm(
- pht(
- "The revision '%s' does not appear to be in the working copy. Are ".
- "you sure you want to amend HEAD with the commit message for '%s'?",
- "D{$revision_id}",
- "D{$revision_id}: {$revision_title}"));
- if (!$ok) {
- throw new ArcanistUserAbortException();
- }
- }
+ private function selectRevisionRef(array $revisions) {
+ if (!$revisions) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'No revision specified with "--revision", and no revisions found '.
+ 'that match the current working copy state. Use "--revision <id>" '.
+ 'to specify which revision you want to amend.'));
}
- if ($is_show) {
- echo $message."\n";
- } else {
- echo pht(
- "Amending commit message to reflect revision %s.\n",
- phutil_console_format(
- '**D%d: %s**',
- $revision_id,
- $revision_title));
+ if (count($revisions) > 1) {
+ echo tsprintf(
+ "%!\n%W\n\n%B\n",
+ pht('MULTIPLE REVISIONS IN WORKING COPY'),
+ pht('More than one revision was found in the working copy:'),
+ mpull($revisions, 'newDisplayRef'));
- $repository_api->amendCommit($message);
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Use "--revision <id>" to specify which revision you want '.
+ 'to amend.'));
}
- return 0;
+ return head($revisions);
}
- public function getSupportedRevisionControlSystems() {
- return array('git', 'hg');
+ private function confirmAmendAuthor(ArcanistRevisionRef $revision_ref) {
+ $viewer = $this->getViewer();
+ $viewer_phid = $viewer->getPHID();
+
+ $author_phid = $revision_ref->getAuthorPHID();
+
+ if ($viewer_phid === $author_phid) {
+ return;
+ }
+
+ $symbols = $this->getSymbolEngine();
+ $author_ref = $symbols->loadUserForSymbol($author_phid);
+ if (!$author_ref) {
+ // If we don't have any luck loading the author, skip this warning.
+ return;
+ }
+
+ echo tsprintf(
+ "%!\n\n%W\n\n%s",
+ pht('NOT REVISION AUTHOR'),
+ array(
+ pht(
+ 'You are amending the working copy using information from '.
+ 'a revision you are not the author of.'),
+ "\n\n",
+ pht(
+ 'The author of this revision (%s) is:',
+ $revision_ref->getMonogram()),
+ ),
+ $author_ref->newDisplayRef());
+
+ $prompt = pht(
+ 'Amend working copy using revision owned by %s?',
+ $author_ref->getMonogram());
+
+ $this->getPrompt('arc.amend.author')
+ ->setQuery($prompt)
+ ->execute();
+ }
+
+ private function confirmAmendNotFound(
+ ArcanistRevisionRef $revision_ref,
+ ArcanistWorkingCopyStateRef $state_ref) {
+
+ $local_refs = $state_ref->getRevisionRefs();
+ $local_refs = mpull($local_refs, null, 'getPHID');
+
+ $revision_phid = $revision_ref->getPHID();
+ $is_local = isset($local_refs[$revision_phid]);
+
+ if ($is_local) {
+ return;
+ }
+
+ echo tsprintf(
+ "%!\n\n%W\n",
+ pht('UNRELATED REVISION'),
+ pht(
+ 'You are amending the working copy using information from '.
+ 'a revision that does not appear to be associated with the '.
+ 'current state of the working copy.'));
+
+ $prompt = pht(
+ 'Amend working copy using unrelated revision %s?',
+ $revision_ref->getMonogram());
+
+ $this->getPrompt('arc.amend.unrelated')
+ ->setQuery($prompt)
+ ->execute();
}
}
diff --git a/src/workflow/ArcanistWorkflow.php b/src/workflow/ArcanistWorkflow.php
--- a/src/workflow/ArcanistWorkflow.php
+++ b/src/workflow/ArcanistWorkflow.php
@@ -76,9 +76,6 @@
private $configurationEngine;
private $configurationSourceList;
- private $viewer;
- private $hardpointEngine;
- private $symbolEngine;
private $promptMap;
final public function setToolset(ArcanistToolset $toolset) {
@@ -2303,45 +2300,7 @@
final public function loadHardpoints(
$objects,
$requests) {
-
- if (!is_array($objects)) {
- $objects = array($objects);
- }
-
- if (!is_array($requests)) {
- $requests = array($requests);
- }
-
- $engine = $this->getHardpointEngine();
-
- $requests = $engine->requestHardpoints(
- $objects,
- $requests);
-
- // TODO: Wait for only the required requests.
- $engine->waitForRequests(array());
- }
-
- private function getHardpointEngine() {
- if ($this->hardpointEngine === null) {
- $this->hardpointEngine = $this->newHardpointEngine();
- }
- return $this->hardpointEngine;
- }
-
- private function newHardpointEngine() {
- $engine = new ArcanistHardpointEngine();
-
- $queries = ArcanistWorkflowHardpointQuery::getAllQueries();
-
- foreach ($queries as $key => $query) {
- $queries[$key] = id(clone $query)
- ->setWorkflow($this);
- }
-
- $engine->setQueries($queries);
-
- return $engine;
+ return $this->getRuntime()->loadHardpoints($objects, $requests);
}
protected function newPrompts() {
@@ -2404,31 +2363,11 @@
}
final protected function getSymbolEngine() {
- if ($this->symbolEngine === null) {
- $this->symbolEngine = $this->newSymbolEngine();
- }
- return $this->symbolEngine;
- }
-
- private function newSymbolEngine() {
- return id(new ArcanistSymbolEngine())
- ->setWorkflow($this);
+ return $this->getRuntime()->getSymbolEngine();
}
final protected function getViewer() {
- if (!$this->viewer) {
- $viewer = $this->getSymbolEngine()
- ->loadUserForSymbol('viewer()');
-
- // TODO: Deal with anonymous stuff.
- if (!$viewer) {
- throw new Exception(pht('No viewer!'));
- }
-
- $this->viewer = $viewer;
- }
-
- return $this->viewer;
+ return $this->getRuntime()->getViewer();
}
}
diff --git a/src/xsprintf/tsprintf.php b/src/xsprintf/tsprintf.php
--- a/src/xsprintf/tsprintf.php
+++ b/src/xsprintf/tsprintf.php
@@ -38,6 +38,23 @@
case 'R':
$type = 's';
break;
+ case 'W':
+ $value = PhutilTerminalString::escapeStringValue($value, true);
+ $value = phutil_console_wrap($value);
+ $type = 's';
+ break;
+ case '!':
+ $value = tsprintf('<bg:yellow>** <!> %s **</bg>', $value);
+ $value = PhutilTerminalString::escapeStringValue($value, false);
+ $type = 's';
+ break;
+ default:
+ throw new Exception(
+ pht(
+ 'Unsupported escape sequence "%s" found in pattern: %s',
+ $type,
+ $pattern));
+ break;
}
$pattern[$pos] = $type;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Feb 3, 10:30 AM (1 h, 51 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7086734
Default Alt Text
D21095.diff (38 KB)
Attached To
Mode
D21095: Update "arc amend" for Toolsets
Attached
Detach File
Event Timeline
Log In to Comment