[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/scripts/repository/ -> reparse.php (source)

   1  #!/usr/bin/env php
   2  <?php
   3  
   4  $root = dirname(dirname(dirname(__FILE__)));
   5  require_once $root.'/scripts/__init_script__.php';
   6  
   7  $args = new PhutilArgumentParser($argv);
   8  $args->setSynopsis(<<<EOHELP
   9  **reparse.php** __what__ __which_parts__ [--trace] [--force]
  10  
  11  Rerun the Diffusion parser on specific commits and repositories. Mostly
  12  useful for debugging changes to Diffusion.
  13  
  14  e.g. enqueue reparse owners in the TEST repo for all commits:
  15  ./reparse.php --all TEST --owners
  16  
  17  e.g. do same but exclude before yesterday (local time):
  18  ./reparse.php --all TEST --owners --min-date yesterday
  19  ./reparse.php --all TEST --owners --min-date "today -1 day"
  20  
  21  e.g. do same but exclude before 03/31/2013 (local time):
  22  ./reparse.php --all TEST --owners --min-date "03/31/2013"
  23  EOHELP
  24  );
  25  
  26  $min_date_usage_examples =
  27    "Valid examples:\n".
  28    "  'today', 'today 2pm', '-1 hour', '-2 hours', '-24 hours',\n".
  29    "  'yesterday', 'today -1 day', 'yesterday 2pm', '2pm -1 day',\n".
  30    "  'last Monday', 'last Monday 14:00', 'last Monday 2pm',\n".
  31    "  '31 March 2013', '31 Mar', '03/31', '03/31/2013',\n".
  32    "See __http://www.php.net/manual/en/datetime.formats.php__ for more.\n";
  33  
  34  $args->parseStandardArguments();
  35  $args->parse(
  36    array(
  37      // what
  38      array(
  39        'name'     => 'revision',
  40        'wildcard' => true,
  41      ),
  42      array(
  43        'name'     => 'all',
  44        'param'    => 'callsign or phid',
  45        'help'     => 'Reparse all commits in the specified repository. This '.
  46                      'mode queues parsers into the task queue; you must run '.
  47                      'taskmasters to actually do the parses. Use with '.
  48                      '__--force-local__ to run the tasks locally instead of '.
  49                      'with taskmasters.',
  50      ),
  51      array(
  52        'name'     => 'min-date',
  53        'param'    => 'date',
  54        'help'     => 'Must be used with __--all__, this will exclude commits '.
  55                      'which are earlier than __date__.'.
  56                      "\n".$min_date_usage_examples,
  57      ),
  58      // which parts
  59      array(
  60        'name'     => 'message',
  61        'help'     => 'Reparse commit messages.',
  62      ),
  63      array(
  64        'name'     => 'change',
  65        'help'     => 'Reparse changes.',
  66      ),
  67      array(
  68        'name'     => 'herald',
  69        'help'     => 'Reevaluate Herald rules (may send huge amounts of email!)',
  70      ),
  71      array(
  72        'name'     => 'owners',
  73        'help'     => 'Reevaluate related commits for owners packages (may '.
  74                      'delete existing relationship entries between your '.
  75                      'package and some old commits!)',
  76      ),
  77      array(
  78        'name'     => 'harbormaster',
  79        'help'     => 'EXPERIMENTAL. Execute Harbormaster.',
  80      ),
  81      // misc options
  82      array(
  83        'name'     => 'force',
  84        'short'    => 'f',
  85        'help'     => 'Act noninteractively, without prompting.',
  86      ),
  87      array(
  88        'name'     => 'force-local',
  89        'help'     => 'Only used with __--all__, use this to run the tasks '.
  90                      'locally instead of deferring them to taskmaster daemons.',
  91      ),
  92    ));
  93  
  94  $all_from_repo = $args->getArg('all');
  95  $reparse_message = $args->getArg('message');
  96  $reparse_change = $args->getArg('change');
  97  $reparse_herald = $args->getArg('herald');
  98  $reparse_owners = $args->getArg('owners');
  99  $reparse_harbormaster = $args->getArg('harbormaster');
 100  $reparse_what = $args->getArg('revision');
 101  $force = $args->getArg('force');
 102  $force_local = $args->getArg('force-local');
 103  $min_date = $args->getArg('min-date');
 104  
 105  if (!$all_from_repo && !$reparse_what) {
 106    usage('Specify a commit or repository to reparse.');
 107  }
 108  
 109  if ($all_from_repo && $reparse_what) {
 110    $commits = implode(', ', $reparse_what);
 111    usage(
 112      "Specify a commit or repository to reparse, not both:\n".
 113      "All from repo: ".$all_from_repo."\n".
 114      "Commit(s) to reparse: ".$commits);
 115  }
 116  
 117  if (!$reparse_message && !$reparse_change && !$reparse_herald &&
 118      !$reparse_owners && !$reparse_harbormaster) {
 119    usage('Specify what information to reparse with --message, --change,  '.
 120          '--herald, --harbormaster, and/or --owners');
 121  }
 122  
 123  $min_timestamp = false;
 124  if ($min_date) {
 125    $min_timestamp = strtotime($min_date);
 126  
 127    if (!$all_from_repo) {
 128      usage(
 129        "You must use --all if you specify --min-date\n".
 130        "e.g.\n".
 131        "  ./reparse.php --all TEST --owners --min-date yesterday");
 132    }
 133  
 134    // previous to PHP 5.1.0 you would compare with -1, instead of false
 135    if (false === $min_timestamp) {
 136      usage(
 137        "Supplied --min-date is not valid\n".
 138        "Supplied value: '".$min_date."'\n".
 139        $min_date_usage_examples);
 140    }
 141  }
 142  
 143  if ($reparse_owners && !$force) {
 144    echo phutil_console_wrap(
 145      'You are about to recreate the relationship entries between the commits '.
 146      'and the packages they touch. This might delete some existing '.
 147      'relationship entries for some old commits.');
 148  
 149    if (!phutil_console_confirm('Are you ready to continue?')) {
 150      echo "Cancelled.\n";
 151      exit(1);
 152    }
 153  }
 154  
 155  $commits = array();
 156  if ($all_from_repo) {
 157    $repository = id(new PhabricatorRepository())->loadOneWhere(
 158      'callsign = %s OR phid = %s',
 159      $all_from_repo,
 160      $all_from_repo);
 161    if (!$repository) {
 162      throw new Exception("Unknown repository {$all_from_repo}!");
 163    }
 164    $constraint = '';
 165    if ($min_timestamp) {
 166      echo "Excluding entries before UNIX timestamp: ".$min_timestamp."\n";
 167      $table = new PhabricatorRepositoryCommit();
 168      $conn_r = $table->establishConnection('r');
 169      $constraint = qsprintf(
 170        $conn_r,
 171        'AND epoch >= %d',
 172        $min_timestamp);
 173    }
 174    $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
 175      'repositoryID = %d %Q',
 176      $repository->getID(),
 177      $constraint);
 178    $callsign = $repository->getCallsign();
 179    if (!$commits) {
 180      echo "No commits have been discovered in {$callsign} repository!\n";
 181      exit;
 182    }
 183  } else {
 184    $commits = array();
 185    foreach ($reparse_what as $identifier) {
 186      $matches = null;
 187      if (!preg_match('/r([A-Z]+)([a-z0-9]+)/', $identifier, $matches)) {
 188        throw new Exception("Can't parse commit identifier!");
 189      }
 190      $callsign = $matches[1];
 191      $commit_identifier = $matches[2];
 192      $repository = id(new PhabricatorRepository())->loadOneWhere(
 193        'callsign = %s',
 194        $callsign);
 195      if (!$repository) {
 196        throw new Exception("No repository with callsign '{$callsign}'!");
 197      }
 198      $commit = id(new PhabricatorRepositoryCommit())->loadOneWhere(
 199        'repositoryID = %d AND commitIdentifier = %s',
 200        $repository->getID(),
 201        $commit_identifier);
 202      if (!$commit) {
 203        throw new Exception(
 204          "No matching commit '{$commit_identifier}' in repository ".
 205          "'{$callsign}'. (For git and mercurial repositories, you must specify ".
 206          "the entire commit hash.)");
 207      }
 208      $commits[] = $commit;
 209    }
 210  }
 211  
 212  if ($all_from_repo && !$force_local) {
 213    echo phutil_console_format(
 214      '**NOTE**: This script will queue tasks to reparse the data. Once the '.
 215      'tasks have been queued, you need to run Taskmaster daemons to execute '.
 216      'them.');
 217    echo "\n\n";
 218    echo "QUEUEING TASKS (".number_format(count($commits))." Commits):\n";
 219  }
 220  
 221  $progress = new PhutilConsoleProgressBar();
 222  $progress->setTotal(count($commits));
 223  
 224  $tasks = array();
 225  foreach ($commits as $commit) {
 226    $classes = array();
 227    switch ($repository->getVersionControlSystem()) {
 228      case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
 229        if ($reparse_message) {
 230          $classes[] = 'PhabricatorRepositoryGitCommitMessageParserWorker';
 231        }
 232        if ($reparse_change) {
 233          $classes[] = 'PhabricatorRepositoryGitCommitChangeParserWorker';
 234        }
 235        break;
 236      case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
 237        if ($reparse_message) {
 238          $classes[] = 'PhabricatorRepositoryMercurialCommitMessageParserWorker';
 239        }
 240        if ($reparse_change) {
 241          $classes[] = 'PhabricatorRepositoryMercurialCommitChangeParserWorker';
 242        }
 243        break;
 244      case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
 245        if ($reparse_message) {
 246          $classes[] = 'PhabricatorRepositorySvnCommitMessageParserWorker';
 247        }
 248        if ($reparse_change) {
 249          $classes[] = 'PhabricatorRepositorySvnCommitChangeParserWorker';
 250        }
 251        break;
 252    }
 253  
 254    if ($reparse_herald) {
 255      $classes[] = 'PhabricatorRepositoryCommitHeraldWorker';
 256    }
 257  
 258    if ($reparse_owners) {
 259      $classes[] = 'PhabricatorRepositoryCommitOwnersWorker';
 260    }
 261  
 262    if ($reparse_harbormaster) {
 263      $classes[] = 'HarbormasterRunnerWorker';
 264    }
 265  
 266    $spec = array(
 267      'commitID'  => $commit->getID(),
 268      'only'      => true,
 269    );
 270  
 271    if ($all_from_repo && !$force_local) {
 272      foreach ($classes as $class) {
 273        PhabricatorWorker::scheduleTask(
 274          $class,
 275          $spec,
 276          PhabricatorWorker::PRIORITY_IMPORT);
 277      }
 278    } else {
 279      foreach ($classes as $class) {
 280        $worker = newv($class, array($spec));
 281        $worker->executeTask();
 282      }
 283    }
 284  
 285    $progress->update(1);
 286  }
 287  
 288  $progress->done();
 289  
 290  function usage($message) {
 291    echo phutil_console_format(
 292      '**Usage Exception:** '.$message."\n".
 293      "Use __--help__ to display full help\n");
 294    exit(1);
 295  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1