public function run()

in src/workflow/ArcanistCloseRevisionWorkflow.php [64:189]


  public function run() {
    $is_finalize = $this->getArgument('finalize');

    $conduit = $this->getConduit();

    $revision_list = $this->getArgument('revision', array());
    if (!$revision_list) {
      throw new ArcanistUsageException(
        pht(
          '%s requires a revision number.',
          'close-revision'));
    }
    if (count($revision_list) != 1) {
      throw new ArcanistUsageException(
        pht(
          '%s requires exactly one revision.',
          'close-revision'));
    }
    $revision_id = reset($revision_list);
    $revision_id = $this->normalizeRevisionID($revision_id);

    $revisions = $conduit->callMethodSynchronous(
      'differential.query',
      array(
        'ids' => array($revision_id),
      ));
    $revision = head($revisions);

    $object_name = "D{$revision_id}";

    if (!$revision && !$is_finalize) {
      throw new ArcanistUsageException(
        pht(
          'Revision %s does not exist.',
          $object_name));
    }

    $status_accepted = ArcanistDifferentialRevisionStatus::ACCEPTED;
    $status_closed   = ArcanistDifferentialRevisionStatus::CLOSED;

    if (!$is_finalize && $revision['status'] != $status_accepted) {
      throw new ArcanistUsageException(
        pht(
          "Revision %s can not be closed. You can only close ".
          "revisions which have been 'accepted'.",
          $object_name));
    }

    if ($revision) {
      $revision_display = sprintf(
        '%s %s',
        $object_name,
        $revision['title']);

      if (!$is_finalize && $revision['authorPHID'] != $this->getUserPHID()) {
        $prompt = pht(
          'You are not the author of revision "%s", '.
          'are you sure you want to close it?',
          $object_name);
        if (!phutil_console_confirm($prompt)) {
          throw new ArcanistUserAbortException();
        }
      }

      $actually_close = true;
      if ($is_finalize) {
        if ($this->getRepositoryPHID()) {
          $actually_close = false;
        } else if ($revision['status'] != $status_accepted) {
          // See T13458. The server doesn't permit a transition to "Closed"
          // over the API if the revision is not "Accepted". If we won't be
          // able to close the revision, skip the attempt and print a
          // message.

          $this->writeWarn(
            pht('OPEN REVISION'),
            pht(
              'Revision "%s" is not in state "Accepted", so it will '.
              'be left open.',
              $object_name));

          $actually_close = false;
        }
      }

      if ($actually_close) {
        $this->writeInfo(
          pht('CLOSE'),
          pht(
            'Closing revision "%s"...',
            $revision_display));

        $conduit->callMethodSynchronous(
          'differential.close',
          array(
            'revisionID' => $revision_id,
          ));

        $this->writeOkay(
          pht('CLOSE'),
          pht(
            'Done, closed revision.'));
      }
    }

    $status = $revision['status'];
    if ($status == $status_accepted || $status == $status_closed) {
      // If this has already been attached to commits, don't show the
      // "you can push this commit" message since we know it's been pushed
      // already.
      $is_finalized = empty($revision['commits']);
    } else {
      $is_finalized = false;
    }

    if (!$this->getArgument('quiet')) {
      if ($is_finalized) {
        $message = $this->getRepositoryAPI()->getFinalizedRevisionMessage();
        echo phutil_console_wrap($message)."\n";
      } else {
        echo pht('Done.')."\n";
      }
    }

    return 0;
  }