Correct Aphlict websocket URI construction after PHP8 compatibility changes
[phabricator.git] / src / applications / repository / management / PhabricatorRepositoryManagementReparseWorkflow.php
blobfe83d271abcbdc984ca7aaaf130c1e3ac7a7a7cf
1 <?php
3 final class PhabricatorRepositoryManagementReparseWorkflow
4 extends PhabricatorRepositoryManagementWorkflow {
6 protected function didConstruct() {
7 $this
8 ->setName('reparse')
9 ->setExamples('**reparse** [options] __commit__')
10 ->setSynopsis(
11 pht(
12 '**reparse** __what__ __which_parts__ [--trace] [--force]'."\n\n".
13 'Rerun the Diffusion parser on specific commits and repositories. '.
14 'Mostly useful for debugging changes to Diffusion.'."\n\n".
15 'e.g. do same but exclude before yesterday (local time):'."\n".
16 'repository reparse --all TEST --change --min-date yesterday'."\n".
17 'repository reparse --all TEST --change --min-date "today -1 day".'.
18 "\n\n".
19 'e.g. do same but exclude before 03/31/2013 (local time):'."\n".
20 'repository reparse --all TEST --change --min-date "03/31/2013"'))
21 ->setArguments(
22 array(
23 array(
24 'name' => 'revision',
25 'wildcard' => true,
27 array(
28 'name' => 'all',
29 'param' => 'repository',
30 'help' => pht(
31 'Reparse all commits in the specified repository.'),
33 array(
34 'name' => 'min-date',
35 'param' => 'date',
36 'help' => pht(
37 "Must be used with __%s__, this will exclude commits which ".
38 "are earlier than __date__.\n".
39 "Valid examples:\n".
40 " 'today', 'today 2pm', '-1 hour', '-2 hours', '-24 hours',\n".
41 " 'yesterday', 'today -1 day', 'yesterday 2pm', '2pm -1 day',\n".
42 " 'last Monday', 'last Monday 14:00', 'last Monday 2pm',\n".
43 " '31 March 2013', '31 Mar', '03/31', '03/31/2013',\n".
44 "See __%s__ for more.",
45 '--all',
46 'http://www.php.net/manual/en/datetime.formats.php'),
48 array(
49 'name' => 'message',
50 'help' => pht('Reparse commit messages.'),
52 array(
53 'name' => 'change',
54 'help' => pht('Reparse source changes.'),
56 array(
57 'name' => 'publish',
58 'help' => pht(
59 'Publish changes: send email, publish Feed stories, run '.
60 'Herald rules, etc.'),
62 array(
63 'name' => 'force',
64 'short' => 'f',
65 'help' => pht('Act noninteractively, without prompting.'),
67 array(
68 'name' => 'background',
69 'help' => pht(
70 'Queue tasks for the daemons instead of running them in the '.
71 'foreground.'),
73 array(
74 'name' => 'importing',
75 'help' => pht('Reparse all steps which have not yet completed.'),
77 ));
81 public function execute(PhutilArgumentParser $args) {
82 $console = PhutilConsole::getConsole();
84 $all_from_repo = $args->getArg('all');
85 $reparse_message = $args->getArg('message');
86 $reparse_change = $args->getArg('change');
87 $reparse_publish = $args->getArg('publish');
88 $reparse_what = $args->getArg('revision');
89 $force = $args->getArg('force');
90 $background = $args->getArg('background');
91 $min_date = $args->getArg('min-date');
92 $importing = $args->getArg('importing');
94 if (!$all_from_repo && !$reparse_what) {
95 throw new PhutilArgumentUsageException(
96 pht('Specify a commit or repository to reparse.'));
99 if ($all_from_repo && $reparse_what) {
100 $commits = implode(', ', $reparse_what);
101 throw new PhutilArgumentUsageException(
102 pht(
103 "Specify a commit or repository to reparse, not both:\n".
104 "All from repo: %s\n".
105 "Commit(s) to reparse: %s",
106 $all_from_repo,
107 $commits));
110 $any_step = ($reparse_message || $reparse_change || $reparse_publish);
112 if ($any_step && $importing) {
113 throw new PhutilArgumentUsageException(
114 pht(
115 'Choosing steps with "--importing" conflicts with flags which '.
116 'select specific steps.'));
117 } else if ($any_step) {
118 // OK.
119 } else if ($importing) {
120 // OK.
121 } else if (!$any_step && !$importing) {
122 throw new PhutilArgumentUsageException(
123 pht(
124 'Specify which steps to reparse with "--message", "--change", '.
125 'and/or "--publish"; or "--importing" to run all missing steps.'));
128 $min_timestamp = false;
129 if ($min_date) {
130 $min_timestamp = strtotime($min_date);
132 if (!$all_from_repo) {
133 throw new PhutilArgumentUsageException(
134 pht(
135 'You must use "--all" if you specify "--min-date".'));
138 // previous to PHP 5.1.0 you would compare with -1, instead of false
139 if (false === $min_timestamp) {
140 throw new PhutilArgumentUsageException(
141 pht(
142 "Supplied --min-date is not valid. See help for valid examples.\n".
143 "Supplied value: '%s'\n",
144 $min_date));
148 $commits = array();
149 if ($all_from_repo) {
150 $repository = id(new PhabricatorRepositoryQuery())
151 ->setViewer(PhabricatorUser::getOmnipotentUser())
152 ->withIdentifiers(array($all_from_repo))
153 ->executeOne();
155 if (!$repository) {
156 throw new PhutilArgumentUsageException(
157 pht('Unknown repository "%s"!', $all_from_repo));
160 $query = id(new DiffusionCommitQuery())
161 ->setViewer(PhabricatorUser::getOmnipotentUser())
162 ->withRepository($repository);
164 if ($min_timestamp) {
165 $query->withEpochRange($min_timestamp, null);
168 if ($importing) {
169 $query->withImporting(true);
172 $commits = $query->execute();
174 if (!$commits) {
175 throw new PhutilArgumentUsageException(
176 pht(
177 'No commits have been discovered in the "%s" repository!',
178 $repository->getDisplayName()));
180 } else {
181 $commits = $this->loadNamedCommits($reparse_what);
184 if (!$background) {
185 PhabricatorWorker::setRunAllTasksInProcess(true);
188 $progress = new PhutilConsoleProgressBar();
189 $progress->setTotal(count($commits));
191 $tasks = array();
192 foreach ($commits as $commit) {
193 $repository = $commit->getRepository();
195 if ($importing) {
196 $status = $commit->getImportStatus();
197 // Find the first missing import step and queue that up.
198 $reparse_message = false;
199 $reparse_change = false;
200 $reparse_publish = false;
201 if (!($status & PhabricatorRepositoryCommit::IMPORTED_MESSAGE)) {
202 $reparse_message = true;
203 } else if (!($status & PhabricatorRepositoryCommit::IMPORTED_CHANGE)) {
204 $reparse_change = true;
205 } else if (!($status & PhabricatorRepositoryCommit::IMPORTED_PUBLISH)) {
206 $reparse_publish = true;
207 } else {
208 continue;
212 $classes = array();
213 switch ($repository->getVersionControlSystem()) {
214 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
215 if ($reparse_message) {
216 $classes[] = 'PhabricatorRepositoryGitCommitMessageParserWorker';
218 if ($reparse_change) {
219 $classes[] = 'PhabricatorRepositoryGitCommitChangeParserWorker';
221 break;
222 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
223 if ($reparse_message) {
224 $classes[] =
225 'PhabricatorRepositoryMercurialCommitMessageParserWorker';
227 if ($reparse_change) {
228 $classes[] = 'PhabricatorRepositoryMercurialCommitChangeParserWorker';
230 break;
231 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
232 if ($reparse_message) {
233 $classes[] = 'PhabricatorRepositorySvnCommitMessageParserWorker';
235 if ($reparse_change) {
236 $classes[] = 'PhabricatorRepositorySvnCommitChangeParserWorker';
238 break;
241 if ($reparse_publish) {
242 $classes[] = 'PhabricatorRepositoryCommitPublishWorker';
245 // NOTE: With "--importing", we queue the first unparsed step and let
246 // it queue the other ones normally. Without "--importing", we queue
247 // all the requested steps explicitly.
249 $spec = array(
250 'commitPHID' => $commit->getPHID(),
251 'only' => !$importing,
252 'via' => 'reparse',
255 foreach ($classes as $class) {
256 try {
257 PhabricatorWorker::scheduleTask(
258 $class,
259 $spec,
260 array(
261 'priority' => PhabricatorWorker::PRIORITY_IMPORT,
262 'objectPHID' => $commit->getPHID(),
263 'containerPHID' => $repository->getPHID(),
265 } catch (PhabricatorWorkerPermanentFailureException $ex) {
266 // See T13315. We expect some reparse steps to occasionally raise
267 // permanent failures: for example, because they are no longer
268 // reachable. This is a routine condition, not a catastrophic
269 // failure, so let the user know something happened but continue
270 // reparsing any remaining commits.
271 echo tsprintf(
272 "<bg:yellow>** %s **</bg> %s\n",
273 pht('WARN'),
274 $ex->getMessage());
278 $progress->update(1);
281 $progress->done();
283 return 0;