コード例 #1
0
 private function assertCommandCorrection($expect, $input, $commands)
 {
     $result = PhutilArgumentSpellingCorrector::newCommandCorrector()->correctSpelling($input, $commands);
     sort($result);
     sort($expect);
     $commands = implode(', ', $commands);
     $this->assertEqual($expect, $result, pht('Correction of %s against: %s', $input, $commands));
 }
コード例 #2
0
 /**
  * Select a workflow. For commands that may operate in several modes, like
  * `arc`, the modes can be split into "workflows". Each workflow specifies
  * the arguments it accepts. This method takes a list of workflows, selects
  * the chosen workflow, parses its arguments, and either executes it (if it
  * is executable) or returns it for handling.
  *
  * See @{class:PhutilArgumentWorkflow} for details on using workflows.
  *
  * @param list List of @{class:PhutilArgumentWorkflow}s.
  * @return PhutilArgumentWorkflow|no  Returns the chosen workflow if it is
  *                                    not executable, or executes it and
  *                                    exits with a return code if it is.
  * @task parse
  */
 public function parseWorkflowsFull(array $workflows)
 {
     assert_instances_of($workflows, 'PhutilArgumentWorkflow');
     // Clear out existing workflows. We need to do this to permit the
     // construction of sub-workflows.
     $this->workflows = array();
     foreach ($workflows as $workflow) {
         $name = $workflow->getName();
         if ($name === null) {
             throw new PhutilArgumentSpecificationException(pht('Workflow has no name!'));
         }
         if (isset($this->workflows[$name])) {
             throw new PhutilArgumentSpecificationException(pht("Two workflows with name '%s!", $name));
         }
         $this->workflows[$name] = $workflow;
     }
     $argv = $this->argv;
     if (empty($argv)) {
         // TODO: this is kind of hacky / magical.
         if (isset($this->workflows['help'])) {
             $argv = array('help');
         } else {
             throw new PhutilArgumentUsageException(pht('No workflow selected.'));
         }
     }
     $flow = array_shift($argv);
     if (empty($this->workflows[$flow])) {
         $corrected = PhutilArgumentSpellingCorrector::newCommandCorrector()->correctSpelling($flow, array_keys($this->workflows));
         if (count($corrected) == 1) {
             $corrected = head($corrected);
             $this->logMessage(tsprintf("%s\n", pht('(Assuming "%s" is the British spelling of "%s".)', $flow, $corrected)));
             $flow = $corrected;
         } else {
             $this->raiseUnknownWorkflow($flow, $corrected);
         }
     }
     $workflow = $this->workflows[$flow];
     if ($this->showHelp) {
         // Make "cmd flow --help" behave like "cmd help flow", not "cmd help".
         $help_flow = idx($this->workflows, 'help');
         if ($help_flow) {
             if ($help_flow !== $workflow) {
                 $workflow = $help_flow;
                 $argv = array($flow);
                 // Prevent parse() from dumping us back out to standard help.
                 $this->showHelp = false;
             }
         } else {
             $this->printHelpAndExit();
         }
     }
     $this->argv = array_values($argv);
     if ($workflow->shouldParsePartial()) {
         $this->parsePartial($workflow->getArguments());
     } else {
         $this->parse($workflow->getArguments());
     }
     if ($workflow->isExecutable()) {
         $workflow->setArgv($this);
         $err = $workflow->execute($this);
         exit($err);
     } else {
         return $workflow;
     }
 }
コード例 #3
0
 public final 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);
 }