Skip to content

Commit

Permalink
Port "arc prompts" from wilds and fix a path issue in shell completion
Browse files Browse the repository at this point in the history
Summary:
Ref T13490. Bring "arc prompts" from "wilds" and hook it into the prompt in "arc shell-complete".

See D21069. Fix an issue where the shell hook tested for a path other than the path it writes to.

Test Plan: Ran "arc shell-complete" with no hook and got a prompt. Shell completed things. Ran "arc prompts shell-complete".

Maniphest Tasks: T13490

Differential Revision: https://secure.phabricator.com/D21085
  • Loading branch information
epriestley committed Apr 11, 2020
1 parent 387027e commit ccd1ebb
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 3 deletions.
2 changes: 2 additions & 0 deletions src/__phutil_library_map__.php
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@
'ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase.php',
'ArcanistProjectConfigurationSource' => 'config/source/ArcanistProjectConfigurationSource.php',
'ArcanistPrompt' => 'toolset/ArcanistPrompt.php',
'ArcanistPromptsWorkflow' => 'toolset/workflow/ArcanistPromptsWorkflow.php',
'ArcanistPublicPropertyXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPublicPropertyXHPASTLinterRule.php',
'ArcanistPublicPropertyXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPublicPropertyXHPASTLinterRuleTestCase.php',
'ArcanistPuppetLintLinter' => 'lint/linter/ArcanistPuppetLintLinter.php',
Expand Down Expand Up @@ -1330,6 +1331,7 @@
'ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistProjectConfigurationSource' => 'ArcanistWorkingCopyConfigurationSource',
'ArcanistPrompt' => 'Phobject',
'ArcanistPromptsWorkflow' => 'ArcanistWorkflow',
'ArcanistPublicPropertyXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPublicPropertyXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPuppetLintLinter' => 'ArcanistExternalLinter',
Expand Down
80 changes: 80 additions & 0 deletions src/toolset/workflow/ArcanistPromptsWorkflow.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

final class ArcanistPromptsWorkflow extends ArcanistWorkflow {

public function supportsToolset(ArcanistToolset $toolset) {
return true;
}

public function getWorkflowName() {
return 'prompts';
}

public function getWorkflowInformation() {
$help = pht(<<<EOTEXT
Show information about prompts a workflow may execute and configure default
responses.
**Show Prompts**
To show possible prompts a workflow may execute, run:
$ arc prompts <workflow>
EOTEXT
);

return $this->newWorkflowInformation()
->addExample(pht('**prompts** __workflow__'))
->setHelp($help);
}

public function getWorkflowArguments() {
return array(
$this->newWorkflowArgument('argv')
->setWildcard(true),
);
}

public function runWorkflow() {
$argv = $this->getArgument('argv');

if (!$argv) {
throw new PhutilArgumentUsageException(
pht('Provide a workflow to list prompts for.'));
}

$runtime = $this->getRuntime();
$workflows = $runtime->getWorkflows();

$workflow_key = array_shift($argv);
$workflow = idx($workflows, $workflow_key);

if (!$workflow) {
throw new PhutilArgumentUsageException(
pht(
'Workflow "%s" is unknown. Supported workflows are: %s.',
$workflow_key,
implode(', ', array_keys($workflows))));
}

$prompts = $workflow->getPromptMap();
if (!$prompts) {
echo tsprintf(
"%s\n",
pht('This workflow does not have any prompts.'));
return 0;
}

foreach ($prompts as $prompt) {
echo tsprintf(
"**%s**\n",
$prompt->getKey());
echo tsprintf(
"%s\n",
$prompt->getDescription());
}

return 0;
}

}
5 changes: 4 additions & 1 deletion src/toolset/workflow/ArcanistShellCompleteWorkflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,10 @@ private function runInstall() {

$log->writeSuccess(
pht('INSTALL'),
pht('Installing shell completion support for "%s".', $shell));
pht(
'Installing shell completion support for "%s" into "%s".',
$shell,
$file_display));

if ($replace) {
$replace_pos = $matches[0][1];
Expand Down
60 changes: 60 additions & 0 deletions src/workflow/ArcanistWorkflow.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ abstract class ArcanistWorkflow extends Phobject {
private $configurationSourceList;

private $hardpointEngine;
private $promptMap;

final public function setToolset(ArcanistToolset $toolset) {
$this->toolset = $toolset;
Expand Down Expand Up @@ -2333,4 +2334,63 @@ private function newHardpointEngine() {
return $engine;
}

protected function newPrompts() {
return array();
}

protected function newPrompt($key) {
return id(new ArcanistPrompt())
->setWorkflow($this)
->setKey($key);
}

public function hasPrompt($key) {
$map = $this->getPromptMap();
return isset($map[$key]);
}

public function getPromptMap() {
if ($this->promptMap === null) {
$prompts = $this->newPrompts();
assert_instances_of($prompts, 'ArcanistPrompt');

$map = array();
foreach ($prompts as $prompt) {
$key = $prompt->getKey();

if (isset($map[$key])) {
throw new Exception(
pht(
'Workflow ("%s") generates two prompts with the same '.
'key ("%s"). Each prompt a workflow generates must have a '.
'unique key.',
get_class($this),
$key));
}

$map[$key] = $prompt;
}

$this->promptMap = $map;
}

return $this->promptMap;
}

protected function getPrompt($key) {
$map = $this->getPromptMap();

$prompt = idx($map, $key);
if (!$prompt) {
throw new Exception(
pht(
'Workflow ("%s") is requesting a prompt ("%s") but it did not '.
'generate any prompt with that name in "newPrompts()".',
get_class($this),
$key));
}

return clone $prompt;
}

}
5 changes: 3 additions & 2 deletions support/shell/hooks/bash-completion.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" > /dev/null && pwd )"
GENERATED_RULES_FILE="${SCRIPTDIR}/../rules/bash-rules.sh"

# Try to generate the shell completion rules if they do not yet exist.
if [ ! -f "${SCRIPTDIR}/bash-rules.sh" ]; then
if [ ! -f "${GENERATED_RULES_FILE}" ]; then
arc shell-complete --generate >/dev/null 2>/dev/null
fi;

# Source the shell completion rules.
source "${SCRIPTDIR}/../rules/bash-rules.sh"
source "${GENERATED_RULES_FILE}"

0 comments on commit ccd1ebb

Please sign in to comment.