Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15442104
D21104.id50266.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
35 KB
Referenced Files
None
Subscribers
None
D21104.id50266.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
@@ -189,9 +189,7 @@
'ArcanistFileConfigurationSource' => 'config/source/ArcanistFileConfigurationSource.php',
'ArcanistFileDataRef' => 'upload/ArcanistFileDataRef.php',
'ArcanistFileRef' => 'ref/file/ArcanistFileRef.php',
- 'ArcanistFileSymbolHardpointQuery' => 'ref/file/ArcanistFileSymbolHardpointQuery.php',
'ArcanistFileSymbolRef' => 'ref/file/ArcanistFileSymbolRef.php',
- 'ArcanistFileSymbolRefInspector' => 'ref/file/ArcanistFileSymbolRefInspector.php',
'ArcanistFileUploader' => 'upload/ArcanistFileUploader.php',
'ArcanistFilenameLinter' => 'lint/linter/ArcanistFilenameLinter.php',
'ArcanistFilenameLinterTestCase' => 'lint/linter/__tests__/ArcanistFilenameLinterTestCase.php',
@@ -361,6 +359,8 @@
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParenthesesSpacingXHPASTLinterRuleTestCase.php',
'ArcanistParseStrUseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistParseStrUseXHPASTLinterRule.php',
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParseStrUseXHPASTLinterRuleTestCase.php',
+ 'ArcanistPasteRef' => 'ref/paste/ArcanistPasteRef.php',
+ 'ArcanistPasteSymbolRef' => 'ref/paste/ArcanistPasteSymbolRef.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php',
@@ -401,9 +401,7 @@
'ArcanistRevisionCommitMessageHardpointQuery' => 'ref/revision/ArcanistRevisionCommitMessageHardpointQuery.php',
'ArcanistRevisionRef' => 'ref/revision/ArcanistRevisionRef.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',
'ArcanistRuboCopLinterTestCase' => 'lint/linter/__tests__/ArcanistRuboCopLinterTestCase.php',
'ArcanistRubyLinter' => 'lint/linter/ArcanistRubyLinter.php',
@@ -424,6 +422,9 @@
'ArcanistSetting' => 'configuration/ArcanistSetting.php',
'ArcanistSettings' => 'configuration/ArcanistSettings.php',
'ArcanistShellCompleteWorkflow' => 'toolset/workflow/ArcanistShellCompleteWorkflow.php',
+ 'ArcanistSimpleSymbolHardpointQuery' => 'ref/simple/ArcanistSimpleSymbolHardpointQuery.php',
+ 'ArcanistSimpleSymbolRef' => 'ref/simple/ArcanistSimpleSymbolRef.php',
+ 'ArcanistSimpleSymbolRefInspector' => 'ref/simple/ArcanistSimpleSymbolRefInspector.php',
'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php',
'ArcanistSlownessXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSlownessXHPASTLinterRule.php',
'ArcanistSlownessXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistSlownessXHPASTLinterRuleTestCase.php',
@@ -439,6 +440,8 @@
'ArcanistSymbolRef' => 'ref/symbol/ArcanistSymbolRef.php',
'ArcanistSyntaxErrorXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSyntaxErrorXHPASTLinterRule.php',
'ArcanistSystemConfigurationSource' => 'config/source/ArcanistSystemConfigurationSource.php',
+ 'ArcanistTaskRef' => 'ref/task/ArcanistTaskRef.php',
+ 'ArcanistTaskSymbolRef' => 'ref/task/ArcanistTaskSymbolRef.php',
'ArcanistTasksWorkflow' => 'workflow/ArcanistTasksWorkflow.php',
'ArcanistTautologicalExpressionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistTautologicalExpressionXHPASTLinterRule.php',
'ArcanistTautologicalExpressionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistTautologicalExpressionXHPASTLinterRuleTestCase.php',
@@ -1171,9 +1174,7 @@
'ArcanistRef',
'ArcanistDisplayRefInterface',
),
- 'ArcanistFileSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
- 'ArcanistFileSymbolRef' => 'ArcanistSymbolRef',
- 'ArcanistFileSymbolRefInspector' => 'ArcanistRefInspector',
+ 'ArcanistFileSymbolRef' => 'ArcanistSimpleSymbolRef',
'ArcanistFileUploader' => 'Phobject',
'ArcanistFilenameLinter' => 'ArcanistLinter',
'ArcanistFilenameLinterTestCase' => 'ArcanistLinterTestCase',
@@ -1343,7 +1344,12 @@
'ArcanistParenthesesSpacingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistParseStrUseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
- 'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistPasteRef' => array(
+ 'ArcanistRef',
+ 'ArcanistDisplayRefInterface',
+ ),
+ 'ArcanistPasteSymbolRef' => 'ArcanistSimpleSymbolRef',
+ 'ArcanistPasteWorkflow' => 'ArcanistArcWorkflow',
'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
'ArcanistPhpLinter' => 'ArcanistExternalLinter',
'ArcanistPhpLinterTestCase' => 'ArcanistExternalLinterTestCase',
@@ -1386,9 +1392,7 @@
'ArcanistDisplayRefInterface',
),
'ArcanistRevisionRefSource' => 'Phobject',
- 'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
- 'ArcanistRevisionSymbolRef' => 'ArcanistSymbolRef',
- 'ArcanistRevisionSymbolRefInspector' => 'ArcanistRefInspector',
+ 'ArcanistRevisionSymbolRef' => 'ArcanistSimpleSymbolRef',
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
@@ -1408,6 +1412,9 @@
'ArcanistSetting' => 'Phobject',
'ArcanistSettings' => 'Phobject',
'ArcanistShellCompleteWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistSimpleSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
+ 'ArcanistSimpleSymbolRef' => 'ArcanistSymbolRef',
+ 'ArcanistSimpleSymbolRefInspector' => 'ArcanistRefInspector',
'ArcanistSingleLintEngine' => 'ArcanistLintEngine',
'ArcanistSlownessXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistSlownessXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
@@ -1423,6 +1430,11 @@
'ArcanistSymbolRef' => 'ArcanistRef',
'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistSystemConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
+ 'ArcanistTaskRef' => array(
+ 'ArcanistRef',
+ 'ArcanistDisplayRefInterface',
+ ),
+ 'ArcanistTaskSymbolRef' => 'ArcanistSimpleSymbolRef',
'ArcanistTasksWorkflow' => 'ArcanistWorkflow',
'ArcanistTautologicalExpressionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistTautologicalExpressionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
diff --git a/src/conduit/ConduitSearchFuture.php b/src/conduit/ConduitSearchFuture.php
--- a/src/conduit/ConduitSearchFuture.php
+++ b/src/conduit/ConduitSearchFuture.php
@@ -6,6 +6,7 @@
private $conduitEngine;
private $method;
private $constraints;
+ private $attachments;
private $objects = array();
private $cursor;
@@ -28,7 +29,7 @@
return $this->method;
}
- public function setConstraints($constraints) {
+ public function setConstraints(array $constraints) {
$this->constraints = $constraints;
return $this;
}
@@ -37,6 +38,15 @@
return $this->constraints;
}
+ public function setAttachments(array $attachments) {
+ $this->attachments = $attachments;
+ return $this;
+ }
+
+ public function getAttachments() {
+ return $this->attachments;
+ }
+
public function isReady() {
if ($this->hasResult()) {
return true;
@@ -86,6 +96,10 @@
'constraints' => $constraints,
);
+ if ($this->attachments) {
+ $parameters['attachments'] = $this->attachments;
+ }
+
if ($this->cursor !== null) {
$parameters['after'] = (string)$this->cursor;
}
diff --git a/src/inspector/ArcanistRefInspector.php b/src/inspector/ArcanistRefInspector.php
--- a/src/inspector/ArcanistRefInspector.php
+++ b/src/inspector/ArcanistRefInspector.php
@@ -6,11 +6,24 @@
abstract public function getInspectFunctionName();
abstract public function newInspectRef(array $argv);
+ protected function newInspectors() {
+ return array($this);
+ }
+
final public static function getAllInspectors() {
- return id(new PhutilClassMapQuery())
+ $base_inspectors = id(new PhutilClassMapQuery())
->setAncestorClass(__CLASS__)
- ->setUniqueMethod('getInspectFunctionName')
->execute();
+
+ $results = array();
+
+ foreach ($base_inspectors as $base_inspector) {
+ foreach ($base_inspector->newInspectors() as $inspector) {
+ $results[] = $inspector;
+ }
+ }
+
+ return mpull($results, null, 'getInspectFunctionName');
}
}
diff --git a/src/log/ArcanistLogEngine.php b/src/log/ArcanistLogEngine.php
--- a/src/log/ArcanistLogEngine.php
+++ b/src/log/ArcanistLogEngine.php
@@ -92,4 +92,14 @@
->setMessage($message));
}
+ public function writeWaitingForInput() {
+ if (!phutil_is_interactive()) {
+ return;
+ }
+
+ $this->writeStatus(
+ pht('INPUT'),
+ pht('Waiting for input on stdin...'));
+ }
+
}
diff --git a/src/ref/ArcanistDisplayRef.php b/src/ref/ArcanistDisplayRef.php
--- a/src/ref/ArcanistDisplayRef.php
+++ b/src/ref/ArcanistDisplayRef.php
@@ -6,6 +6,7 @@
ArcanistTerminalStringInterface {
private $ref;
+ private $uri;
public function setRef(ArcanistRef $ref) {
$this->ref = $ref;
@@ -16,6 +17,15 @@
return $this->ref;
}
+ public function setURI($uri) {
+ $this->uri = $uri;
+ return $this;
+ }
+
+ public function getURI() {
+ return $this->uri;
+ }
+
public function newTerminalString() {
$ref = $this->getRef();
@@ -60,9 +70,20 @@
}
$ref = $this->getRef();
- return tsprintf(
+ $output = array();
+
+ $output[] = tsprintf(
"<bg:cyan>** * **</bg> %s\n",
$display_text);
+
+ $uri = $this->getURI();
+ if ($uri !== null) {
+ $output[] = tsprintf(
+ "<bg:cyan>** :// **</bg> __%s__\n",
+ $uri);
+ }
+
+ return $output;
}
}
diff --git a/src/ref/file/ArcanistFileSymbolRef.php b/src/ref/file/ArcanistFileSymbolRef.php
--- a/src/ref/file/ArcanistFileSymbolRef.php
+++ b/src/ref/file/ArcanistFileSymbolRef.php
@@ -1,47 +1,30 @@
<?php
final class ArcanistFileSymbolRef
- extends ArcanistSymbolRef {
-
- private $type;
-
- const TYPE_ID = 'id';
- const TYPE_PHID = 'phid';
+ extends ArcanistSimpleSymbolRef {
public function getRefDisplayName() {
return pht('File Symbol "%s"', $this->getSymbol());
}
- protected function newCacheKeyParts() {
- return array(
- sprintf('type(%s)', $this->type),
- );
+ protected function getSimpleSymbolPrefixPattern() {
+ return '[Ff]?';
+ }
+
+ protected function getSimpleSymbolPHIDType() {
+ return 'FILE';
+ }
+
+ public function getSimpleSymbolConduitSearchMethodName() {
+ return 'file.search';
}
- public function getSymbolType() {
- return $this->type;
+ public function getSimpleSymbolInspectFunctionName() {
+ return 'file';
}
- protected function resolveSymbol($symbol) {
- $matches = null;
-
- $is_id = preg_match('/^[Ff]?([1-9]\d*)\z/', $symbol, $matches);
- if ($is_id) {
- $this->type = self::TYPE_ID;
- return (int)$matches[1];
- }
-
- $is_phid = preg_match('/^PHID-FILE-\S+\z/', $symbol, $matches);
- if ($is_phid) {
- $this->type = self::TYPE_PHID;
- return $matches[0];
- }
-
- throw new PhutilArgumentUsageException(
- pht(
- 'The format of file symbol "%s" is unrecognized. Expected a '.
- 'monogram like "F123", or an ID like "123", or a file PHID.',
- $symbol));
+ public function newSimpleSymbolObjectRef() {
+ return new ArcanistFileRef();
}
}
diff --git a/src/ref/file/ArcanistFileSymbolRefInspector.php b/src/ref/file/ArcanistFileSymbolRefInspector.php
deleted file mode 100644
--- a/src/ref/file/ArcanistFileSymbolRefInspector.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-
-final class ArcanistFileSymbolRefInspector
- extends ArcanistRefInspector {
-
- public function getInspectFunctionName() {
- return 'file';
- }
-
- public function newInspectRef(array $argv) {
- if (count($argv) !== 1) {
- throw new PhutilArgumentUsageException(
- pht(
- 'Expected exactly one argument to "file(...)" with a '.
- 'file symbol.'));
- }
-
- return id(new ArcanistFileSymbolRef())
- ->setSymbol($argv[0]);
- }
-
-}
diff --git a/src/ref/paste/ArcanistPasteRef.php b/src/ref/paste/ArcanistPasteRef.php
new file mode 100644
--- /dev/null
+++ b/src/ref/paste/ArcanistPasteRef.php
@@ -0,0 +1,52 @@
+<?php
+
+final class ArcanistPasteRef
+ extends ArcanistRef
+ implements
+ ArcanistDisplayRefInterface {
+
+ private $parameters;
+
+ public function getRefDisplayName() {
+ return pht('Paste "%s"', $this->getMonogram());
+ }
+
+ public static function newFromConduit(array $parameters) {
+ $ref = new self();
+ $ref->parameters = $parameters;
+ return $ref;
+ }
+
+ public function getID() {
+ return idx($this->parameters, 'id');
+ }
+
+ public function getPHID() {
+ return idx($this->parameters, 'phid');
+ }
+
+ public function getTitle() {
+ return idxv($this->parameters, array('fields', 'title'));
+ }
+
+ public function getURI() {
+ return idxv($this->parameters, array('fields', 'uri'));
+ }
+
+ public function getContent() {
+ return idxv($this->parameters, array('attachments', 'content', 'content'));
+ }
+
+ public function getMonogram() {
+ return 'P'.$this->getID();
+ }
+
+ public function getDisplayRefObjectName() {
+ return $this->getMonogram();
+ }
+
+ public function getDisplayRefTitle() {
+ return $this->getTitle();
+ }
+
+}
diff --git a/src/ref/paste/ArcanistPasteSymbolRef.php b/src/ref/paste/ArcanistPasteSymbolRef.php
new file mode 100644
--- /dev/null
+++ b/src/ref/paste/ArcanistPasteSymbolRef.php
@@ -0,0 +1,36 @@
+<?php
+
+final class ArcanistPasteSymbolRef
+ extends ArcanistSimpleSymbolRef {
+
+ public function getRefDisplayName() {
+ return pht('Paste Symbol "%s"', $this->getSymbol());
+ }
+
+ protected function getSimpleSymbolPrefixPattern() {
+ return '[Pp]?';
+ }
+
+ protected function getSimpleSymbolPHIDType() {
+ return 'PSTE';
+ }
+
+ public function getSimpleSymbolConduitSearchMethodName() {
+ return 'paste.search';
+ }
+
+ public function getSimpleSymbolConduitSearchAttachments() {
+ return array(
+ 'content' => true,
+ );
+ }
+
+ public function getSimpleSymbolInspectFunctionName() {
+ return 'paste';
+ }
+
+ public function newSimpleSymbolObjectRef() {
+ return new ArcanistPasteRef();
+ }
+
+}
diff --git a/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php b/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
deleted file mode 100644
--- a/src/ref/revision/ArcanistRevisionSymbolHardpointQuery.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-final class ArcanistRevisionSymbolHardpointQuery
- extends ArcanistRuntimeHardpointQuery {
-
- 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->yieldConduitSearch(
- 'differential.revision.search',
- array(
- 'ids' => array_values($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);
- }
-
-}
diff --git a/src/ref/revision/ArcanistRevisionSymbolRef.php b/src/ref/revision/ArcanistRevisionSymbolRef.php
--- a/src/ref/revision/ArcanistRevisionSymbolRef.php
+++ b/src/ref/revision/ArcanistRevisionSymbolRef.php
@@ -1,25 +1,30 @@
<?php
final class ArcanistRevisionSymbolRef
- extends ArcanistSymbolRef {
+ extends ArcanistSimpleSymbolRef {
public function getRefDisplayName() {
return pht('Revision Symbol "%s"', $this->getSymbol());
}
- protected function resolveSymbol($symbol) {
- $matches = null;
+ protected function getSimpleSymbolPrefixPattern() {
+ return '[Dd]?';
+ }
+
+ protected function getSimpleSymbolPHIDType() {
+ return 'DREV';
+ }
- 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));
- }
+ public function getSimpleSymbolConduitSearchMethodName() {
+ return 'differential.revision.search';
+ }
+
+ public function getSimpleSymbolInspectFunctionName() {
+ return 'revision';
+ }
- return (int)$matches[1];
+ public function newSimpleSymbolObjectRef() {
+ return new ArcanistRevisionRef();
}
}
diff --git a/src/ref/revision/ArcanistRevisionSymbolRefInspector.php b/src/ref/revision/ArcanistRevisionSymbolRefInspector.php
deleted file mode 100644
--- a/src/ref/revision/ArcanistRevisionSymbolRefInspector.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?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]);
- }
-
-}
diff --git a/src/ref/file/ArcanistFileSymbolHardpointQuery.php b/src/ref/simple/ArcanistSimpleSymbolHardpointQuery.php
rename from src/ref/file/ArcanistFileSymbolHardpointQuery.php
rename to src/ref/simple/ArcanistSimpleSymbolHardpointQuery.php
--- a/src/ref/file/ArcanistFileSymbolHardpointQuery.php
+++ b/src/ref/simple/ArcanistSimpleSymbolHardpointQuery.php
@@ -1,6 +1,6 @@
<?php
-final class ArcanistFileSymbolHardpointQuery
+final class ArcanistSimpleSymbolHardpointQuery
extends ArcanistRuntimeHardpointQuery {
public function getHardpoints() {
@@ -10,7 +10,7 @@
}
protected function canLoadRef(ArcanistRef $ref) {
- return ($ref instanceof ArcanistFileSymbolRef);
+ return ($ref instanceof ArcanistSimpleSymbolRef);
}
public function loadHardpoint(array $refs, $hardpoint) {
@@ -19,23 +19,31 @@
foreach ($refs as $key => $ref) {
switch ($ref->getSymbolType()) {
- case ArcanistFileSymbolRef::TYPE_ID:
+ case ArcanistSimpleSymbolRef::TYPE_ID:
$id_map[$key] = $ref->getSymbol();
break;
- case ArcanistFileSymbolRef::TYPE_PHID:
+ case ArcanistSimpleSymbolRef::TYPE_PHID:
$phid_map[$key] = $ref->getSymbol();
break;
}
}
+ $template_ref = head($refs);
+
+ $conduit_method =
+ $template_ref->getSimpleSymbolConduitSearchMethodName();
+ $conduit_attachments =
+ $template_ref->getSimpleSymbolConduitSearchAttachments();
+
$futures = array();
if ($id_map) {
$id_future = $this->newConduitSearch(
- 'file.search',
+ $conduit_method,
array(
'ids' => array_values(array_fuse($id_map)),
- ));
+ ),
+ $conduit_attachments);
$futures[] = $id_future;
} else {
@@ -44,10 +52,11 @@
if ($phid_map) {
$phid_future = $this->newConduitSearch(
- 'file.search',
+ $ref->getSimpleSymbolConduitSearchMethodName(),
array(
'phids' => array_values(array_fuse($phid_map)),
- ));
+ ),
+ $conduit_attachments);
$futures[] = $phid_future;
} else {
@@ -76,12 +85,16 @@
}
}
+ $object_ref = $template_ref->newSimpleSymbolObjectRef();
+
foreach ($result_map as $key => $raw_result) {
if ($raw_result === null) {
continue;
}
- $result_map[$key] = ArcanistFileRef::newFromConduit($raw_result);
+ $result_map[$key] = call_user_func_array(
+ array(get_class($object_ref), 'newFromConduit'),
+ array($raw_result));
}
yield $this->yieldMap($result_map);
diff --git a/src/ref/simple/ArcanistSimpleSymbolRef.php b/src/ref/simple/ArcanistSimpleSymbolRef.php
new file mode 100644
--- /dev/null
+++ b/src/ref/simple/ArcanistSimpleSymbolRef.php
@@ -0,0 +1,58 @@
+<?php
+
+abstract class ArcanistSimpleSymbolRef
+ extends ArcanistSymbolRef {
+
+ private $type;
+
+ const TYPE_ID = 'id';
+ const TYPE_PHID = 'phid';
+
+ final protected function newCacheKeyParts() {
+ return array(
+ sprintf('type(%s)', $this->type),
+ );
+ }
+
+ final public function getSymbolType() {
+ return $this->type;
+ }
+
+ final protected function resolveSymbol($symbol) {
+ $matches = null;
+
+ $prefix_pattern = $this->getSimpleSymbolPrefixPattern();
+ $id_pattern = '(^'.$prefix_pattern.'([1-9]\d*)\z)';
+
+ $is_id = preg_match($id_pattern, $symbol, $matches);
+ if ($is_id) {
+ $this->type = self::TYPE_ID;
+ return (int)$matches[1];
+ }
+
+ $phid_type = $this->getSimpleSymbolPHIDType();
+ $phid_type = preg_quote($phid_type);
+ $phid_pattern = '(^PHID-'.$phid_type.'-\S+\z)';
+ $is_phid = preg_match($phid_pattern, $symbol, $matches);
+ if ($is_phid) {
+ $this->type = self::TYPE_PHID;
+ return $matches[0];
+ }
+
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'The format of symbol "%s" is unrecognized. Expected a '.
+ 'monogram like "X123", or an ID like "123", or a PHID.',
+ $symbol));
+ }
+
+ abstract protected function getSimpleSymbolPrefixPattern();
+ abstract protected function getSimpleSymbolPHIDType();
+ abstract public function getSimpleSymbolConduitSearchMethodName();
+ abstract public function getSimpleSymbolInspectFunctionName();
+
+ public function getSimpleSymbolConduitSearchAttachments() {
+ return array();
+ }
+
+}
diff --git a/src/ref/simple/ArcanistSimpleSymbolRefInspector.php b/src/ref/simple/ArcanistSimpleSymbolRefInspector.php
new file mode 100644
--- /dev/null
+++ b/src/ref/simple/ArcanistSimpleSymbolRefInspector.php
@@ -0,0 +1,47 @@
+<?php
+
+final class ArcanistSimpleSymbolRefInspector
+ extends ArcanistRefInspector {
+
+ private $templateRef;
+
+ protected function newInspectors() {
+ $refs = id(new PhutilClassMapQuery())
+ ->setAncestorClass('ArcanistSimpleSymbolRef')
+ ->execute();
+
+ $inspectors = array();
+ foreach ($refs as $ref) {
+ $inspectors[] = id(new self())
+ ->setTemplateRef($ref);
+ }
+
+ return $inspectors;
+ }
+
+ public function setTemplateRef(ArcanistSimpleSymbolRef $template_ref) {
+ $this->templateRef = $template_ref;
+ return $this;
+ }
+
+ public function getTemplateRef() {
+ return $this->templateRef;
+ }
+
+ public function getInspectFunctionName() {
+ return $this->getTemplateRef()->getSimpleSymbolInspectFunctionName();
+ }
+
+ public function newInspectRef(array $argv) {
+ if (count($argv) !== 1) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Expected exactly one argument to "%s(...)" with a symbol.',
+ $this->getInspectFunctionName()));
+ }
+
+ return id(clone $this->getTemplateRef())
+ ->setSymbol($argv[0]);
+ }
+
+}
diff --git a/src/ref/symbol/ArcanistSymbolEngine.php b/src/ref/symbol/ArcanistSymbolEngine.php
--- a/src/ref/symbol/ArcanistSymbolEngine.php
+++ b/src/ref/symbol/ArcanistSymbolEngine.php
@@ -59,6 +59,17 @@
$symbols);
}
+ public function loadPasteForSymbol($symbol) {
+ $refs = $this->loadPastesForSymbols(array($symbol));
+ return head($refs)->getObject();
+ }
+
+ public function loadPastesForSymbols(array $symbols) {
+ return $this->loadRefsForSymbols(
+ new ArcanistPasteSymbolRef(),
+ $symbols);
+ }
+
public function loadRefsForSymbols(
ArcanistSymbolRef $template,
array $symbols) {
diff --git a/src/ref/task/ArcanistTaskRef.php b/src/ref/task/ArcanistTaskRef.php
new file mode 100644
--- /dev/null
+++ b/src/ref/task/ArcanistTaskRef.php
@@ -0,0 +1,44 @@
+<?php
+
+final class ArcanistTaskRef
+ extends ArcanistRef
+ implements
+ ArcanistDisplayRefInterface {
+
+ private $parameters;
+
+ public function getRefDisplayName() {
+ return pht('Task "%s"', $this->getMonogram());
+ }
+
+ public static function newFromConduit(array $parameters) {
+ $ref = new self();
+ $ref->parameters = $parameters;
+ return $ref;
+ }
+
+ public function getID() {
+ return idx($this->parameters, 'id');
+ }
+
+ public function getPHID() {
+ return idx($this->parameters, 'phid');
+ }
+
+ public function getName() {
+ return idxv($this->parameters, array('fields', 'name'));
+ }
+
+ public function getMonogram() {
+ return 'T'.$this->getID();
+ }
+
+ public function getDisplayRefObjectName() {
+ return $this->getMonogram();
+ }
+
+ public function getDisplayRefTitle() {
+ return $this->getName();
+ }
+
+}
diff --git a/src/ref/task/ArcanistTaskSymbolRef.php b/src/ref/task/ArcanistTaskSymbolRef.php
new file mode 100644
--- /dev/null
+++ b/src/ref/task/ArcanistTaskSymbolRef.php
@@ -0,0 +1,30 @@
+<?php
+
+final class ArcanistTaskSymbolRef
+ extends ArcanistSimpleSymbolRef {
+
+ public function getRefDisplayName() {
+ return pht('Task Symbol "%s"', $this->getSymbol());
+ }
+
+ protected function getSimpleSymbolPrefixPattern() {
+ return '[Tt]?';
+ }
+
+ protected function getSimpleSymbolPHIDType() {
+ return 'TASK';
+ }
+
+ public function getSimpleSymbolConduitSearchMethodName() {
+ return 'maniphest.search';
+ }
+
+ public function getSimpleSymbolInspectFunctionName() {
+ return 'task';
+ }
+
+ public function newSimpleSymbolObjectRef() {
+ return new ArcanistTaskRef();
+ }
+
+}
diff --git a/src/toolset/query/ArcanistRuntimeHardpointQuery.php b/src/toolset/query/ArcanistRuntimeHardpointQuery.php
--- a/src/toolset/query/ArcanistRuntimeHardpointQuery.php
+++ b/src/toolset/query/ArcanistRuntimeHardpointQuery.php
@@ -51,14 +51,19 @@
abstract protected function canLoadRef(ArcanistRef $ref);
- final public function newConduitSearch($method, $constraints) {
+ final public function newConduitSearch(
+ $method,
+ $constraints,
+ $attachments = array()) {
+
$conduit_engine = $this->getRuntime()
->getConduitEngine();
$conduit_future = id(new ConduitSearchFuture())
->setConduitEngine($conduit_engine)
->setMethod($method)
- ->setConstraints($constraints);
+ ->setConstraints($constraints)
+ ->setAttachments($attachments);
return $conduit_future;
}
diff --git a/src/workflow/ArcanistCallConduitWorkflow.php b/src/workflow/ArcanistCallConduitWorkflow.php
--- a/src/workflow/ArcanistCallConduitWorkflow.php
+++ b/src/workflow/ArcanistCallConduitWorkflow.php
@@ -44,13 +44,7 @@
}
$method = head($method);
- if (phutil_is_interactive()) {
- echo tsprintf(
- "%s\n",
- pht('Waiting for JSON parameters on stdin...'));
- }
-
- $params = @file_get_contents('php://stdin');
+ $params = $this->readStdin();
try {
$params = phutil_json_decode($params);
} catch (PhutilJSONParserException $ex) {
diff --git a/src/workflow/ArcanistPasteWorkflow.php b/src/workflow/ArcanistPasteWorkflow.php
--- a/src/workflow/ArcanistPasteWorkflow.php
+++ b/src/workflow/ArcanistPasteWorkflow.php
@@ -1,145 +1,137 @@
<?php
-/**
- * Upload a chunk of text to the Paste application, or download one.
- */
-final class ArcanistPasteWorkflow extends ArcanistWorkflow {
-
- private $id;
- private $language;
- private $title;
- private $json;
+final class ArcanistPasteWorkflow
+ extends ArcanistArcWorkflow {
public function getWorkflowName() {
return 'paste';
}
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **paste** [--title __title__] [--lang __language__] [--json]
- **paste** __id__ [--json]
-EOTEXT
- );
- }
-
- public function getCommandHelp() {
- return phutil_console_format(<<<EOTEXT
- Supports: text
- Share and grab text using the Paste application. To create a paste,
- use stdin to provide the text:
+ public function getWorkflowInformation() {
+ $help = pht(<<<EOTEXT
+Share and grab text using the Paste application. To create a paste,
+use stdin to provide the text:
- $ cat list_of_ducks.txt | arc paste
+ $ cat list_of_ducks.txt | arc paste
- To retrieve a paste, specify the paste ID:
+To retrieve a paste, specify the paste ID:
- $ arc paste P123
+ $ arc paste P123
EOTEXT
);
+
+ return $this->newWorkflowInformation()
+ ->addExample('**paste** [__options__] --')
+ ->addExample('**paste** [__options__] -- __object__')
+ ->setHelp($help);
}
- public function getArguments() {
+ public function getWorkflowArguments() {
return array(
- 'title' => array(
- 'param' => 'title',
- 'help' => pht('Title for the paste.'),
- ),
- 'lang' => array(
- 'param' => 'language',
- 'help' => pht('Language for syntax highlighting.'),
- ),
- 'json' => array(
- 'help' => pht('Output in JSON format.'),
- ),
- '*' => 'argv',
+ $this->newWorkflowArgument('title')
+ ->setParameter('title')
+ ->setHelp(pht('Title for the paste.')),
+ $this->newWorkflowArgument('lang')
+ ->setParameter('language')
+ ->setHelp(pht('Language for the paste.')),
+ $this->newWorkflowArgument('json')
+ ->setHelp(pht('Output in JSON format.')),
+ $this->newWorkflowArgument('argv')
+ ->setWildcard(true),
);
}
- public function requiresAuthentication() {
- return true;
- }
-
- protected function didParseArguments() {
- $this->json = $this->getArgument('json');
- $this->language = $this->getArgument('lang');
- $this->title = $this->getArgument('title');
+ public function runWorkflow() {
+ $set_language = $this->getArgument('lang');
+ $set_title = $this->getArgument('title');
$argv = $this->getArgument('argv');
if (count($argv) > 1) {
- throw new ArcanistUsageException(
- pht('Specify only one paste to retrieve.'));
- } else if (count($argv) == 1) {
- $id = $argv[0];
- if (!preg_match('/^P?\d+/', $id)) {
- throw new ArcanistUsageException(
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Specify only one paste to retrieve.'));
+ }
+
+ $symbols = $this->getSymbolEngine();
+
+ if (count($argv) === 1) {
+ if ($set_language !== null) {
+ throw new PhutilArgumentUsageException(
pht(
- 'Specify a paste ID, like %s.',
- 'P123'));
+ 'Flag "--lang" is not supported when reading pastes.'));
}
- $this->id = (int)ltrim($id, 'P');
- if ($this->language || $this->title) {
- throw new ArcanistUsageException(
+ if ($set_title !== null) {
+ throw new PhutilArgumentUsageException(
pht(
- 'Use options %s and %s only when creating pastes.',
- '--lang',
- '--title'));
+ 'Flag "--title" is not supported when reading pastes.'));
}
- }
- }
- public function run() {
- if ($this->id) {
- return $this->getPaste();
- } else {
- return $this->createPaste();
- }
- }
+ $paste_symbol = $argv[0];
- private function getPaste() {
- $conduit = $this->getConduit();
-
- $info = $conduit->callMethodSynchronous(
- 'paste.query',
- array(
- 'ids' => array($this->id),
- ));
- $info = head($info);
-
- if ($this->json) {
- echo json_encode($info)."\n";
- } else {
- echo $info['content'];
- if (!preg_match('/\\n$/', $info['content'])) {
- // If there's no newline, add one, since it looks stupid otherwise. If
- // you want byte-for-byte equivalence you can use `--json`.
- echo "\n";
+ $paste_ref = $symbols->loadPasteForSymbol($paste_symbol);
+ if (!$paste_ref) {
+ throw new PhutilArgumentUsageException(
+ pht(
+ 'Paste "%s" does not exist, or you do not have access '.
+ 'to see it.'));
}
+
+ echo $paste_ref->getContent();
+
+ return 0;
}
- return 0;
- }
+ $content = $this->readStdin();
- private function createPaste() {
- $conduit = $this->getConduit();
+ $xactions = array();
- if (!function_exists('posix_isatty') || posix_isatty(STDIN)) {
- $this->writeStatusMessage(pht('Reading paste from stdin...')."\n");
+ if ($set_title === null) {
+ $set_title = pht('Command-Line Input');
}
- $info = $conduit->callMethodSynchronous(
- 'paste.create',
- array(
- 'content' => file_get_contents('php://stdin'),
- 'title' => $this->title,
- 'language' => $this->language,
- ));
-
- if ($this->getArgument('json')) {
- echo json_encode($info)."\n";
- } else {
- echo $info['objectName'].': '.$info['uri']."\n";
+ $xactions[] = array(
+ 'type' => 'title',
+ 'value' => $set_title,
+ );
+
+ if ($set_language !== null) {
+ $xactions[] = array(
+ 'type' => 'language',
+ 'value' => $set_language,
+ );
}
+ $xactions[] = array(
+ 'type' => 'text',
+ 'value' => $content,
+ );
+
+ $method = 'paste.edit';
+
+ $parameters = array(
+ 'transactions' => $xactions,
+ );
+
+ $conduit_engine = $this->getConduitEngine();
+ $conduit_call = $conduit_engine->newCall($method, $parameters);
+ $conduit_future = $conduit_engine->newFuture($conduit_call);
+ $result = $conduit_future->resolve();
+
+ $paste_phid = idxv($result, array('object', 'phid'));
+ $paste_ref = $symbols->loadPasteForSymbol($paste_phid);
+
+ $log = $this->getLogEngine();
+
+ $log->writeSuccess(
+ pht('DONE'),
+ pht('Created a new paste.'));
+
+ echo tsprintf(
+ '%s',
+ $paste_ref->newDisplayRef()
+ ->setURI($paste_ref->getURI()));
+
return 0;
}
diff --git a/src/workflow/ArcanistWorkflow.php b/src/workflow/ArcanistWorkflow.php
--- a/src/workflow/ArcanistWorkflow.php
+++ b/src/workflow/ArcanistWorkflow.php
@@ -52,7 +52,6 @@
private $repositoryAPI;
private $configurationManager;
private $arguments = array();
- private $passedArguments = array();
private $command;
private $stashed;
@@ -777,10 +776,6 @@
return $this->arguments->getArg($key);
}
- final public function getPassedArguments() {
- return $this->passedArguments;
- }
-
final public function getCompleteArgumentSpecification() {
$spec = $this->getArguments();
$arc_config = $this->getArcanistConfiguration();
@@ -791,8 +786,6 @@
}
final public function parseArguments(array $args) {
- $this->passedArguments = $args;
-
$spec = $this->getCompleteArgumentSpecification();
$dict = array();
@@ -2411,4 +2404,21 @@
return $this->getRuntime()->getViewer();
}
+ final protected function readStdin() {
+ $log = $this->getLogEngine();
+ $log->writeWaitingForInput();
+
+ // NOTE: We can't just "file_get_contents()" here because signals don't
+ // interrupt it. If the user types "^C", we want to interrupt the read.
+
+ $raw_handle = fopen('php://stdin', 'rb');
+ $stdin = new PhutilSocketChannel($raw_handle);
+
+ while ($stdin->update()) {
+ PhutilChannel::waitForAny(array($stdin));
+ }
+
+ return $stdin->read();
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 27, 9:31 PM (4 d, 20 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7224155
Default Alt Text
D21104.id50266.diff (35 KB)
Attached To
Mode
D21104: Update "arc paste" for Toolsets
Attached
Detach File
Event Timeline
Log In to Comment