public function parseWorkflowsFull()

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;
    }
  }