[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |