mirror of
https://we.phorge.it/source/arcanist.git
synced 2024-11-22 06:42:41 +01:00
Update "arc paste" for Toolsets
Summary: Ref T13490. More-or-less straightforward upgrade to modern calls. Test Plan: Created and viewed pastes. Maniphest Tasks: T13490 Differential Revision: https://secure.phabricator.com/D21104
This commit is contained in:
parent
c8dd2a3753
commit
d408a80ae1
22 changed files with 539 additions and 273 deletions
|
@ -189,9 +189,7 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'ArcanistRef',
|
||||
'ArcanistDisplayRefInterface',
|
||||
),
|
||||
'ArcanistFileSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||
'ArcanistFileSymbolRef' => 'ArcanistSymbolRef',
|
||||
'ArcanistFileSymbolRefInspector' => 'ArcanistRefInspector',
|
||||
'ArcanistFileSymbolRef' => 'ArcanistSimpleSymbolRef',
|
||||
'ArcanistFileUploader' => 'Phobject',
|
||||
'ArcanistFilenameLinter' => 'ArcanistLinter',
|
||||
'ArcanistFilenameLinterTestCase' => 'ArcanistLinterTestCase',
|
||||
|
@ -1343,7 +1344,12 @@ phutil_register_library_map(array(
|
|||
'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 @@ phutil_register_library_map(array(
|
|||
'ArcanistDisplayRefInterface',
|
||||
),
|
||||
'ArcanistRevisionRefSource' => 'Phobject',
|
||||
'ArcanistRevisionSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||
'ArcanistRevisionSymbolRef' => 'ArcanistSymbolRef',
|
||||
'ArcanistRevisionSymbolRefInspector' => 'ArcanistRefInspector',
|
||||
'ArcanistRevisionSymbolRef' => 'ArcanistSimpleSymbolRef',
|
||||
'ArcanistRuboCopLinter' => 'ArcanistExternalLinter',
|
||||
'ArcanistRuboCopLinterTestCase' => 'ArcanistExternalLinterTestCase',
|
||||
'ArcanistRubyLinter' => 'ArcanistExternalLinter',
|
||||
|
@ -1408,6 +1412,9 @@ phutil_register_library_map(array(
|
|||
'ArcanistSetting' => 'Phobject',
|
||||
'ArcanistSettings' => 'Phobject',
|
||||
'ArcanistShellCompleteWorkflow' => 'ArcanistWorkflow',
|
||||
'ArcanistSimpleSymbolHardpointQuery' => 'ArcanistRuntimeHardpointQuery',
|
||||
'ArcanistSimpleSymbolRef' => 'ArcanistSymbolRef',
|
||||
'ArcanistSimpleSymbolRefInspector' => 'ArcanistRefInspector',
|
||||
'ArcanistSingleLintEngine' => 'ArcanistLintEngine',
|
||||
'ArcanistSlownessXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistSlownessXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
|
@ -1423,6 +1430,11 @@ phutil_register_library_map(array(
|
|||
'ArcanistSymbolRef' => 'ArcanistRef',
|
||||
'ArcanistSyntaxErrorXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistSystemConfigurationSource' => 'ArcanistFilesystemConfigurationSource',
|
||||
'ArcanistTaskRef' => array(
|
||||
'ArcanistRef',
|
||||
'ArcanistDisplayRefInterface',
|
||||
),
|
||||
'ArcanistTaskSymbolRef' => 'ArcanistSimpleSymbolRef',
|
||||
'ArcanistTasksWorkflow' => 'ArcanistWorkflow',
|
||||
'ArcanistTautologicalExpressionXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
|
||||
'ArcanistTautologicalExpressionXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
|
||||
|
|
|
@ -6,6 +6,7 @@ final class ConduitSearchFuture
|
|||
private $conduitEngine;
|
||||
private $method;
|
||||
private $constraints;
|
||||
private $attachments;
|
||||
|
||||
private $objects = array();
|
||||
private $cursor;
|
||||
|
@ -28,7 +29,7 @@ final class ConduitSearchFuture
|
|||
return $this->method;
|
||||
}
|
||||
|
||||
public function setConstraints($constraints) {
|
||||
public function setConstraints(array $constraints) {
|
||||
$this->constraints = $constraints;
|
||||
return $this;
|
||||
}
|
||||
|
@ -37,6 +38,15 @@ final class ConduitSearchFuture
|
|||
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 @@ final class ConduitSearchFuture
|
|||
'constraints' => $constraints,
|
||||
);
|
||||
|
||||
if ($this->attachments) {
|
||||
$parameters['attachments'] = $this->attachments;
|
||||
}
|
||||
|
||||
if ($this->cursor !== null) {
|
||||
$parameters['after'] = (string)$this->cursor;
|
||||
}
|
||||
|
|
|
@ -6,11 +6,24 @@ abstract class ArcanistRefInspector
|
|||
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');
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -92,4 +92,14 @@ final class ArcanistLogEngine
|
|||
->setMessage($message));
|
||||
}
|
||||
|
||||
public function writeWaitingForInput() {
|
||||
if (!phutil_is_interactive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->writeStatus(
|
||||
pht('INPUT'),
|
||||
pht('Waiting for input on stdin...'));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ final class ArcanistDisplayRef
|
|||
ArcanistTerminalStringInterface {
|
||||
|
||||
private $ref;
|
||||
private $uri;
|
||||
|
||||
public function setRef(ArcanistRef $ref) {
|
||||
$this->ref = $ref;
|
||||
|
@ -16,6 +17,15 @@ final class ArcanistDisplayRef
|
|||
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 @@ final class ArcanistDisplayRef
|
|||
}
|
||||
|
||||
$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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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]?';
|
||||
}
|
||||
|
||||
public function getSymbolType() {
|
||||
return $this->type;
|
||||
protected function getSimpleSymbolPHIDType() {
|
||||
return 'FILE';
|
||||
}
|
||||
|
||||
protected function resolveSymbol($symbol) {
|
||||
$matches = null;
|
||||
public function getSimpleSymbolConduitSearchMethodName() {
|
||||
return 'file.search';
|
||||
}
|
||||
|
||||
$is_id = preg_match('/^[Ff]?([1-9]\d*)\z/', $symbol, $matches);
|
||||
if ($is_id) {
|
||||
$this->type = self::TYPE_ID;
|
||||
return (int)$matches[1];
|
||||
}
|
||||
public function getSimpleSymbolInspectFunctionName() {
|
||||
return 'file';
|
||||
}
|
||||
|
||||
$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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
52
src/ref/paste/ArcanistPasteRef.php
Normal file
52
src/ref/paste/ArcanistPasteRef.php
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
36
src/ref/paste/ArcanistPasteSymbolRef.php
Normal file
36
src/ref/paste/ArcanistPasteSymbolRef.php
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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]?';
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
protected function getSimpleSymbolPHIDType() {
|
||||
return 'DREV';
|
||||
}
|
||||
|
||||
return (int)$matches[1];
|
||||
public function getSimpleSymbolConduitSearchMethodName() {
|
||||
return 'differential.revision.search';
|
||||
}
|
||||
|
||||
public function getSimpleSymbolInspectFunctionName() {
|
||||
return 'revision';
|
||||
}
|
||||
|
||||
public function newSimpleSymbolObjectRef() {
|
||||
return new ArcanistRevisionRef();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
|
||||
final class ArcanistFileSymbolHardpointQuery
|
||||
final class ArcanistSimpleSymbolHardpointQuery
|
||||
extends ArcanistRuntimeHardpointQuery {
|
||||
|
||||
public function getHardpoints() {
|
||||
|
@ -10,7 +10,7 @@ final class ArcanistFileSymbolHardpointQuery
|
|||
}
|
||||
|
||||
protected function canLoadRef(ArcanistRef $ref) {
|
||||
return ($ref instanceof ArcanistFileSymbolRef);
|
||||
return ($ref instanceof ArcanistSimpleSymbolRef);
|
||||
}
|
||||
|
||||
public function loadHardpoint(array $refs, $hardpoint) {
|
||||
|
@ -19,23 +19,31 @@ final class ArcanistFileSymbolHardpointQuery
|
|||
|
||||
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 @@ final class ArcanistFileSymbolHardpointQuery
|
|||
|
||||
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 @@ final class ArcanistFileSymbolHardpointQuery
|
|||
}
|
||||
}
|
||||
|
||||
$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);
|
58
src/ref/simple/ArcanistSimpleSymbolRef.php
Normal file
58
src/ref/simple/ArcanistSimpleSymbolRef.php
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
47
src/ref/simple/ArcanistSimpleSymbolRefInspector.php
Normal file
47
src/ref/simple/ArcanistSimpleSymbolRefInspector.php
Normal file
|
@ -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]);
|
||||
}
|
||||
|
||||
}
|
|
@ -59,6 +59,17 @@ final class ArcanistSymbolEngine
|
|||
$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) {
|
||||
|
|
44
src/ref/task/ArcanistTaskRef.php
Normal file
44
src/ref/task/ArcanistTaskRef.php
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
30
src/ref/task/ArcanistTaskSymbolRef.php
Normal file
30
src/ref/task/ArcanistTaskSymbolRef.php
Normal file
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -51,14 +51,19 @@ abstract class ArcanistRuntimeHardpointQuery
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -44,13 +44,7 @@ EOTEXT
|
|||
}
|
||||
$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) {
|
||||
|
|
|
@ -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]
|
||||
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
|
||||
|
||||
To retrieve a paste, specify the paste ID:
|
||||
|
||||
$ arc paste P123
|
||||
EOTEXT
|
||||
);
|
||||
|
||||
return $this->newWorkflowInformation()
|
||||
->addExample('**paste** [__options__] --')
|
||||
->addExample('**paste** [__options__] -- __object__')
|
||||
->setHelp($help);
|
||||
}
|
||||
|
||||
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:
|
||||
|
||||
$ cat list_of_ducks.txt | arc paste
|
||||
|
||||
To retrieve a paste, specify the paste ID:
|
||||
|
||||
$ arc paste P123
|
||||
EOTEXT
|
||||
);
|
||||
}
|
||||
|
||||
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,
|
||||
));
|
||||
$xactions[] = array(
|
||||
'type' => 'title',
|
||||
'value' => $set_title,
|
||||
);
|
||||
|
||||
if ($this->getArgument('json')) {
|
||||
echo json_encode($info)."\n";
|
||||
} else {
|
||||
echo $info['objectName'].': '.$info['uri']."\n";
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,6 @@ abstract class ArcanistWorkflow extends Phobject {
|
|||
private $repositoryAPI;
|
||||
private $configurationManager;
|
||||
private $arguments = array();
|
||||
private $passedArguments = array();
|
||||
private $command;
|
||||
|
||||
private $stashed;
|
||||
|
@ -777,10 +776,6 @@ abstract class ArcanistWorkflow extends Phobject {
|
|||
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 @@ abstract class ArcanistWorkflow extends Phobject {
|
|||
}
|
||||
|
||||
final public function parseArguments(array $args) {
|
||||
$this->passedArguments = $args;
|
||||
|
||||
$spec = $this->getCompleteArgumentSpecification();
|
||||
|
||||
$dict = array();
|
||||
|
@ -2411,4 +2404,21 @@ abstract class ArcanistWorkflow extends Phobject {
|
|||
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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue