<?php

final class PhabricatorConfigManagementDoneWorkflow
  extends PhabricatorConfigManagementWorkflow {

  protected function didConstruct() {
    $this
      ->setName('done')
      ->setExamples('**done** __activity__')
      ->setSynopsis(pht('Mark a manual upgrade activity as complete.'))
      ->setArguments(
        array(
          array(
            'name' => 'activities',
            'wildcard' => true,
          ),
        ));
  }

  public function execute(PhutilArgumentParser $args) {
    $activities = $args->getArg('activities');
    if (!$activities) {
      throw new PhutilArgumentUsageException(
        pht('Specify an activity to mark as completed.'));
    }

    foreach ($activities as $type) {
      $activity = id(new PhabricatorConfigManualActivity())->loadOneWhere(
        'activityType = %s',
        $type);
      if (!$activity) {
        throw new PhutilArgumentUsageException(
          pht(
            'Activity "%s" is not currently marked as required, so there '.
            'is no need to complete it.',
            $type));
      } else {
        $activity->delete();
        echo tsprintf(
          "%s\n",
          pht(
            'Marked activity "%s" as completed.',
            $type));
      }
    }

    echo tsprintf(
      "%s\n",
      pht('Done.'));

    return 0;
  }

}

<?php

final class PhabricatorConfigManagementDoneWorkflow
  extends PhabricatorConfigManagementWorkflow {

  protected function didConstruct() {
    $this
      ->setName('done')
      ->setExamples('**done** __activity__')
      ->setSynopsis(pht('Mark a manual upgrade activity as complete.'))
      ->setArguments(
        array(
          array(
            'name' => 'force',
            'short' => 'f',
            'help' => pht(
              'Mark activities complete even if there is no outstanding '.
              'need to complete them.'),
          ),
          array(
            'name' => 'activities',
            'wildcard' => true,
          ),
        ));
  }

  public function execute(PhutilArgumentParser $args) {
    $is_force = $args->getArg('force');

    $activities = $args->getArg('activities');
    if (!$activities) {
      throw new PhutilArgumentUsageException(
        pht('Specify an activity to mark as completed.'));
    }

    foreach ($activities as $type) {
      $activity = id(new PhabricatorConfigManualActivity())->loadOneWhere(
        'activityType = %s',
        $type);
      if (!$activity) {
        if ($is_force) {
          echo tsprintf(
            "%s\n",
            pht(
              'Activity "%s" did not need to be marked as complete.',
              $type));
        } else {
          throw new PhutilArgumentUsageException(
            pht(
              'Activity "%s" is not currently marked as required, so there '.
              'is no need to complete it.',
              $type));
        }
      } else {
        $activity->delete();
        echo tsprintf(
          "%s\n",
          pht(
            'Marked activity "%s" as completed.',
            $type));
      }
    }

    echo tsprintf(
      "%s\n",
      pht('Done.'));

    return 0;
  }

}

Add a "--force" argument to "bin/config done"
Add a "--force" argument to "bin/config done"

Summary:
Ref T11922. When we deploy on Saturday I need to rebuild all the cluster indexes, but some instances won't have anything indexed so they won't actually trigger the activity.

Add a `--force` flag that just clears an activity even if the activity is not required.

Test Plan: Ran `bin/config done reindex --force` several times.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T11922

Differential Revision: https://secure.phabricator.com/D16970
