Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/phabricator
Path: blob/master/src/applications/diffusion/management/DiffusionRepositoryBasicsManagementPanel.php
13395 views
1
<?php
2
3
final class DiffusionRepositoryBasicsManagementPanel
4
extends DiffusionRepositoryManagementPanel {
5
6
const PANELKEY = 'basics';
7
8
public function getManagementPanelLabel() {
9
return pht('Basics');
10
}
11
12
public function getManagementPanelOrder() {
13
return 100;
14
}
15
16
public function getManagementPanelIcon() {
17
return 'fa-code';
18
}
19
20
protected function getEditEngineFieldKeys() {
21
return array(
22
'name',
23
'callsign',
24
'shortName',
25
'description',
26
'projectPHIDs',
27
);
28
}
29
30
public function buildManagementPanelCurtain() {
31
$repository = $this->getRepository();
32
$viewer = $this->getViewer();
33
34
$action_list = id(new PhabricatorActionListView())
35
->setViewer($viewer);
36
37
$can_edit = PhabricatorPolicyFilter::hasCapability(
38
$viewer,
39
$repository,
40
PhabricatorPolicyCapability::CAN_EDIT);
41
42
$edit_uri = $this->getEditPageURI();
43
$activate_uri = $repository->getPathURI('edit/activate/');
44
$delete_uri = $repository->getPathURI('edit/delete/');
45
$encoding_uri = $this->getEditPageURI('encoding');
46
$dangerous_uri = $repository->getPathURI('edit/dangerous/');
47
$enormous_uri = $repository->getPathURI('edit/enormous/');
48
$update_uri = $repository->getPathURI('edit/update/');
49
$publish_uri = $repository->getPathURI('edit/publish/');
50
51
if ($repository->isTracked()) {
52
$activate_icon = 'fa-ban';
53
$activate_label = pht('Deactivate Repository');
54
} else {
55
$activate_icon = 'fa-check';
56
$activate_label = pht('Activate Repository');
57
}
58
59
if (!$repository->isPublishingDisabled()) {
60
$publish_icon = 'fa-ban';
61
$publish_label = pht('Disable Publishing');
62
} else {
63
$publish_icon = 'fa-check';
64
$publish_label = pht('Enable Publishing');
65
}
66
67
$should_dangerous = $repository->shouldAllowDangerousChanges();
68
if ($should_dangerous) {
69
$dangerous_icon = 'fa-shield';
70
$dangerous_name = pht('Prevent Dangerous Changes');
71
$can_dangerous = $can_edit;
72
} else {
73
$dangerous_icon = 'fa-exclamation-triangle';
74
$dangerous_name = pht('Allow Dangerous Changes');
75
$can_dangerous = ($can_edit && $repository->canAllowDangerousChanges());
76
}
77
78
$should_enormous = $repository->shouldAllowEnormousChanges();
79
if ($should_enormous) {
80
$enormous_icon = 'fa-shield';
81
$enormous_name = pht('Prevent Enormous Changes');
82
$can_enormous = $can_edit;
83
} else {
84
$enormous_icon = 'fa-exclamation-triangle';
85
$enormous_name = pht('Allow Enormous Changes');
86
$can_enormous = ($can_edit && $repository->canAllowEnormousChanges());
87
}
88
89
$action_list->addAction(
90
id(new PhabricatorActionView())
91
->setName(pht('Edit Basic Information'))
92
->setHref($edit_uri)
93
->setIcon('fa-pencil')
94
->setDisabled(!$can_edit)
95
->setWorkflow(!$can_edit));
96
97
$action_list->addAction(
98
id(new PhabricatorActionView())
99
->setName(pht('Edit Text Encoding'))
100
->setIcon('fa-text-width')
101
->setHref($encoding_uri)
102
->setDisabled(!$can_edit)
103
->setWorkflow(!$can_edit));
104
105
$action_list->addAction(
106
id(new PhabricatorActionView())
107
->setName($dangerous_name)
108
->setHref($dangerous_uri)
109
->setIcon($dangerous_icon)
110
->setDisabled(!$can_dangerous)
111
->setWorkflow(true));
112
113
$action_list->addAction(
114
id(new PhabricatorActionView())
115
->setName($enormous_name)
116
->setHref($enormous_uri)
117
->setIcon($enormous_icon)
118
->setDisabled(!$can_enormous)
119
->setWorkflow(true));
120
121
$action_list->addAction(
122
id(new PhabricatorActionView())
123
->setType(PhabricatorActionView::TYPE_DIVIDER));
124
125
$action_list->addAction(
126
id(new PhabricatorActionView())
127
->setName($activate_label)
128
->setHref($activate_uri)
129
->setIcon($activate_icon)
130
->setDisabled(!$can_edit)
131
->setWorkflow(true));
132
133
$action_list->addAction(
134
id(new PhabricatorActionView())
135
->setName($publish_label)
136
->setHref($publish_uri)
137
->setIcon($publish_icon)
138
->setDisabled(!$can_edit)
139
->setWorkflow(true));
140
141
$action_list->addAction(
142
id(new PhabricatorActionView())
143
->setName(pht('Update Now'))
144
->setHref($update_uri)
145
->setIcon('fa-refresh')
146
->setWorkflow(true)
147
->setDisabled(!$can_edit));
148
149
$action_list->addAction(
150
id(new PhabricatorActionView())
151
->setType(PhabricatorActionView::TYPE_DIVIDER));
152
153
$action_list->addAction(
154
id(new PhabricatorActionView())
155
->setName(pht('Delete Repository'))
156
->setHref($delete_uri)
157
->setIcon('fa-times')
158
->setWorkflow(true));
159
160
return $this->newCurtainView()
161
->setActionList($action_list);
162
}
163
164
public function buildManagementPanelContent() {
165
$basics = $this->buildBasics();
166
$basics = $this->newBox(pht('Properties'), $basics);
167
168
$repository = $this->getRepository();
169
170
$state = $this->buildStateView($repository);
171
172
$is_new = $repository->isNewlyInitialized();
173
$info_view = null;
174
if ($is_new) {
175
$messages = array();
176
177
$messages[] = pht(
178
'This newly created repository is not active yet. Configure policies, '.
179
'options, and URIs. When ready, %s the repository.',
180
phutil_tag('strong', array(), pht('Activate')));
181
182
if ($repository->isHosted()) {
183
$messages[] = pht(
184
'If activated now, this repository will become a new hosted '.
185
'repository. To observe an existing repository instead, configure '.
186
'it in the %s panel.',
187
phutil_tag('strong', array(), pht('URIs')));
188
} else {
189
$messages[] = pht(
190
'If activated now, this repository will observe an existing remote '.
191
'repository and begin importing changes.');
192
}
193
194
$info_view = id(new PHUIInfoView())
195
->setSeverity(PHUIInfoView::SEVERITY_NOTICE)
196
->setErrors($messages);
197
}
198
199
$description = $this->buildDescription();
200
if ($description) {
201
$description = $this->newBox(pht('Description'), $description);
202
}
203
$status = $this->buildStatus();
204
205
return array($info_view, $state, $basics, $description, $status);
206
}
207
208
private function buildBasics() {
209
$repository = $this->getRepository();
210
$viewer = $this->getViewer();
211
212
$view = id(new PHUIPropertyListView())
213
->setViewer($viewer);
214
215
$name = $repository->getName();
216
$view->addProperty(pht('Name'), $name);
217
218
$type = PhabricatorRepositoryType::getNameForRepositoryType(
219
$repository->getVersionControlSystem());
220
$view->addProperty(pht('Type'), $type);
221
222
$callsign = $repository->getCallsign();
223
if (!strlen($callsign)) {
224
$callsign = phutil_tag('em', array(), pht('No Callsign'));
225
}
226
$view->addProperty(pht('Callsign'), $callsign);
227
228
$short_name = $repository->getRepositorySlug();
229
if ($short_name === null) {
230
$short_name = phutil_tag('em', array(), pht('No Short Name'));
231
}
232
$view->addProperty(pht('Short Name'), $short_name);
233
234
$encoding = $repository->getDetail('encoding');
235
if (!$encoding) {
236
$encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)'));
237
}
238
$view->addProperty(pht('Encoding'), $encoding);
239
240
$can_dangerous = $repository->canAllowDangerousChanges();
241
if (!$can_dangerous) {
242
$dangerous = phutil_tag('em', array(), pht('Not Preventable'));
243
} else {
244
$should_dangerous = $repository->shouldAllowDangerousChanges();
245
if ($should_dangerous) {
246
$dangerous = pht('Allowed');
247
} else {
248
$dangerous = pht('Not Allowed');
249
}
250
}
251
252
$view->addProperty(pht('Dangerous Changes'), $dangerous);
253
254
$can_enormous = $repository->canAllowEnormousChanges();
255
if (!$can_enormous) {
256
$enormous = phutil_tag('em', array(), pht('Not Preventable'));
257
} else {
258
$should_enormous = $repository->shouldAllowEnormousChanges();
259
if ($should_enormous) {
260
$enormous = pht('Allowed');
261
} else {
262
$enormous = pht('Not Allowed');
263
}
264
}
265
266
$view->addProperty(pht('Enormous Changes'), $enormous);
267
268
return $view;
269
}
270
271
272
private function buildDescription() {
273
$repository = $this->getRepository();
274
$viewer = $this->getViewer();
275
276
$description = $repository->getDetail('description');
277
278
$view = id(new PHUIPropertyListView())
279
->setViewer($viewer);
280
if (!strlen($description)) {
281
return null;
282
} else {
283
$description = new PHUIRemarkupView($viewer, $description);
284
}
285
$view->addTextContent($description);
286
287
return $view;
288
}
289
290
private function buildStatus() {
291
$repository = $this->getRepository();
292
$viewer = $this->getViewer();
293
294
$view = id(new PHUIPropertyListView())
295
->setViewer($viewer);
296
297
$view->addProperty(
298
pht('Update Frequency'),
299
$this->buildRepositoryUpdateInterval($repository));
300
301
$messages = $this->loadStatusMessages($repository);
302
303
$status = $this->buildRepositoryStatus($repository, $messages);
304
$raw_error = $this->buildRepositoryRawError($repository, $messages);
305
306
$view->addProperty(pht('Status'), $status);
307
if ($raw_error) {
308
$view->addSectionHeader(pht('Raw Error'));
309
$view->addTextContent($raw_error);
310
}
311
312
return $this->newBox(pht('Working Copy Status'), $view);
313
}
314
315
private function buildRepositoryUpdateInterval(
316
PhabricatorRepository $repository) {
317
318
$smart_wait = $repository->loadUpdateInterval();
319
320
$doc_href = PhabricatorEnv::getDoclink(
321
'Diffusion User Guide: Repository Updates');
322
323
return array(
324
phutil_format_relative_time_detailed($smart_wait),
325
" \xC2\xB7 ",
326
phutil_tag(
327
'a',
328
array(
329
'href' => $doc_href,
330
'target' => '_blank',
331
),
332
pht('Learn More')),
333
);
334
}
335
336
private function buildRepositoryStatus(
337
PhabricatorRepository $repository,
338
array $messages) {
339
340
$viewer = $this->getViewer();
341
$is_cluster = $repository->getAlmanacServicePHID();
342
343
$view = new PHUIStatusListView();
344
345
if ($repository->isTracked()) {
346
$view->addItem(
347
id(new PHUIStatusItemView())
348
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
349
->setTarget(pht('Repository Active')));
350
} else {
351
$view->addItem(
352
id(new PHUIStatusItemView())
353
->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey')
354
->setTarget(pht('Repository Inactive'))
355
->setNote(
356
pht('Activate this repository to begin or resume import.')));
357
return $view;
358
}
359
360
$binaries = array();
361
$svnlook_check = false;
362
switch ($repository->getVersionControlSystem()) {
363
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
364
$binaries[] = 'git';
365
break;
366
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
367
$binaries[] = 'svn';
368
break;
369
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
370
$binaries[] = 'hg';
371
break;
372
}
373
374
if ($repository->isHosted()) {
375
$proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS;
376
$proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP;
377
$can_http = $repository->canServeProtocol($proto_http, false) ||
378
$repository->canServeProtocol($proto_https, false);
379
380
if ($can_http) {
381
switch ($repository->getVersionControlSystem()) {
382
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
383
$binaries[] = 'git-http-backend';
384
break;
385
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
386
$binaries[] = 'svnserve';
387
$binaries[] = 'svnadmin';
388
$binaries[] = 'svnlook';
389
$svnlook_check = true;
390
break;
391
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
392
$binaries[] = 'hg';
393
break;
394
}
395
}
396
397
398
$proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH;
399
$can_ssh = $repository->canServeProtocol($proto_ssh, false);
400
401
if ($can_ssh) {
402
switch ($repository->getVersionControlSystem()) {
403
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
404
$binaries[] = 'git-receive-pack';
405
$binaries[] = 'git-upload-pack';
406
break;
407
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
408
$binaries[] = 'svnserve';
409
$binaries[] = 'svnadmin';
410
$binaries[] = 'svnlook';
411
$svnlook_check = true;
412
break;
413
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
414
$binaries[] = 'hg';
415
break;
416
}
417
}
418
}
419
420
$binaries = array_unique($binaries);
421
if (!$is_cluster) {
422
// We're only checking for binaries if we aren't running with a cluster
423
// configuration. In theory, we could check for binaries on the
424
// repository host machine, but we'd need to make this more complicated
425
// to do that.
426
427
foreach ($binaries as $binary) {
428
$where = Filesystem::resolveBinary($binary);
429
if (!$where) {
430
$view->addItem(
431
id(new PHUIStatusItemView())
432
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
433
->setTarget(
434
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
435
->setNote(pht(
436
"Unable to find this binary in the webserver's PATH. You may ".
437
"need to configure %s.",
438
$this->getEnvConfigLink())));
439
} else {
440
$view->addItem(
441
id(new PHUIStatusItemView())
442
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
443
->setTarget(
444
pht('Found Binary %s', phutil_tag('tt', array(), $binary)))
445
->setNote(phutil_tag('tt', array(), $where)));
446
}
447
}
448
449
// This gets checked generically above. However, for svn commit hooks, we
450
// need this to be in environment.append-paths because subversion strips
451
// PATH.
452
if ($svnlook_check) {
453
$where = Filesystem::resolveBinary('svnlook');
454
if ($where) {
455
$path = substr($where, 0, strlen($where) - strlen('svnlook'));
456
$dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
457
$in_path = false;
458
foreach ($dirs as $dir) {
459
if (Filesystem::isDescendant($path, $dir)) {
460
$in_path = true;
461
break;
462
}
463
}
464
if (!$in_path) {
465
$view->addItem(
466
id(new PHUIStatusItemView())
467
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
468
->setTarget(
469
pht('Commit Hooks: %s', phutil_tag('tt', array(), $binary)))
470
->setNote(
471
pht(
472
'The directory containing the "svnlook" binary is not '.
473
'listed in "environment.append-paths", so commit hooks '.
474
'(which execute with an empty "PATH") will not be able to '.
475
'find "svnlook". Add `%s` to %s.',
476
$path,
477
$this->getEnvConfigLink())));
478
}
479
}
480
}
481
}
482
483
$doc_href = PhabricatorEnv::getDoclink('Managing Daemons with phd');
484
485
$daemon_instructions = pht(
486
'Use %s to start daemons. See %s.',
487
phutil_tag('tt', array(), 'bin/phd start'),
488
phutil_tag(
489
'a',
490
array(
491
'href' => $doc_href,
492
),
493
pht('Managing Daemons with phd')));
494
495
496
$pull_daemon = id(new PhabricatorDaemonLogQuery())
497
->setViewer(PhabricatorUser::getOmnipotentUser())
498
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
499
->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon'))
500
->setLimit(1)
501
->execute();
502
503
if ($pull_daemon) {
504
505
// TODO: In a cluster environment, we need a daemon on this repository's
506
// host, specifically, and we aren't checking for that right now. This
507
// is a reasonable proxy for things being more-or-less correctly set up,
508
// though.
509
510
$view->addItem(
511
id(new PHUIStatusItemView())
512
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
513
->setTarget(pht('Pull Daemon Running')));
514
} else {
515
$view->addItem(
516
id(new PHUIStatusItemView())
517
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
518
->setTarget(pht('Pull Daemon Not Running'))
519
->setNote($daemon_instructions));
520
}
521
522
523
$task_daemon = id(new PhabricatorDaemonLogQuery())
524
->setViewer(PhabricatorUser::getOmnipotentUser())
525
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
526
->withDaemonClasses(array('PhabricatorTaskmasterDaemon'))
527
->setLimit(1)
528
->execute();
529
if ($task_daemon) {
530
$view->addItem(
531
id(new PHUIStatusItemView())
532
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
533
->setTarget(pht('Task Daemon Running')));
534
} else {
535
$view->addItem(
536
id(new PHUIStatusItemView())
537
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
538
->setTarget(pht('Task Daemon Not Running'))
539
->setNote($daemon_instructions));
540
}
541
542
543
if ($is_cluster) {
544
// Just omit this status check for now in cluster environments. We
545
// could make a service call and pull it from the repository host
546
// eventually.
547
} else if ($repository->usesLocalWorkingCopy()) {
548
$local_parent = dirname($repository->getLocalPath());
549
if (Filesystem::pathExists($local_parent)) {
550
$view->addItem(
551
id(new PHUIStatusItemView())
552
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
553
->setTarget(pht('Storage Directory OK'))
554
->setNote(phutil_tag('tt', array(), $local_parent)));
555
} else {
556
$view->addItem(
557
id(new PHUIStatusItemView())
558
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
559
->setTarget(pht('No Storage Directory'))
560
->setNote(
561
pht(
562
'Storage directory %s does not exist, or is not readable by '.
563
'the webserver. Create this directory or make it readable.',
564
phutil_tag('tt', array(), $local_parent))));
565
return $view;
566
}
567
568
$local_path = $repository->getLocalPath();
569
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT);
570
if ($message) {
571
switch ($message->getStatusCode()) {
572
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
573
$view->addItem(
574
id(new PHUIStatusItemView())
575
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
576
->setTarget(pht('Initialization Error'))
577
->setNote($message->getParameter('message')));
578
return $view;
579
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
580
if (Filesystem::pathExists($local_path)) {
581
$view->addItem(
582
id(new PHUIStatusItemView())
583
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
584
->setTarget(pht('Working Copy OK'))
585
->setNote(phutil_tag('tt', array(), $local_path)));
586
} else {
587
$view->addItem(
588
id(new PHUIStatusItemView())
589
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
590
->setTarget(pht('Working Copy Error'))
591
->setNote(
592
pht(
593
'Working copy %s has been deleted, or is not '.
594
'readable by the webserver. Make this directory '.
595
'readable. If it has been deleted, the daemons should '.
596
'restore it automatically.',
597
phutil_tag('tt', array(), $local_path))));
598
return $view;
599
}
600
break;
601
default:
602
$view->addItem(
603
id(new PHUIStatusItemView())
604
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
605
->setTarget(pht('Initializing Working Copy'))
606
->setNote(pht('Daemons are initializing the working copy.')));
607
return $view;
608
}
609
} else {
610
$view->addItem(
611
id(new PHUIStatusItemView())
612
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
613
->setTarget(pht('No Working Copy Yet'))
614
->setNote(
615
pht('Waiting for daemons to build a working copy.')));
616
return $view;
617
}
618
}
619
620
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
621
if ($message) {
622
switch ($message->getStatusCode()) {
623
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
624
$message = $message->getParameter('message');
625
626
$suggestion = null;
627
if (preg_match('/Permission denied \(publickey\)./', $message)) {
628
$suggestion = pht(
629
'Public Key Error: This error usually indicates that the '.
630
'keypair you have configured does not have permission to '.
631
'access the repository.');
632
}
633
634
$view->addItem(
635
id(new PHUIStatusItemView())
636
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
637
->setTarget(pht('Update Error'))
638
->setNote($suggestion));
639
return $view;
640
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
641
$ago = (PhabricatorTime::getNow() - $message->getEpoch());
642
$view->addItem(
643
id(new PHUIStatusItemView())
644
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
645
->setTarget(pht('Updates OK'))
646
->setNote(
647
pht(
648
'Last updated %s (%s ago).',
649
phabricator_datetime($message->getEpoch(), $viewer),
650
phutil_format_relative_time_detailed($ago))));
651
break;
652
}
653
} else {
654
$view->addItem(
655
id(new PHUIStatusItemView())
656
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
657
->setTarget(pht('Waiting For Update'))
658
->setNote(
659
pht('Waiting for daemons to read updates.')));
660
}
661
662
if ($repository->isImporting()) {
663
$ratio = $repository->loadImportProgress();
664
$percentage = sprintf('%.2f%%', 100 * $ratio);
665
666
$view->addItem(
667
id(new PHUIStatusItemView())
668
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
669
->setTarget(pht('Importing'))
670
->setNote(
671
pht('%s Complete', $percentage)));
672
} else {
673
$view->addItem(
674
id(new PHUIStatusItemView())
675
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
676
->setTarget(pht('Fully Imported')));
677
}
678
679
if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) {
680
$view->addItem(
681
id(new PHUIStatusItemView())
682
->setIcon(PHUIStatusItemView::ICON_UP, 'indigo')
683
->setTarget(pht('Prioritized'))
684
->setNote(pht('This repository will be updated soon!')));
685
}
686
687
return $view;
688
}
689
690
private function buildRepositoryRawError(
691
PhabricatorRepository $repository,
692
array $messages) {
693
$viewer = $this->getViewer();
694
695
$can_edit = PhabricatorPolicyFilter::hasCapability(
696
$viewer,
697
$repository,
698
PhabricatorPolicyCapability::CAN_EDIT);
699
700
$raw_error = null;
701
702
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
703
if ($message) {
704
switch ($message->getStatusCode()) {
705
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
706
$raw_error = $message->getParameter('message');
707
break;
708
}
709
}
710
711
if ($raw_error !== null) {
712
if (!$can_edit) {
713
$raw_message = pht(
714
'You must be able to edit a repository to see raw error messages '.
715
'because they sometimes disclose sensitive information.');
716
$raw_message = phutil_tag('em', array(), $raw_message);
717
} else {
718
$raw_message = phutil_escape_html_newlines($raw_error);
719
}
720
} else {
721
$raw_message = null;
722
}
723
724
return $raw_message;
725
}
726
727
private function loadStatusMessages(PhabricatorRepository $repository) {
728
$messages = id(new PhabricatorRepositoryStatusMessage())
729
->loadAllWhere('repositoryID = %d', $repository->getID());
730
$messages = mpull($messages, null, 'getStatusType');
731
732
return $messages;
733
}
734
735
private function getEnvConfigLink() {
736
$config_href = '/config/edit/environment.append-paths/';
737
return phutil_tag(
738
'a',
739
array(
740
'href' => $config_href,
741
),
742
'environment.append-paths');
743
}
744
745
private function buildStateView(PhabricatorRepository $repository) {
746
$viewer = $this->getViewer();
747
$is_new = $repository->isNewlyInitialized();
748
749
$view = id(new PHUIPropertyListView())
750
->setViewer($viewer);
751
752
if (!$repository->isTracked()) {
753
if ($is_new) {
754
$active_icon = 'fa-ban';
755
$active_color = 'yellow';
756
$active_label = pht('Not Activated Yet');
757
$active_note = pht('Complete Setup and Activate Repository');
758
} else {
759
$active_icon = 'fa-times';
760
$active_color = 'red';
761
$active_label = pht('Not Active');
762
$active_note = pht('Repository Disabled');
763
}
764
} else if ($repository->isImporting()) {
765
$active_icon = 'fa-hourglass';
766
$active_color = 'yellow';
767
$active_label = pht('Importing...');
768
$active_note = null;
769
} else {
770
$active_icon = 'fa-check';
771
$active_color = 'green';
772
$active_label = pht('Repository Active');
773
$active_note = null;
774
}
775
776
$active_view = id(new PHUIStatusListView())
777
->addItem(
778
id(new PHUIStatusItemView())
779
->setIcon($active_icon, $active_color)
780
->setTarget($active_label)
781
->setNote($active_note));
782
783
if ($repository->isPublishingDisabled()) {
784
$publishing_icon = 'fa-times';
785
$publishing_color = 'red';
786
$publishing_label = pht('Not Publishing');
787
$publishing_note = pht('Publishing Disabled');
788
} else if (!$repository->isTracked()) {
789
$publishing_icon = 'fa-ban';
790
$publishing_color = 'yellow';
791
$publishing_label = pht('Not Publishing');
792
if ($is_new) {
793
$publishing_note = pht('Repository Not Active Yet');
794
} else {
795
$publishing_note = pht('Repository Inactive');
796
}
797
} else if ($repository->isImporting()) {
798
$publishing_icon = 'fa-ban';
799
$publishing_color = 'yellow';
800
$publishing_label = pht('Not Publishing');
801
$publishing_note = pht('Repository Importing');
802
} else {
803
$publishing_icon = 'fa-check';
804
$publishing_color = 'green';
805
$publishing_label = pht('Publishing Active');
806
$publishing_note = null;
807
}
808
809
$publishing_view = id(new PHUIStatusListView())
810
->addItem(
811
id(new PHUIStatusItemView())
812
->setIcon($publishing_icon, $publishing_color)
813
->setTarget($publishing_label)
814
->setNote($publishing_note));
815
816
$view->addProperty(pht('Active'), $active_view);
817
$view->addProperty(pht('Publishing'), $publishing_view);
818
819
return $this->newBox(pht('State'), $view);
820
}
821
822
}
823
824