in src/parser/argument/PhutilArgumentParser.php [372:462]
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;
}
}