Page MenuHomePhabricator

D19678.id47021.diff
No OneTemporary

D19678.id47021.diff

Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -15,9 +15,11 @@
'ArcanistAbstractPrivateMethodXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistAbstractPrivateMethodXHPASTLinterRuleTestCase.php',
'ArcanistAliasFunctionXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistAliasFunctionXHPASTLinterRule.php',
'ArcanistAliasFunctionXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistAliasFunctionXHPASTLinterRuleTestCase.php',
- 'ArcanistAliasWorkflow' => 'workflow/ArcanistAliasWorkflow.php',
+ 'ArcanistAliasWorkflow' => 'toolset/ArcanistAliasWorkflow.php',
'ArcanistAmendWorkflow' => 'workflow/ArcanistAmendWorkflow.php',
'ArcanistAnoidWorkflow' => 'workflow/ArcanistAnoidWorkflow.php',
+ 'ArcanistArcToolset' => 'toolset/ArcanistArcToolset.php',
+ 'ArcanistArcWorkflow' => 'workflow/ArcanistArcWorkflow.php',
'ArcanistArrayCombineXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistArrayCombineXHPASTLinterRule.php',
'ArcanistArrayCombineXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistArrayCombineXHPASTLinterRuleTestCase.php',
'ArcanistArrayIndexSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistArrayIndexSpacingXHPASTLinterRule.php',
@@ -96,7 +98,6 @@
'ArcanistConcatenationOperatorXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistConcatenationOperatorXHPASTLinterRuleTestCase.php',
'ArcanistConduitCall' => 'conduit/ArcanistConduitCall.php',
'ArcanistConduitEngine' => 'conduit/ArcanistConduitEngine.php',
- 'ArcanistConfiguration' => 'configuration/ArcanistConfiguration.php',
'ArcanistConfigurationDrivenLintEngine' => 'lint/engine/ArcanistConfigurationDrivenLintEngine.php',
'ArcanistConfigurationDrivenUnitTestEngine' => 'unit/engine/ArcanistConfigurationDrivenUnitTestEngine.php',
'ArcanistConfigurationManager' => 'configuration/ArcanistConfigurationManager.php',
@@ -186,7 +187,6 @@
'ArcanistHLintLinter' => 'lint/linter/ArcanistHLintLinter.php',
'ArcanistHLintLinterTestCase' => 'lint/linter/__tests__/ArcanistHLintLinterTestCase.php',
'ArcanistHardpointLoader' => 'loader/ArcanistHardpointLoader.php',
- 'ArcanistHelpWorkflow' => 'workflow/ArcanistHelpWorkflow.php',
'ArcanistHexadecimalNumericScalarCasingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistHexadecimalNumericScalarCasingXHPASTLinterRule.php',
'ArcanistHexadecimalNumericScalarCasingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistHexadecimalNumericScalarCasingXHPASTLinterRuleTestCase.php',
'ArcanistHgClientChannel' => 'hgdaemon/ArcanistHgClientChannel.php',
@@ -310,6 +310,7 @@
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistParseStrUseXHPASTLinterRuleTestCase.php',
'ArcanistPasteWorkflow' => 'workflow/ArcanistPasteWorkflow.php',
'ArcanistPatchWorkflow' => 'workflow/ArcanistPatchWorkflow.php',
+ 'ArcanistPhageToolset' => 'toolset/ArcanistPhageToolset.php',
'ArcanistPhpLinter' => 'lint/linter/ArcanistPhpLinter.php',
'ArcanistPhpLinterTestCase' => 'lint/linter/__tests__/ArcanistPhpLinterTestCase.php',
'ArcanistPhpcsLinter' => 'lint/linter/ArcanistPhpcsLinter.php',
@@ -317,6 +318,7 @@
'ArcanistPhpunitTestResultParser' => 'unit/parser/ArcanistPhpunitTestResultParser.php',
'ArcanistPhrequentWorkflow' => 'workflow/ArcanistPhrequentWorkflow.php',
'ArcanistPhutilLibraryLinter' => 'lint/linter/ArcanistPhutilLibraryLinter.php',
+ 'ArcanistPhutilWorkflow' => 'toolset/ArcanistPhutilWorkflow.php',
'ArcanistPhutilXHPASTLinterStandard' => 'lint/linter/standards/phutil/ArcanistPhutilXHPASTLinterStandard.php',
'ArcanistPlusOperatorOnStringsXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistPlusOperatorOnStringsXHPASTLinterRule.php',
'ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase.php',
@@ -361,7 +363,7 @@
'ArcanistSetConfigWorkflow' => 'workflow/ArcanistSetConfigWorkflow.php',
'ArcanistSetting' => 'configuration/ArcanistSetting.php',
'ArcanistSettings' => 'configuration/ArcanistSettings.php',
- 'ArcanistShellCompleteWorkflow' => 'workflow/ArcanistShellCompleteWorkflow.php',
+ 'ArcanistShellCompleteWorkflow' => 'toolset/ArcanistShellCompleteWorkflow.php',
'ArcanistSingleLintEngine' => 'lint/engine/ArcanistSingleLintEngine.php',
'ArcanistSlownessXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistSlownessXHPASTLinterRule.php',
'ArcanistSlownessXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistSlownessXHPASTLinterRuleTestCase.php',
@@ -389,6 +391,7 @@
'ArcanistTodoCommentXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistTodoCommentXHPASTLinterRule.php',
'ArcanistTodoCommentXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistTodoCommentXHPASTLinterRuleTestCase.php',
'ArcanistTodoWorkflow' => 'workflow/ArcanistTodoWorkflow.php',
+ 'ArcanistToolset' => 'toolset/ArcanistToolset.php',
'ArcanistUSEnglishTranslation' => 'internationalization/ArcanistUSEnglishTranslation.php',
'ArcanistUnableToParseXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistUnableToParseXHPASTLinterRule.php',
'ArcanistUnaryPostfixExpressionSpacingXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistUnaryPostfixExpressionSpacingXHPASTLinterRule.php',
@@ -425,10 +428,10 @@
'ArcanistVariableReferenceSpacingXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistVariableReferenceSpacingXHPASTLinterRuleTestCase.php',
'ArcanistVariableVariableXHPASTLinterRule' => 'lint/linter/xhpast/rules/ArcanistVariableVariableXHPASTLinterRule.php',
'ArcanistVariableVariableXHPASTLinterRuleTestCase' => 'lint/linter/xhpast/rules/__tests__/ArcanistVariableVariableXHPASTLinterRuleTestCase.php',
- 'ArcanistVersionWorkflow' => 'workflow/ArcanistVersionWorkflow.php',
+ 'ArcanistVersionWorkflow' => 'toolset/ArcanistVersionWorkflow.php',
'ArcanistWeldWorkflow' => 'workflow/ArcanistWeldWorkflow.php',
'ArcanistWhichWorkflow' => 'workflow/ArcanistWhichWorkflow.php',
- 'ArcanistWorkflow' => 'workflow/ArcanistWorkflow.php',
+ 'ArcanistWorkflow' => 'toolset/ArcanistWorkflow.php',
'ArcanistWorkingCopyIdentity' => 'workingcopyidentity/ArcanistWorkingCopyIdentity.php',
'ArcanistWorkingCopyStateRef' => 'ref/ArcanistWorkingCopyStateRef.php',
'ArcanistXHPASTLintNamingHook' => 'lint/linter/xhpast/ArcanistXHPASTLintNamingHook.php',
@@ -467,6 +470,8 @@
'ArcanistAliasWorkflow' => 'ArcanistWorkflow',
'ArcanistAmendWorkflow' => 'ArcanistWorkflow',
'ArcanistAnoidWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistArcToolset' => 'ArcanistToolset',
+ 'ArcanistArcWorkflow' => 'ArcanistWorkflow',
'ArcanistArrayCombineXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistArrayCombineXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistArrayIndexSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
@@ -545,7 +550,6 @@
'ArcanistConcatenationOperatorXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistConduitCall' => 'Phobject',
'ArcanistConduitEngine' => 'Phobject',
- 'ArcanistConfiguration' => 'Phobject',
'ArcanistConfigurationDrivenLintEngine' => 'ArcanistLintEngine',
'ArcanistConfigurationDrivenUnitTestEngine' => 'ArcanistUnitTestEngine',
'ArcanistConfigurationManager' => 'Phobject',
@@ -635,7 +639,6 @@
'ArcanistHLintLinter' => 'ArcanistExternalLinter',
'ArcanistHLintLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistHardpointLoader' => 'Phobject',
- 'ArcanistHelpWorkflow' => 'ArcanistWorkflow',
'ArcanistHexadecimalNumericScalarCasingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistHexadecimalNumericScalarCasingXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistHgClientChannel' => 'PhutilProtocolChannel',
@@ -759,6 +762,7 @@
'ArcanistParseStrUseXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistPasteWorkflow' => 'ArcanistWorkflow',
'ArcanistPatchWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistPhageToolset' => 'ArcanistToolset',
'ArcanistPhpLinter' => 'ArcanistExternalLinter',
'ArcanistPhpLinterTestCase' => 'ArcanistExternalLinterTestCase',
'ArcanistPhpcsLinter' => 'ArcanistExternalLinter',
@@ -766,6 +770,7 @@
'ArcanistPhpunitTestResultParser' => 'ArcanistTestResultParser',
'ArcanistPhrequentWorkflow' => 'ArcanistWorkflow',
'ArcanistPhutilLibraryLinter' => 'ArcanistLinter',
+ 'ArcanistPhutilWorkflow' => 'PhutilArgumentWorkflow',
'ArcanistPhutilXHPASTLinterStandard' => 'ArcanistLinterStandard',
'ArcanistPlusOperatorOnStringsXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistPlusOperatorOnStringsXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
@@ -838,6 +843,7 @@
'ArcanistTodoCommentXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistTodoCommentXHPASTLinterRuleTestCase' => 'ArcanistXHPASTLinterRuleTestCase',
'ArcanistTodoWorkflow' => 'ArcanistWorkflow',
+ 'ArcanistToolset' => 'Phobject',
'ArcanistUSEnglishTranslation' => 'PhutilTranslation',
'ArcanistUnableToParseXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
'ArcanistUnaryPostfixExpressionSpacingXHPASTLinterRule' => 'ArcanistXHPASTLinterRule',
Index: src/configuration/ArcanistConfiguration.php
===================================================================
--- src/configuration/ArcanistConfiguration.php
+++ /dev/null
@@ -1,187 +0,0 @@
-<?php
-
-/**
- * Runtime workflow configuration. In Arcanist, commands you type like
- * "arc diff" or "arc lint" are called "workflows". This class allows you to add
- * new workflows (and extend existing workflows) by subclassing it and then
- * pointing to your subclass in your project configuration.
- *
- * When specified as the **arcanist_configuration** class in your project's
- * ##.arcconfig##, your subclass will be instantiated (instead of this class)
- * and be able to handle all the method calls. In particular, you can:
- *
- * - create, replace, or disable workflows by overriding buildWorkflow()
- * and buildAllWorkflows();
- * - add additional steps before or after workflows run by overriding
- * willRunWorkflow() or didRunWorkflow() or didAbortWorkflow(); and
- * - add new flags to existing workflows by overriding
- * getCustomArgumentsForCommand().
- *
- * @concrete-extensible
- */
-class ArcanistConfiguration extends Phobject {
-
- public function buildWorkflow($command) {
- if ($command == '--help') {
- // Special-case "arc --help" to behave like "arc help" instead of telling
- // you to type "arc help" without being helpful.
- $command = 'help';
- } else if ($command == '--version') {
- // Special-case "arc --version" to behave like "arc version".
- $command = 'version';
- }
-
- $workflow = idx($this->buildAllWorkflows(), $command);
-
- if (!$workflow) {
- return null;
- }
-
- return clone $workflow;
- }
-
- public function buildAllWorkflows() {
- return id(new PhutilClassMapQuery())
- ->setAncestorClass('ArcanistWorkflow')
- ->setUniqueMethod('getWorkflowName')
- ->execute();
- }
-
- final public function isValidWorkflow($workflow) {
- return (bool)$this->buildWorkflow($workflow);
- }
-
- public function willRunWorkflow($command, ArcanistWorkflow $workflow) {
- // This is a hook.
- }
-
- public function didRunWorkflow($command, ArcanistWorkflow $workflow, $err) {
-
- // This is a hook.
- }
-
- public function didAbortWorkflow($command, $workflow, Exception $ex) {
- // This is a hook.
- }
-
- public function getCustomArgumentsForCommand($command) {
- return array();
- }
-
- final public function selectWorkflow(
- &$command,
- array &$args,
- ArcanistConfigurationManager $configuration_manager,
- PhutilConsole $console) {
-
- // First, try to build a workflow with the exact name provided. We always
- // pick an exact match, and do not allow aliases to override it.
- $workflow = $this->buildWorkflow($command);
- if ($workflow) {
- return $workflow;
- }
-
- // If the user has an alias, like 'arc alias dhelp diff help', look it up
- // and substitute it. We do this only after trying to resolve the workflow
- // normally to prevent you from doing silly things like aliasing 'alias'
- // to something else.
- $aliases = ArcanistAliasWorkflow::getAliases($configuration_manager);
- list($new_command, $args) = ArcanistAliasWorkflow::resolveAliases(
- $command,
- $this,
- $args,
- $configuration_manager);
-
- $full_alias = idx($aliases, $command, array());
- $full_alias = implode(' ', $full_alias);
-
- // Run shell command aliases.
- if (ArcanistAliasWorkflow::isShellCommandAlias($new_command)) {
- $shell_cmd = substr($full_alias, 1);
-
- $console->writeLog(
- "[%s: 'arc %s' -> $ %s]",
- pht('alias'),
- $command,
- $shell_cmd);
-
- if ($args) {
- $err = phutil_passthru('%C %Ls', $shell_cmd, $args);
- } else {
- $err = phutil_passthru('%C', $shell_cmd);
- }
-
- exit($err);
- }
-
- // Run arc command aliases.
- if ($new_command) {
- $workflow = $this->buildWorkflow($new_command);
- if ($workflow) {
- $console->writeLog(
- "[%s: 'arc %s' -> 'arc %s']\n",
- pht('alias'),
- $command,
- $full_alias);
- $command = $new_command;
- return $workflow;
- }
- }
-
- $all = array_keys($this->buildAllWorkflows());
-
- // We haven't found a real command or an alias, so try to locate a command
- // by unique prefix.
- $prefixes = $this->expandCommandPrefix($command, $all);
-
- if (count($prefixes) == 1) {
- $command = head($prefixes);
- return $this->buildWorkflow($command);
- } else if (count($prefixes) > 1) {
- $this->raiseUnknownCommand($command, $prefixes);
- }
-
-
- // We haven't found a real command, alias, or unique prefix. Try similar
- // spellings.
- $corrected = PhutilArgumentSpellingCorrector::newCommandCorrector()
- ->correctSpelling($command, $all);
- if (count($corrected) == 1) {
- $console->writeErr(
- pht(
- "(Assuming '%s' is the British spelling of '%s'.)",
- $command,
- head($corrected))."\n");
- $command = head($corrected);
- return $this->buildWorkflow($command);
- } else if (count($corrected) > 1) {
- $this->raiseUnknownCommand($command, $corrected);
- }
-
- $this->raiseUnknownCommand($command);
- }
-
- private function raiseUnknownCommand($command, array $maybe = array()) {
- $message = pht("Unknown command '%s'. Try '%s'.", $command, 'arc help');
- if ($maybe) {
- $message .= "\n\n".pht('Did you mean:')."\n";
- sort($maybe);
- foreach ($maybe as $other) {
- $message .= " ".$other."\n";
- }
- }
- throw new ArcanistUsageException($message);
- }
-
- private function expandCommandPrefix($command, array $options) {
- $is_prefix = array();
- foreach ($options as $option) {
- if (strncmp($option, $command, strlen($command)) == 0) {
- $is_prefix[$option] = true;
- }
- }
-
- return array_keys($is_prefix);
- }
-
-}
Index: src/configuration/ArcanistConfigurationManager.php
===================================================================
--- src/configuration/ArcanistConfigurationManager.php
+++ src/configuration/ArcanistConfigurationManager.php
@@ -146,6 +146,10 @@
return $this;
}
+ public function getRuntimeConfig($key, $default = null) {
+ return idx($this->runtimeConfig, $key, $default);
+ }
+
/* -( Read/write config )--------------------------------------------------- */
public function readLocalArcConfig() {
Index: src/toolset/ArcanistAliasWorkflow.php
===================================================================
--- src/toolset/ArcanistAliasWorkflow.php
+++ src/toolset/ArcanistAliasWorkflow.php
@@ -9,46 +9,50 @@
return 'alias';
}
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **alias**
- **alias** __command__
- **alias** __command__ __target__ -- [__options__]
-EOTEXT
- );
+ public function supportsToolset(ArcanistToolset $toolset) {
+ return true;
}
- public function getCommandHelp() {
- return phutil_console_format(<<<EOTEXT
- Supports: cli
- Create an alias from __command__ to __target__ (optionally, with
- __options__). For example:
+ public function getWorkflowSynopses() {
+ return array(
+ pht('**alias**'),
+ pht('**alias** __command__'),
+ pht('**alias** __command__ __target__ -- [__options__]'),
+ );
+ }
+
+ public function getWorkflowHelp() {
+ return pht(<<<EOTEXT
+Supports: cli
+Create an alias from __command__ to __target__ (optionally, with __options__).
+For example:
- arc alias fpatch patch -- --force
+ %s alias fpatch patch -- --force
- ...will create a new 'arc' command, 'arc fpatch', which invokes
- 'arc patch --force ...' when run. NOTE: use "--" before specifying
- options!
+...will create a new 'arc' command, 'arc fpatch', which invokes
+'arc patch --force ...' when run. NOTE: use "--" before specifying
+options!
- If you start an alias with "!", the remainder of the alias will be
- invoked as a shell command. For example, if you want to implement
- 'arc ls', you can do so like this:
+If you start an alias with "!", the remainder of the alias will be
+invoked as a shell command. For example, if you want to implement
+'arc ls', you can do so like this:
- arc alias ls '!ls'
+ %s alias ls '!ls'
- You can now run "arc ls" and it will behave like "ls". Of course, this
- example is silly and would make your life worse.
+You can now run "arc ls" and it will behave like "ls". Of course, this
+example is silly and would make your life worse.
- You can not overwrite builtins, including 'alias' itself. The builtin
- will always execute, even if it was added after your alias.
+You can not overwrite builtins, including 'alias' itself. The builtin
+will always execute, even if it was added after your alias.
- To remove an alias, run:
+To remove an alias, run:
- arc alias fpatch
+ arc alias fpatch
- Without any arguments, 'arc alias' will list aliases.
+Without any arguments, 'arc alias' will list aliases.
EOTEXT
- );
+ ,
+ $this->getToolsetName());
}
public function getArguments() {
@@ -75,7 +79,7 @@
$this->getConfigurationManager()->writeUserConfigurationFile($config);
}
- public function run() {
+ public function runWorkflow() {
$aliases = self::getAliases($this->getConfigurationManager());
$argv = $this->getArgument('argv');
Index: src/toolset/ArcanistArcToolset.php
===================================================================
--- /dev/null
+++ src/toolset/ArcanistArcToolset.php
@@ -0,0 +1,26 @@
+<?php
+
+final class ArcanistArcToolset extends ArcanistToolset {
+
+ const TOOLSETKEY = 'arc';
+
+ public function getToolsetArguments() {
+ return array(
+ array(
+ 'name' => 'conduit-uri',
+ 'param' => 'uri',
+ 'help' => pht('Connect to Phabricator install specified by __uri__.'),
+ ),
+ array(
+ 'name' => 'conduit-token',
+ 'param' => 'token',
+ 'help' => pht('Use a specific authentication token.'),
+ ),
+ array(
+ 'name' => 'anonymous',
+ 'help' => pht('Run workflow as a public user, without authenticating.'),
+ ),
+ );
+ }
+
+}
Index: src/toolset/ArcanistPhageToolset.php
===================================================================
--- /dev/null
+++ src/toolset/ArcanistPhageToolset.php
@@ -0,0 +1,8 @@
+<?php
+
+final class ArcanistPhageToolset extends ArcanistToolset {
+
+ const TOOLSETKEY = 'phage';
+
+
+}
Index: src/toolset/ArcanistPhutilWorkflow.php
===================================================================
--- /dev/null
+++ src/toolset/ArcanistPhutilWorkflow.php
@@ -0,0 +1,24 @@
+<?php
+
+final class ArcanistPhutilWorkflow extends PhutilArgumentWorkflow {
+
+ private $workflow;
+
+ public function setWorkflow(ArcanistWorkflow $workflow) {
+ $this->workflow = $workflow;
+ return $this;
+ }
+
+ public function getWorkflow() {
+ return $this->workflow;
+ }
+
+ public function isExecutable() {
+ return true;
+ }
+
+ public function execute(PhutilArgumentParser $args) {
+ return $this->getWorkflow()->executeWorkflow($args);
+ }
+
+}
Index: src/toolset/ArcanistShellCompleteWorkflow.php
===================================================================
--- src/toolset/ArcanistShellCompleteWorkflow.php
+++ src/toolset/ArcanistShellCompleteWorkflow.php
@@ -5,22 +5,24 @@
*/
final class ArcanistShellCompleteWorkflow extends ArcanistWorkflow {
+ public function supportsToolset(ArcanistToolset $toolset) {
+ return true;
+ }
+
public function getWorkflowName() {
return 'shell-complete';
}
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **shell-complete** __--current__ __N__ -- [__argv__]
-EOTEXT
- );
+ public function getWorkflowSynopses() {
+ return array(
+ pht('**shell-complete** __--current__ __N__ -- [__argv__]'),
+ );
}
- public function getCommandHelp() {
- return phutil_console_format(<<<EOTEXT
- Supports: bash, etc.
- Implements shell completion. To use shell completion, source the
- appropriate script from 'resources/shell/' in your .shellrc.
+ public function getWorkflowHelp() {
+ return pht(<<<EOTEXT
+Implements shell completion. To use shell completion, source the appropriate
+script from 'resources/shell/' in your .shellrc.
EOTEXT
);
}
Index: src/toolset/ArcanistToolset.php
===================================================================
--- /dev/null
+++ src/toolset/ArcanistToolset.php
@@ -0,0 +1,22 @@
+<?php
+
+abstract class ArcanistToolset extends Phobject {
+
+ final public function getToolsetKey() {
+ return $this->getPhobjectClassConstant('TOOLSETKEY');
+ }
+
+ final public static function newToolsetMap() {
+ $toolsets = id(new PhutilClassMapQuery())
+ ->setAncestorClass(__CLASS__)
+ ->setUniqueMethod('getToolsetKey')
+ ->execute();
+
+ return $toolsets;
+ }
+
+ public function getToolsetArguments() {
+ return array();
+ }
+
+}
Index: src/toolset/ArcanistVersionWorkflow.php
===================================================================
--- src/toolset/ArcanistVersionWorkflow.php
+++ src/toolset/ArcanistVersionWorkflow.php
@@ -5,26 +5,31 @@
*/
final class ArcanistVersionWorkflow extends ArcanistWorkflow {
+ public function supportsToolset(ArcanistToolset $toolset) {
+ return true;
+ }
+
public function getWorkflowName() {
return 'version';
}
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **version** [__options__]
-EOTEXT
- );
+ public function getWorkflowSynopses() {
+ return array(
+ '**version**',
+ );
}
- public function getCommandHelp() {
- return phutil_console_format(pht(<<<EOTEXT
- Supports: cli
- Shows the current version of arcanist.
+ public function getWorkflowHelp() {
+ return pht(<<<EOTEXT
+Shows the current version of **%s**.
EOTEXT
- ));
+ ,
+ $this->getToolsetKey());
}
public function run() {
+ // TODO: Show the toolset version, not just the "arc" version.
+
$console = PhutilConsole::getConsole();
if (!Filesystem::binaryExists('git')) {
Index: src/toolset/ArcanistWorkflow.php
===================================================================
--- /dev/null
+++ src/toolset/ArcanistWorkflow.php
@@ -0,0 +1,88 @@
+<?php
+
+abstract class ArcanistWorkflow extends Phobject {
+
+ private $toolset;
+ private $arguments;
+
+
+ /**
+ * Return the command used to invoke this workflow from the command like,
+ * e.g. "help" for @{class:ArcanistHelpWorkflow}.
+ *
+ * @return string The command a user types to invoke this workflow.
+ */
+ abstract public function getWorkflowName();
+
+ protected function runWorkflow() {
+ // TOOLSETS: Temporary to get this working.
+ throw new PhutilMethodNotImplementedException();
+ }
+
+ protected function runWorkflowCleanup() {
+ // TOOLSETS: Do we need this?
+ return;
+ }
+
+ /**
+ * Return true if this workflow belongs to the given toolset. Toolsets let
+ * you move a set of "arc" commands under some other command.
+ *
+ * @param ArcanistToolset Current selected toolset.
+ * @return bool True if this command supports the provided toolset.
+ */
+ public function supportsToolset(ArcanistToolset $toolset) {
+ // TOOLSETS: Temporary!
+ return true;
+ }
+
+ public function newPhutilWorkflow() {
+ return id(new ArcanistPhutilWorkflow())
+ ->setName($this->getWorkflowName())
+ ->setWorkflow($this);
+ }
+
+ final public function getToolset() {
+ return $this->toolset;
+ }
+
+ final public function setToolset(ArcanistToolset $toolset) {
+ $this->toolset = $toolset;
+ return $this;
+ }
+
+ final protected function getToolsetKey() {
+ return $this->getToolset()->getToolsetKey();
+ }
+
+ final public function executeWorkflow(PhutilArgumentParser $args) {
+ $this->arguments = $args;
+ $caught = null;
+
+ try {
+ $err = $this->runWorkflow($args);
+ } catch (Exception $ex) {
+ $caught = $ex;
+ }
+
+ try {
+ $this->runWorkflowCleanup();
+ } catch (Exception $ex) {
+ phlog($ex);
+ }
+
+ if ($caught) {
+ throw $caught;
+ }
+
+ return $err;
+ }
+
+ final public function getArgument($key, $default = null) {
+ // TOOLSETS: This is a stub for now.
+ return $default;
+
+ return $this->arguments->getArg($key, $default);
+ }
+
+}
Index: src/workflow/ArcanistArcWorkflow.php
===================================================================
--- src/workflow/ArcanistArcWorkflow.php
+++ src/workflow/ArcanistArcWorkflow.php
@@ -33,7 +33,7 @@
* @task scratch Scratch Files
* @task phabrep Phabricator Repositories
*/
-abstract class ArcanistWorkflow extends Phobject {
+abstract class ArcanistArcWorkflow extends ArcanistWorkflow {
const COMMIT_DISABLE = 0;
const COMMIT_ALLOW = 1;
@@ -52,8 +52,6 @@
private $userName;
private $repositoryAPI;
private $configurationManager;
- private $arguments = array();
- private $passedArguments = array();
private $command;
private $stashed;
@@ -72,11 +70,9 @@
private $changeCache = array();
private $conduitEngine;
-
- public function __construct() {}
-
-
- abstract public function run();
+ final public function supportsToolset(ArcanistToolset $toolset) {
+ return ($toolset->getToolsetKey() === 'arc');
+ }
/**
* Finalizes any cleanup operations that need to occur regardless of
@@ -86,27 +82,6 @@
$this->finalizeWorkingCopy();
}
- /**
- * Return the command used to invoke this workflow from the command like,
- * e.g. "help" for @{class:ArcanistHelpWorkflow}.
- *
- * @return string The command a user types to invoke this workflow.
- */
- abstract public function getWorkflowName();
-
- /**
- * Return console formatted string with all command synopses.
- *
- * @return string 6-space indented list of available command synopses.
- */
- abstract public function getCommandSynopses();
-
- /**
- * Return console formatted string with command help printed in `arc help`.
- *
- * @return string 10-space indented help to use the command.
- */
- abstract public function getCommandHelp();
/* -( Conduit )------------------------------------------------------------ */
@@ -610,169 +585,6 @@
return $workflow;
}
- final public function getArgument($key, $default = null) {
- return idx($this->arguments, $key, $default);
- }
-
- final public function getPassedArguments() {
- return $this->passedArguments;
- }
-
- final public function getCompleteArgumentSpecification() {
- $spec = $this->getArguments();
- $arc_config = $this->getArcanistConfiguration();
- $command = $this->getCommand();
- $spec += $arc_config->getCustomArgumentsForCommand($command);
-
- return $spec;
- }
-
- final public function parseArguments(array $args) {
- $this->passedArguments = $args;
-
- $spec = $this->getCompleteArgumentSpecification();
-
- $dict = array();
-
- $more_key = null;
- if (!empty($spec['*'])) {
- $more_key = $spec['*'];
- unset($spec['*']);
- $dict[$more_key] = array();
- }
-
- $short_to_long_map = array();
- foreach ($spec as $long => $options) {
- if (!empty($options['short'])) {
- $short_to_long_map[$options['short']] = $long;
- }
- }
-
- foreach ($spec as $long => $options) {
- if (!empty($options['repeat'])) {
- $dict[$long] = array();
- }
- }
-
- $more = array();
- $size = count($args);
- for ($ii = 0; $ii < $size; $ii++) {
- $arg = $args[$ii];
- $arg_name = null;
- $arg_key = null;
- if ($arg == '--') {
- $more = array_merge(
- $more,
- array_slice($args, $ii + 1));
- break;
- } else if (!strncmp($arg, '--', 2)) {
- $arg_key = substr($arg, 2);
- $parts = explode('=', $arg_key, 2);
- if (count($parts) == 2) {
- list($arg_key, $val) = $parts;
-
- array_splice($args, $ii, 1, array('--'.$arg_key, $val));
- $size++;
- }
-
- if (!array_key_exists($arg_key, $spec)) {
- $corrected = PhutilArgumentSpellingCorrector::newFlagCorrector()
- ->correctSpelling($arg_key, array_keys($spec));
- if (count($corrected) == 1) {
- PhutilConsole::getConsole()->writeErr(
- pht(
- "(Assuming '%s' is the British spelling of '%s'.)",
- '--'.$arg_key,
- '--'.head($corrected))."\n");
- $arg_key = head($corrected);
- } else {
- throw new ArcanistUsageException(
- pht(
- "Unknown argument '%s'. Try '%s'.",
- $arg_key,
- 'arc help'));
- }
- }
- } else if (!strncmp($arg, '-', 1)) {
- $arg_key = substr($arg, 1);
- if (empty($short_to_long_map[$arg_key])) {
- throw new ArcanistUsageException(
- pht(
- "Unknown argument '%s'. Try '%s'.",
- $arg_key,
- 'arc help'));
- }
- $arg_key = $short_to_long_map[$arg_key];
- } else {
- $more[] = $arg;
- continue;
- }
-
- $options = $spec[$arg_key];
- if (empty($options['param'])) {
- $dict[$arg_key] = true;
- } else {
- if ($ii == $size - 1) {
- throw new ArcanistUsageException(
- pht(
- "Option '%s' requires a parameter.",
- $arg));
- }
- if (!empty($options['repeat'])) {
- $dict[$arg_key][] = $args[$ii + 1];
- } else {
- $dict[$arg_key] = $args[$ii + 1];
- }
- $ii++;
- }
- }
-
- if ($more) {
- if ($more_key) {
- $dict[$more_key] = $more;
- } else {
- $example = reset($more);
- throw new ArcanistUsageException(
- pht(
- "Unrecognized argument '%s'. Try '%s'.",
- $example,
- 'arc help'));
- }
- }
-
- foreach ($dict as $key => $value) {
- if (empty($spec[$key]['conflicts'])) {
- continue;
- }
- foreach ($spec[$key]['conflicts'] as $conflict => $more) {
- if (isset($dict[$conflict])) {
- if ($more) {
- $more = ': '.$more;
- } else {
- $more = '.';
- }
- // TODO: We'll always display these as long-form, when the user might
- // have typed them as short form.
- throw new ArcanistUsageException(
- pht(
- "Arguments '%s' and '%s' are mutually exclusive",
- "--{$key}",
- "--{$conflict}").$more);
- }
- }
- }
-
- $this->arguments = $dict;
-
- $this->didParseArguments();
-
- return $this;
- }
-
- protected function didParseArguments() {
- // Override this to customize workflow argument behavior.
- }
-
final public function getWorkingCopy() {
$working_copy = $this->getConfigurationManager()->getWorkingCopyIdentity();
if (!$working_copy) {
@@ -1301,31 +1113,6 @@
return $this->changeCache[$path];
}
- final public function willRunWorkflow() {
- $spec = $this->getCompleteArgumentSpecification();
- foreach ($this->arguments as $arg => $value) {
- if (empty($spec[$arg])) {
- continue;
- }
- $options = $spec[$arg];
- if (!empty($options['supports'])) {
- $system_name = $this->getRepositoryAPI()->getSourceControlSystemName();
- if (!in_array($system_name, $options['supports'])) {
- $extended_info = null;
- if (!empty($options['nosupport'][$system_name])) {
- $extended_info = ' '.$options['nosupport'][$system_name];
- }
- throw new ArcanistUsageException(
- pht(
- "Option '%s' is not supported under %s.",
- "--{$arg}",
- $system_name).
- $extended_info);
- }
- }
- }
- }
-
final protected function normalizeRevisionID($revision_id) {
return preg_replace('/^D/i', '', $revision_id);
}
Index: src/workflow/ArcanistHelpWorkflow.php
===================================================================
--- src/workflow/ArcanistHelpWorkflow.php
+++ /dev/null
@@ -1,221 +0,0 @@
-<?php
-
-/**
- * Seduces the reader with majestic prose.
- */
-final class ArcanistHelpWorkflow extends ArcanistWorkflow {
-
- public function getWorkflowName() {
- return 'help';
- }
-
- public function getCommandSynopses() {
- return phutil_console_format(<<<EOTEXT
- **help** [__command__]
- **help** --full
-EOTEXT
- );
- }
-
- public function getCommandHelp() {
- return phutil_console_format(<<<EOTEXT
- Supports: english
- Shows this help. With __command__, shows help about a specific
- command.
-EOTEXT
- );
- }
-
- public function getArguments() {
- return array(
- 'full' => array(
- 'help' => pht('Print detailed information about each command.'),
- ),
- '*' => 'command',
- );
- }
-
- public function run() {
-
- $arc_config = $this->getArcanistConfiguration();
- $workflows = $arc_config->buildAllWorkflows();
- ksort($workflows);
-
- $target = null;
- if ($this->getArgument('command')) {
- $target = head($this->getArgument('command'));
- if (empty($workflows[$target])) {
- throw new ArcanistUsageException(
- pht(
- "Unrecognized command '%s'. Try '%s'.",
- $target,
- 'arc help'));
- }
- }
-
- $cmdref = array();
- foreach ($workflows as $command => $workflow) {
- if ($target && $target != $command) {
- continue;
- }
- if (!$target && !$this->getArgument('full')) {
- $cmdref[] = $workflow->getCommandSynopses();
- continue;
- }
- $optref = array();
- $arguments = $workflow->getArguments();
-
- $config_arguments = $arc_config->getCustomArgumentsForCommand($command);
-
- // This juggling is to put the extension arguments after the normal
- // arguments, and make sure the normal arguments aren't overwritten.
- ksort($arguments);
- ksort($config_arguments);
- foreach ($config_arguments as $argument => $spec) {
- if (empty($arguments[$argument])) {
- $arguments[$argument] = $spec;
- }
- }
-
- foreach ($arguments as $argument => $spec) {
- if ($argument == '*') {
- continue;
- }
- if (!empty($spec['hide'])) {
- continue;
- }
- if (isset($spec['param'])) {
- if (isset($spec['short'])) {
- $optref[] = phutil_console_format(
- ' __--%s__ __%s__, __-%s__ __%s__',
- $argument,
- $spec['param'],
- $spec['short'],
- $spec['param']);
- } else {
- $optref[] = phutil_console_format(
- ' __--%s__ __%s__',
- $argument,
- $spec['param']);
- }
- } else {
- if (isset($spec['short'])) {
- $optref[] = phutil_console_format(
- ' __--%s__, __-%s__',
- $argument,
- $spec['short']);
- } else {
- $optref[] = phutil_console_format(
- ' __--%s__',
- $argument);
- }
- }
-
- if (isset($config_arguments[$argument])) {
- $optref[] = ' '.
- pht('(This is a custom option for this project.)');
- }
-
- if (isset($spec['supports'])) {
- $optref[] = ' '.
- pht('Supports: %s', implode(', ', $spec['supports']));
- }
-
- if (isset($spec['help'])) {
- $docs = $spec['help'];
- } else {
- $docs = pht('This option is not documented.');
- }
- $docs = phutil_console_wrap($docs, 14);
- $optref[] = "{$docs}\n";
- }
- if ($optref) {
- $optref = implode("\n", $optref);
- $optref = "\n\n".$optref;
- } else {
- $optref = "\n";
- }
-
- $cmdref[] =
- $workflow->getCommandSynopses()."\n".
- $workflow->getCommandHelp().
- $optref;
- }
- $cmdref = implode("\n\n", $cmdref);
-
- if ($target) {
- echo "\n".$cmdref."\n";
- return;
- }
-
- $self = 'arc';
- echo phutil_console_format(<<<EOTEXT
-**NAME**
- **{$self}** - arcanist, a code review and revision management utility
-
-**SYNOPSIS**
- **{$self}** __command__ [__options__] [__args__]
- This help file provides a detailed command reference.
-
-**COMMAND REFERENCE**
-
-{$cmdref}
-
-
-EOTEXT
- );
-
- if (!$this->getArgument('full')) {
- echo pht(
- "Run '%s' to get commands and options descriptions.\n",
- 'arc help --full');
- return;
- }
-
- echo phutil_console_format(<<<EOTEXT
-**OPTION REFERENCE**
-
- __--trace__
- Debugging command. Shows underlying commands as they are executed,
- and full stack traces when exceptions are thrown.
-
- __--no-ansi__
- Output in plain ASCII text only, without color or style.
-
- __--ansi__
- Use formatting even in environments which probably don't support it.
- Example: arc --ansi unit | less -r
-
- __--load-phutil-library=/path/to/library__
- Ignore libraries listed in .arcconfig and explicitly load specified
- libraries instead. Mostly useful for Arcanist development.
-
- __--conduit-uri__ __uri__
- Ignore configured Conduit URI and use an explicit one instead. Mostly
- useful for Arcanist development.
-
- __--conduit-token__ __token__
- Ignore configured credentials and use an explicit API token instead.
-
- __--conduit-version__ __version__
- Ignore software version and claim to be running some other version
- instead. Mostly useful for Arcanist development. May cause bad things
- to happen.
-
- __--conduit-timeout__ __timeout__
- Override the default Conduit timeout. Specified in seconds.
-
- __--config__ __key=value__
- Specify a runtime configuration value. This will take precedence
- over static values, and only affect the current arcanist invocation.
-
- __--skip-arcconfig__
- Skip the working copy configuration file
-
- __--arcrc-file__ __filename__
- Use provided file instead of ~/.arcrc.
-
-EOTEXT
- );
- }
-}
Index: src/workflow/ArcanistLiberateWorkflow.php
===================================================================
--- src/workflow/ArcanistLiberateWorkflow.php
+++ src/workflow/ArcanistLiberateWorkflow.php
@@ -68,7 +68,7 @@
);
}
- public function run() {
+ public function runWorkflow() {
$argv = $this->getArgument('argv');
if (count($argv) > 1) {
throw new ArcanistUsageException(

File Metadata

Mime Type
text/plain
Expires
Sun, May 12, 4:15 AM (2 w, 6 d ago)
Storage Engine
amazon-s3
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
phabricator/secure/ik/aq/v4qre4kudgqpr24o
Default Alt Text
D19678.id47021.diff (40 KB)

Event Timeline