[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class DiffusionRepositoryEditMainController 4 extends DiffusionRepositoryEditController { 5 6 public function processRequest() { 7 $request = $this->getRequest(); 8 $viewer = $request->getUser(); 9 $drequest = $this->diffusionRequest; 10 $repository = $drequest->getRepository(); 11 12 PhabricatorPolicyFilter::requireCapability( 13 $viewer, 14 $repository, 15 PhabricatorPolicyCapability::CAN_EDIT); 16 17 $is_svn = false; 18 $is_git = false; 19 $is_hg = false; 20 switch ($repository->getVersionControlSystem()) { 21 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 22 $is_git = true; 23 break; 24 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 25 $is_svn = true; 26 break; 27 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 28 $is_hg = true; 29 break; 30 } 31 32 $has_branches = ($is_git || $is_hg); 33 $has_local = $repository->usesLocalWorkingCopy(); 34 35 $crumbs = $this->buildApplicationCrumbs($is_main = true); 36 37 $title = pht('Edit %s', $repository->getName()); 38 39 $header = id(new PHUIHeaderView()) 40 ->setHeader($title); 41 if ($repository->isTracked()) { 42 $header->setStatus('fa-check', 'bluegrey', pht('Active')); 43 } else { 44 $header->setStatus('fa-ban', 'dark', pht('Inactive')); 45 } 46 47 $basic_actions = $this->buildBasicActions($repository); 48 $basic_properties = 49 $this->buildBasicProperties($repository, $basic_actions); 50 51 $policy_actions = $this->buildPolicyActions($repository); 52 $policy_properties = 53 $this->buildPolicyProperties($repository, $policy_actions); 54 55 $remote_properties = null; 56 if (!$repository->isHosted()) { 57 $remote_properties = $this->buildRemoteProperties( 58 $repository, 59 $this->buildRemoteActions($repository)); 60 } 61 62 $encoding_actions = $this->buildEncodingActions($repository); 63 $encoding_properties = 64 $this->buildEncodingProperties($repository, $encoding_actions); 65 66 $hosting_properties = $this->buildHostingProperties( 67 $repository, 68 $this->buildHostingActions($repository)); 69 70 71 $branches_properties = null; 72 if ($has_branches) { 73 $branches_properties = $this->buildBranchesProperties( 74 $repository, 75 $this->buildBranchesActions($repository)); 76 } 77 78 $subversion_properties = null; 79 if ($is_svn) { 80 $subversion_properties = $this->buildSubversionProperties( 81 $repository, 82 $this->buildSubversionActions($repository)); 83 } 84 85 $local_properties = null; 86 if ($has_local) { 87 $local_properties = $this->buildLocalProperties( 88 $repository, 89 $this->buildLocalActions($repository)); 90 } 91 92 $actions_properties = $this->buildActionsProperties( 93 $repository, 94 $this->buildActionsActions($repository)); 95 96 $xactions = id(new PhabricatorRepositoryTransactionQuery()) 97 ->setViewer($viewer) 98 ->withObjectPHIDs(array($repository->getPHID())) 99 ->execute(); 100 101 $engine = id(new PhabricatorMarkupEngine()) 102 ->setViewer($viewer); 103 foreach ($xactions as $xaction) { 104 if ($xaction->getComment()) { 105 $engine->addObject( 106 $xaction->getComment(), 107 PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT); 108 } 109 } 110 $engine->process(); 111 112 $xaction_view = id(new PhabricatorApplicationTransactionView()) 113 ->setUser($viewer) 114 ->setObjectPHID($repository->getPHID()) 115 ->setTransactions($xactions) 116 ->setMarkupEngine($engine); 117 118 $boxes = array(); 119 120 $boxes[] = id(new PHUIObjectBoxView()) 121 ->setHeader($header) 122 ->addPropertyList($basic_properties); 123 124 $boxes[] = id(new PHUIObjectBoxView()) 125 ->setHeaderText(pht('Policies')) 126 ->addPropertyList($policy_properties); 127 128 $boxes[] = id(new PHUIObjectBoxView()) 129 ->setHeaderText(pht('Hosting')) 130 ->addPropertyList($hosting_properties); 131 132 if ($repository->canMirror()) { 133 $mirror_actions = $this->buildMirrorActions($repository); 134 $mirror_properties = $this->buildMirrorProperties( 135 $repository, 136 $mirror_actions); 137 138 $mirrors = id(new PhabricatorRepositoryMirrorQuery()) 139 ->setViewer($viewer) 140 ->withRepositoryPHIDs(array($repository->getPHID())) 141 ->execute(); 142 143 $mirror_list = $this->buildMirrorList($repository, $mirrors); 144 145 $boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors'); 146 147 $boxes[] = id(new PHUIObjectBoxView()) 148 ->setHeaderText(pht('Mirrors')) 149 ->addPropertyList($mirror_properties); 150 151 $boxes[] = $mirror_list; 152 } 153 154 if ($remote_properties) { 155 $boxes[] = id(new PHUIObjectBoxView()) 156 ->setHeaderText(pht('Remote')) 157 ->addPropertyList($remote_properties); 158 } 159 160 if ($local_properties) { 161 $boxes[] = id(new PHUIObjectBoxView()) 162 ->setHeaderText(pht('Local')) 163 ->addPropertyList($local_properties); 164 } 165 166 $boxes[] = id(new PHUIObjectBoxView()) 167 ->setHeaderText(pht('Text Encoding')) 168 ->addPropertyList($encoding_properties); 169 170 if ($branches_properties) { 171 $boxes[] = id(new PHUIObjectBoxView()) 172 ->setHeaderText(pht('Branches')) 173 ->addPropertyList($branches_properties); 174 } 175 176 if ($subversion_properties) { 177 $boxes[] = id(new PHUIObjectBoxView()) 178 ->setHeaderText(pht('Subversion')) 179 ->addPropertyList($subversion_properties); 180 } 181 182 $boxes[] = id(new PHUIObjectBoxView()) 183 ->setHeaderText(pht('Actions')) 184 ->addPropertyList($actions_properties); 185 186 return $this->buildApplicationPage( 187 array( 188 $crumbs, 189 $boxes, 190 $xaction_view, 191 ), 192 array( 193 'title' => $title, 194 )); 195 } 196 197 private function buildBasicActions(PhabricatorRepository $repository) { 198 $viewer = $this->getRequest()->getUser(); 199 200 $view = id(new PhabricatorActionListView()) 201 ->setObjectURI($this->getRequest()->getRequestURI()) 202 ->setUser($viewer); 203 204 $edit = id(new PhabricatorActionView()) 205 ->setIcon('fa-pencil') 206 ->setName(pht('Edit Basic Information')) 207 ->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/')); 208 $view->addAction($edit); 209 210 $edit = id(new PhabricatorActionView()) 211 ->setIcon('fa-refresh') 212 ->setName(pht('Update Now')) 213 ->setWorkflow(true) 214 ->setHref( 215 $this->getRepositoryControllerURI($repository, 'edit/update/')); 216 $view->addAction($edit); 217 218 $activate = id(new PhabricatorActionView()) 219 ->setHref( 220 $this->getRepositoryControllerURI($repository, 'edit/activate/')) 221 ->setWorkflow(true); 222 223 if ($repository->isTracked()) { 224 $activate 225 ->setIcon('fa-pause') 226 ->setName(pht('Deactivate Repository')); 227 } else { 228 $activate 229 ->setIcon('fa-play') 230 ->setName(pht('Activate Repository')); 231 } 232 233 $view->addAction($activate); 234 235 $view->addAction( 236 id(new PhabricatorActionView()) 237 ->setName(pht('Delete Repository')) 238 ->setIcon('fa-times') 239 ->setHref( 240 $this->getRepositoryControllerURI($repository, 'edit/delete/')) 241 ->setDisabled(true) 242 ->setWorkflow(true)); 243 244 return $view; 245 } 246 247 private function buildBasicProperties( 248 PhabricatorRepository $repository, 249 PhabricatorActionListView $actions) { 250 251 $viewer = $this->getRequest()->getUser(); 252 253 $view = id(new PHUIPropertyListView()) 254 ->setUser($viewer) 255 ->setActionList($actions); 256 257 $type = PhabricatorRepositoryType::getNameForRepositoryType( 258 $repository->getVersionControlSystem()); 259 260 $view->addProperty(pht('Type'), $type); 261 $view->addProperty(pht('Callsign'), $repository->getCallsign()); 262 263 264 $clone_name = $repository->getDetail('clone-name'); 265 266 if ($repository->isHosted()) { 267 $view->addProperty( 268 pht('Clone/Checkout As'), 269 $clone_name 270 ? $clone_name.'/' 271 : phutil_tag('em', array(), $repository->getCloneName().'/')); 272 } 273 274 $project_phids = PhabricatorEdgeQuery::loadDestinationPHIDs( 275 $repository->getPHID(), 276 PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 277 if ($project_phids) { 278 $this->loadHandles($project_phids); 279 $project_text = $this->renderHandlesForPHIDs($project_phids); 280 } else { 281 $project_text = phutil_tag('em', array(), pht('None')); 282 } 283 $view->addProperty( 284 pht('Projects'), 285 $project_text); 286 287 $view->addProperty( 288 pht('Status'), 289 $this->buildRepositoryStatus($repository)); 290 291 $view->addProperty( 292 pht('Update Frequency'), 293 $this->buildRepositoryUpdateInterval($repository)); 294 295 $description = $repository->getDetail('description'); 296 $view->addSectionHeader(pht('Description')); 297 if (!strlen($description)) { 298 $description = phutil_tag('em', array(), pht('No description provided.')); 299 } else { 300 $description = PhabricatorMarkupEngine::renderOneObject( 301 $repository, 302 'description', 303 $viewer); 304 } 305 $view->addTextContent($description); 306 307 return $view; 308 } 309 310 private function buildEncodingActions(PhabricatorRepository $repository) { 311 $viewer = $this->getRequest()->getUser(); 312 313 $view = id(new PhabricatorActionListView()) 314 ->setObjectURI($this->getRequest()->getRequestURI()) 315 ->setUser($viewer); 316 317 $edit = id(new PhabricatorActionView()) 318 ->setIcon('fa-pencil') 319 ->setName(pht('Edit Text Encoding')) 320 ->setHref( 321 $this->getRepositoryControllerURI($repository, 'edit/encoding/')); 322 $view->addAction($edit); 323 324 return $view; 325 } 326 327 private function buildEncodingProperties( 328 PhabricatorRepository $repository, 329 PhabricatorActionListView $actions) { 330 331 $viewer = $this->getRequest()->getUser(); 332 333 $view = id(new PHUIPropertyListView()) 334 ->setUser($viewer) 335 ->setActionList($actions); 336 337 $encoding = $repository->getDetail('encoding'); 338 if (!$encoding) { 339 $encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)')); 340 } 341 342 $view->addProperty(pht('Encoding'), $encoding); 343 344 return $view; 345 } 346 347 private function buildPolicyActions(PhabricatorRepository $repository) { 348 $viewer = $this->getRequest()->getUser(); 349 350 $view = id(new PhabricatorActionListView()) 351 ->setObjectURI($this->getRequest()->getRequestURI()) 352 ->setUser($viewer); 353 354 $edit = id(new PhabricatorActionView()) 355 ->setIcon('fa-pencil') 356 ->setName(pht('Edit Policies')) 357 ->setHref( 358 $this->getRepositoryControllerURI($repository, 'edit/policy/')); 359 $view->addAction($edit); 360 361 return $view; 362 } 363 364 private function buildPolicyProperties( 365 PhabricatorRepository $repository, 366 PhabricatorActionListView $actions) { 367 368 $viewer = $this->getRequest()->getUser(); 369 370 $view = id(new PHUIPropertyListView()) 371 ->setUser($viewer) 372 ->setActionList($actions); 373 374 $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( 375 $viewer, 376 $repository); 377 378 $view->addProperty( 379 pht('Visible To'), 380 $descriptions[PhabricatorPolicyCapability::CAN_VIEW]); 381 382 $view->addProperty( 383 pht('Editable By'), 384 $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); 385 386 $pushable = $repository->isHosted() 387 ? $descriptions[DiffusionPushCapability::CAPABILITY] 388 : phutil_tag('em', array(), pht('Not a Hosted Repository')); 389 $view->addProperty(pht('Pushable By'), $pushable); 390 391 return $view; 392 } 393 394 private function buildBranchesActions(PhabricatorRepository $repository) { 395 $viewer = $this->getRequest()->getUser(); 396 397 $view = id(new PhabricatorActionListView()) 398 ->setObjectURI($this->getRequest()->getRequestURI()) 399 ->setUser($viewer); 400 401 $edit = id(new PhabricatorActionView()) 402 ->setIcon('fa-pencil') 403 ->setName(pht('Edit Branches')) 404 ->setHref( 405 $this->getRepositoryControllerURI($repository, 'edit/branches/')); 406 $view->addAction($edit); 407 408 return $view; 409 } 410 411 private function buildBranchesProperties( 412 PhabricatorRepository $repository, 413 PhabricatorActionListView $actions) { 414 415 $viewer = $this->getRequest()->getUser(); 416 417 $view = id(new PHUIPropertyListView()) 418 ->setUser($viewer) 419 ->setActionList($actions); 420 421 $default_branch = nonempty( 422 $repository->getHumanReadableDetail('default-branch'), 423 phutil_tag('em', array(), $repository->getDefaultBranch())); 424 $view->addProperty(pht('Default Branch'), $default_branch); 425 426 $track_only = nonempty( 427 $repository->getHumanReadableDetail('branch-filter', array()), 428 phutil_tag('em', array(), pht('Track All Branches'))); 429 $view->addProperty(pht('Track Only'), $track_only); 430 431 $autoclose_only = nonempty( 432 $repository->getHumanReadableDetail('close-commits-filter', array()), 433 phutil_tag('em', array(), pht('Autoclose On All Branches'))); 434 435 if ($repository->getDetail('disable-autoclose')) { 436 $autoclose_only = phutil_tag('em', array(), pht('Disabled')); 437 } 438 439 $view->addProperty(pht('Autoclose Only'), $autoclose_only); 440 441 return $view; 442 } 443 444 private function buildSubversionActions(PhabricatorRepository $repository) { 445 $viewer = $this->getRequest()->getUser(); 446 447 $view = id(new PhabricatorActionListView()) 448 ->setObjectURI($this->getRequest()->getRequestURI()) 449 ->setUser($viewer); 450 451 $edit = id(new PhabricatorActionView()) 452 ->setIcon('fa-pencil') 453 ->setName(pht('Edit Subversion Info')) 454 ->setHref( 455 $this->getRepositoryControllerURI($repository, 'edit/subversion/')); 456 $view->addAction($edit); 457 458 return $view; 459 } 460 461 private function buildSubversionProperties( 462 PhabricatorRepository $repository, 463 PhabricatorActionListView $actions) { 464 465 $viewer = $this->getRequest()->getUser(); 466 467 $view = id(new PHUIPropertyListView()) 468 ->setUser($viewer) 469 ->setActionList($actions); 470 471 $svn_uuid = nonempty( 472 $repository->getUUID(), 473 phutil_tag('em', array(), pht('Not Configured'))); 474 $view->addProperty(pht('Subversion UUID'), $svn_uuid); 475 476 $svn_subpath = nonempty( 477 $repository->getHumanReadableDetail('svn-subpath'), 478 phutil_tag('em', array(), pht('Import Entire Repository'))); 479 $view->addProperty(pht('Import Only'), $svn_subpath); 480 481 return $view; 482 } 483 484 private function buildActionsActions(PhabricatorRepository $repository) { 485 $viewer = $this->getRequest()->getUser(); 486 487 $view = id(new PhabricatorActionListView()) 488 ->setObjectURI($this->getRequest()->getRequestURI()) 489 ->setUser($viewer); 490 491 $edit = id(new PhabricatorActionView()) 492 ->setIcon('fa-pencil') 493 ->setName(pht('Edit Actions')) 494 ->setHref( 495 $this->getRepositoryControllerURI($repository, 'edit/actions/')); 496 $view->addAction($edit); 497 498 return $view; 499 } 500 501 private function buildActionsProperties( 502 PhabricatorRepository $repository, 503 PhabricatorActionListView $actions) { 504 505 $viewer = $this->getRequest()->getUser(); 506 507 $view = id(new PHUIPropertyListView()) 508 ->setUser($viewer) 509 ->setActionList($actions); 510 511 $notify = $repository->getDetail('herald-disabled') 512 ? pht('Off') 513 : pht('On'); 514 $notify = phutil_tag('em', array(), $notify); 515 $view->addProperty(pht('Publish/Notify'), $notify); 516 517 $autoclose = $repository->getDetail('disable-autoclose') 518 ? pht('Off') 519 : pht('On'); 520 $autoclose = phutil_tag('em', array(), $autoclose); 521 $view->addProperty(pht('Autoclose'), $autoclose); 522 523 return $view; 524 } 525 526 private function buildRemoteActions(PhabricatorRepository $repository) { 527 $viewer = $this->getRequest()->getUser(); 528 529 $view = id(new PhabricatorActionListView()) 530 ->setObjectURI($this->getRequest()->getRequestURI()) 531 ->setUser($viewer); 532 533 $edit = id(new PhabricatorActionView()) 534 ->setIcon('fa-pencil') 535 ->setName(pht('Edit Remote')) 536 ->setHref( 537 $this->getRepositoryControllerURI($repository, 'edit/remote/')); 538 $view->addAction($edit); 539 540 return $view; 541 } 542 543 private function buildRemoteProperties( 544 PhabricatorRepository $repository, 545 PhabricatorActionListView $actions) { 546 547 $viewer = $this->getRequest()->getUser(); 548 549 $view = id(new PHUIPropertyListView()) 550 ->setUser($viewer) 551 ->setActionList($actions); 552 553 $view->addProperty( 554 pht('Remote URI'), 555 $repository->getHumanReadableDetail('remote-uri')); 556 557 $credential_phid = $repository->getCredentialPHID(); 558 if ($credential_phid) { 559 $this->loadHandles(array($credential_phid)); 560 $view->addProperty( 561 pht('Credential'), 562 $this->getHandle($credential_phid)->renderLink()); 563 } 564 565 return $view; 566 } 567 568 private function buildLocalActions(PhabricatorRepository $repository) { 569 $viewer = $this->getRequest()->getUser(); 570 571 $view = id(new PhabricatorActionListView()) 572 ->setObjectURI($this->getRequest()->getRequestURI()) 573 ->setUser($viewer); 574 575 $edit = id(new PhabricatorActionView()) 576 ->setIcon('fa-pencil') 577 ->setName(pht('Edit Local')) 578 ->setHref( 579 $this->getRepositoryControllerURI($repository, 'edit/local/')); 580 $view->addAction($edit); 581 582 return $view; 583 } 584 585 private function buildLocalProperties( 586 PhabricatorRepository $repository, 587 PhabricatorActionListView $actions) { 588 589 $viewer = $this->getRequest()->getUser(); 590 591 $view = id(new PHUIPropertyListView()) 592 ->setUser($viewer) 593 ->setActionList($actions); 594 595 $view->addProperty( 596 pht('Local Path'), 597 $repository->getHumanReadableDetail('local-path')); 598 599 return $view; 600 } 601 602 private function buildHostingActions(PhabricatorRepository $repository) { 603 $user = $this->getRequest()->getUser(); 604 605 $view = id(new PhabricatorActionListView()) 606 ->setObjectURI($this->getRequest()->getRequestURI()) 607 ->setUser($user); 608 609 $edit = id(new PhabricatorActionView()) 610 ->setIcon('fa-pencil') 611 ->setName(pht('Edit Hosting')) 612 ->setHref( 613 $this->getRepositoryControllerURI($repository, 'edit/hosting/')); 614 $view->addAction($edit); 615 616 if ($repository->canAllowDangerousChanges()) { 617 if ($repository->shouldAllowDangerousChanges()) { 618 $changes = id(new PhabricatorActionView()) 619 ->setIcon('fa-shield') 620 ->setName(pht('Prevent Dangerous Changes')) 621 ->setHref( 622 $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) 623 ->setWorkflow(true); 624 } else { 625 $changes = id(new PhabricatorActionView()) 626 ->setIcon('fa-bullseye') 627 ->setName(pht('Allow Dangerous Changes')) 628 ->setHref( 629 $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) 630 ->setWorkflow(true); 631 } 632 $view->addAction($changes); 633 } 634 635 return $view; 636 } 637 638 private function buildHostingProperties( 639 PhabricatorRepository $repository, 640 PhabricatorActionListView $actions) { 641 642 $user = $this->getRequest()->getUser(); 643 644 $view = id(new PHUIPropertyListView()) 645 ->setUser($user) 646 ->setActionList($actions); 647 648 $hosting = $repository->isHosted() 649 ? pht('Hosted on Phabricator') 650 : pht('Hosted Elsewhere'); 651 $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting)); 652 653 $view->addProperty( 654 pht('Serve over HTTP'), 655 phutil_tag( 656 'em', 657 array(), 658 PhabricatorRepository::getProtocolAvailabilityName( 659 $repository->getServeOverHTTP()))); 660 661 $view->addProperty( 662 pht('Serve over SSH'), 663 phutil_tag( 664 'em', 665 array(), 666 PhabricatorRepository::getProtocolAvailabilityName( 667 $repository->getServeOverSSH()))); 668 669 if ($repository->canAllowDangerousChanges()) { 670 if ($repository->shouldAllowDangerousChanges()) { 671 $description = pht('Allowed'); 672 } else { 673 $description = pht('Not Allowed'); 674 } 675 676 $view->addProperty( 677 pht('Dangerous Changes'), 678 $description); 679 } 680 681 return $view; 682 } 683 684 private function buildRepositoryStatus( 685 PhabricatorRepository $repository) { 686 687 $viewer = $this->getRequest()->getUser(); 688 689 $view = new PHUIStatusListView(); 690 691 $messages = id(new PhabricatorRepositoryStatusMessage()) 692 ->loadAllWhere('repositoryID = %d', $repository->getID()); 693 $messages = mpull($messages, null, 'getStatusType'); 694 695 if ($repository->isTracked()) { 696 $view->addItem( 697 id(new PHUIStatusItemView()) 698 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 699 ->setTarget(pht('Repository Active'))); 700 } else { 701 $view->addItem( 702 id(new PHUIStatusItemView()) 703 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') 704 ->setTarget(pht('Repository Inactive')) 705 ->setNote( 706 pht('Activate this repository to begin or resume import.'))); 707 return $view; 708 } 709 710 $binaries = array(); 711 $svnlook_check = false; 712 switch ($repository->getVersionControlSystem()) { 713 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 714 $binaries[] = 'git'; 715 break; 716 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 717 $binaries[] = 'svn'; 718 break; 719 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 720 $binaries[] = 'hg'; 721 break; 722 } 723 724 if ($repository->isHosted()) { 725 if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { 726 switch ($repository->getVersionControlSystem()) { 727 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 728 $binaries[] = 'git-http-backend'; 729 break; 730 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 731 $binaries[] = 'svnserve'; 732 $binaries[] = 'svnadmin'; 733 $binaries[] = 'svnlook'; 734 $svnlook_check = true; 735 break; 736 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 737 $binaries[] = 'hg'; 738 break; 739 } 740 } 741 if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { 742 switch ($repository->getVersionControlSystem()) { 743 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 744 $binaries[] = 'git-receive-pack'; 745 $binaries[] = 'git-upload-pack'; 746 break; 747 case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 748 $binaries[] = 'svnserve'; 749 $binaries[] = 'svnadmin'; 750 $binaries[] = 'svnlook'; 751 $svnlook_check = true; 752 break; 753 case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 754 $binaries[] = 'hg'; 755 break; 756 } 757 } 758 } 759 760 $binaries = array_unique($binaries); 761 foreach ($binaries as $binary) { 762 $where = Filesystem::resolveBinary($binary); 763 if (!$where) { 764 $view->addItem( 765 id(new PHUIStatusItemView()) 766 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 767 ->setTarget( 768 pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) 769 ->setNote(pht( 770 "Unable to find this binary in the webserver's PATH. You may ". 771 "need to configure %s.", 772 $this->getEnvConfigLink()))); 773 } else { 774 $view->addItem( 775 id(new PHUIStatusItemView()) 776 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 777 ->setTarget( 778 pht('Found Binary %s', phutil_tag('tt', array(), $binary))) 779 ->setNote(phutil_tag('tt', array(), $where))); 780 } 781 } 782 783 // This gets checked generically above. However, for svn commit hooks, we 784 // need this to be in environment.append-paths because subversion strips 785 // PATH. 786 if ($svnlook_check) { 787 $where = Filesystem::resolveBinary('svnlook'); 788 if ($where) { 789 $path = substr($where, 0, strlen($where) - strlen('svnlook')); 790 $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); 791 $in_path = false; 792 foreach ($dirs as $dir) { 793 if (Filesystem::isDescendant($path, $dir)) { 794 $in_path = true; 795 break; 796 } 797 } 798 if (!$in_path) { 799 $view->addItem( 800 id(new PHUIStatusItemView()) 801 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 802 ->setTarget( 803 pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) 804 ->setNote(pht( 805 'Unable to find this binary in `environment.append-paths`. '. 806 'You need to configure %s and include %s.', 807 $this->getEnvConfigLink(), 808 $path))); 809 } 810 } 811 } 812 813 $doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd'); 814 815 $daemon_instructions = pht( 816 'Use %s to start daemons. See %s.', 817 phutil_tag('tt', array(), 'bin/phd start'), 818 phutil_tag( 819 'a', 820 array( 821 'href' => $doc_href, 822 ), 823 pht('Managing Daemons with phd'))); 824 825 826 $pull_daemon = id(new PhabricatorDaemonLogQuery()) 827 ->setViewer(PhabricatorUser::getOmnipotentUser()) 828 ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) 829 ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) 830 ->setLimit(1) 831 ->execute(); 832 833 if ($pull_daemon) { 834 $view->addItem( 835 id(new PHUIStatusItemView()) 836 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 837 ->setTarget(pht('Pull Daemon Running'))); 838 } else { 839 $view->addItem( 840 id(new PHUIStatusItemView()) 841 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 842 ->setTarget(pht('Pull Daemon Not Running')) 843 ->setNote($daemon_instructions)); 844 } 845 846 847 $task_daemon = id(new PhabricatorDaemonLogQuery()) 848 ->setViewer(PhabricatorUser::getOmnipotentUser()) 849 ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) 850 ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) 851 ->setLimit(1) 852 ->execute(); 853 if ($task_daemon) { 854 $view->addItem( 855 id(new PHUIStatusItemView()) 856 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 857 ->setTarget(pht('Task Daemon Running'))); 858 } else { 859 $view->addItem( 860 id(new PHUIStatusItemView()) 861 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 862 ->setTarget(pht('Task Daemon Not Running')) 863 ->setNote($daemon_instructions)); 864 } 865 866 if ($repository->usesLocalWorkingCopy()) { 867 $local_parent = dirname($repository->getLocalPath()); 868 if (Filesystem::pathExists($local_parent)) { 869 $view->addItem( 870 id(new PHUIStatusItemView()) 871 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 872 ->setTarget(pht('Storage Directory OK')) 873 ->setNote(phutil_tag('tt', array(), $local_parent))); 874 } else { 875 $view->addItem( 876 id(new PHUIStatusItemView()) 877 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 878 ->setTarget(pht('No Storage Directory')) 879 ->setNote( 880 pht( 881 'Storage directory %s does not exist, or is not readable by '. 882 'the webserver. Create this directory or make it readable.', 883 phutil_tag('tt', array(), $local_parent)))); 884 return $view; 885 } 886 887 $local_path = $repository->getLocalPath(); 888 $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); 889 if ($message) { 890 switch ($message->getStatusCode()) { 891 case PhabricatorRepositoryStatusMessage::CODE_ERROR: 892 $view->addItem( 893 id(new PHUIStatusItemView()) 894 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 895 ->setTarget(pht('Initialization Error')) 896 ->setNote($message->getParameter('message'))); 897 return $view; 898 case PhabricatorRepositoryStatusMessage::CODE_OKAY: 899 if (Filesystem::pathExists($local_path)) { 900 $view->addItem( 901 id(new PHUIStatusItemView()) 902 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 903 ->setTarget(pht('Working Copy OK')) 904 ->setNote(phutil_tag('tt', array(), $local_path))); 905 } else { 906 $view->addItem( 907 id(new PHUIStatusItemView()) 908 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 909 ->setTarget(pht('Working Copy Error')) 910 ->setNote( 911 pht( 912 'Working copy %s has been deleted, or is not '. 913 'readable by the webserver. Make this directory '. 914 'readable. If it has been deleted, the daemons should '. 915 'restore it automatically.', 916 phutil_tag('tt', array(), $local_path)))); 917 return $view; 918 } 919 break; 920 case PhabricatorRepositoryStatusMessage::CODE_WORKING: 921 $view->addItem( 922 id(new PHUIStatusItemView()) 923 ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') 924 ->setTarget(pht('Initializing Working Copy')) 925 ->setNote(pht('Daemons are initializing the working copy.'))); 926 return $view; 927 default: 928 $view->addItem( 929 id(new PHUIStatusItemView()) 930 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 931 ->setTarget(pht('Unknown Init Status')) 932 ->setNote($message->getStatusCode())); 933 return $view; 934 } 935 } else { 936 $view->addItem( 937 id(new PHUIStatusItemView()) 938 ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') 939 ->setTarget(pht('No Working Copy Yet')) 940 ->setNote( 941 pht('Waiting for daemons to build a working copy.'))); 942 return $view; 943 } 944 } 945 946 $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); 947 if ($message) { 948 switch ($message->getStatusCode()) { 949 case PhabricatorRepositoryStatusMessage::CODE_ERROR: 950 $view->addItem( 951 id(new PHUIStatusItemView()) 952 ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 953 ->setTarget(pht('Update Error')) 954 ->setNote($message->getParameter('message'))); 955 return $view; 956 case PhabricatorRepositoryStatusMessage::CODE_OKAY: 957 $ago = (PhabricatorTime::getNow() - $message->getEpoch()); 958 $view->addItem( 959 id(new PHUIStatusItemView()) 960 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 961 ->setTarget(pht('Updates OK')) 962 ->setNote( 963 pht( 964 'Last updated %s (%s ago).', 965 phabricator_datetime($message->getEpoch(), $viewer), 966 phutil_format_relative_time_detailed($ago)))); 967 break; 968 } 969 } else { 970 $view->addItem( 971 id(new PHUIStatusItemView()) 972 ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') 973 ->setTarget(pht('Waiting For Update')) 974 ->setNote( 975 pht('Waiting for daemons to read updates.'))); 976 } 977 978 if ($repository->isImporting()) { 979 $progress = queryfx_all( 980 $repository->establishConnection('r'), 981 'SELECT importStatus, count(*) N FROM %T WHERE repositoryID = %d 982 GROUP BY importStatus', 983 id(new PhabricatorRepositoryCommit())->getTableName(), 984 $repository->getID()); 985 986 $done = 0; 987 $total = 0; 988 foreach ($progress as $row) { 989 $total += $row['N'] * 4; 990 $status = $row['importStatus']; 991 if ($status & PhabricatorRepositoryCommit::IMPORTED_MESSAGE) { 992 $done += $row['N']; 993 } 994 if ($status & PhabricatorRepositoryCommit::IMPORTED_CHANGE) { 995 $done += $row['N']; 996 } 997 if ($status & PhabricatorRepositoryCommit::IMPORTED_OWNERS) { 998 $done += $row['N']; 999 } 1000 if ($status & PhabricatorRepositoryCommit::IMPORTED_HERALD) { 1001 $done += $row['N']; 1002 } 1003 } 1004 1005 if ($total) { 1006 $percentage = 100 * ($done / $total); 1007 } else { 1008 $percentage = 0; 1009 } 1010 1011 // Cap this at "99.99%", because it's confusing to users when the actual 1012 // fraction is "99.996%" and it rounds up to "100.00%". 1013 if ($percentage > 99.99) { 1014 $percentage = 99.99; 1015 } 1016 1017 $percentage = sprintf('%.2f%%', $percentage); 1018 1019 $view->addItem( 1020 id(new PHUIStatusItemView()) 1021 ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') 1022 ->setTarget(pht('Importing')) 1023 ->setNote( 1024 pht('%s Complete', $percentage))); 1025 } else { 1026 $view->addItem( 1027 id(new PHUIStatusItemView()) 1028 ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 1029 ->setTarget(pht('Fully Imported'))); 1030 } 1031 1032 if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { 1033 $view->addItem( 1034 id(new PHUIStatusItemView()) 1035 ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') 1036 ->setTarget(pht('Prioritized')) 1037 ->setNote(pht('This repository will be updated soon!'))); 1038 } 1039 1040 return $view; 1041 } 1042 1043 private function buildRepositoryUpdateInterval( 1044 PhabricatorRepository $repository) { 1045 1046 $smart_wait = $repository->loadUpdateInterval(); 1047 1048 $doc_href = PhabricatorEnv::getDoclink( 1049 'Diffusion User Guide: Repository Updates'); 1050 1051 return array( 1052 phutil_format_relative_time_detailed($smart_wait), 1053 " \xC2\xB7 ", 1054 phutil_tag( 1055 'a', 1056 array( 1057 'href' => $doc_href, 1058 'target' => '_blank', 1059 ), 1060 pht('Learn More')), 1061 ); 1062 } 1063 1064 1065 private function buildMirrorActions( 1066 PhabricatorRepository $repository) { 1067 1068 $viewer = $this->getRequest()->getUser(); 1069 1070 $mirror_actions = id(new PhabricatorActionListView()) 1071 ->setObjectURI($this->getRequest()->getRequestURI()) 1072 ->setUser($viewer); 1073 1074 $new_mirror_uri = $this->getRepositoryControllerURI( 1075 $repository, 1076 'mirror/edit/'); 1077 1078 $mirror_actions->addAction( 1079 id(new PhabricatorActionView()) 1080 ->setName(pht('Add Mirror')) 1081 ->setIcon('fa-plus') 1082 ->setHref($new_mirror_uri) 1083 ->setWorkflow(true)); 1084 1085 return $mirror_actions; 1086 } 1087 1088 private function buildMirrorProperties( 1089 PhabricatorRepository $repository, 1090 PhabricatorActionListView $actions) { 1091 1092 $viewer = $this->getRequest()->getUser(); 1093 1094 $mirror_properties = id(new PHUIPropertyListView()) 1095 ->setUser($viewer) 1096 ->setActionList($actions); 1097 1098 $mirror_properties->addProperty( 1099 '', 1100 phutil_tag( 1101 'em', 1102 array(), 1103 pht('Automatically push changes into other remotes.'))); 1104 1105 return $mirror_properties; 1106 } 1107 1108 private function buildMirrorList( 1109 PhabricatorRepository $repository, 1110 array $mirrors) { 1111 assert_instances_of($mirrors, 'PhabricatorRepositoryMirror'); 1112 1113 $mirror_list = id(new PHUIObjectItemListView()) 1114 ->setNoDataString(pht('This repository has no configured mirrors.')); 1115 1116 foreach ($mirrors as $mirror) { 1117 $item = id(new PHUIObjectItemView()) 1118 ->setHeader($mirror->getRemoteURI()); 1119 1120 $edit_uri = $this->getRepositoryControllerURI( 1121 $repository, 1122 'mirror/edit/'.$mirror->getID().'/'); 1123 1124 $delete_uri = $this->getRepositoryControllerURI( 1125 $repository, 1126 'mirror/delete/'.$mirror->getID().'/'); 1127 1128 $item->addAction( 1129 id(new PHUIListItemView()) 1130 ->setIcon('fa-pencil') 1131 ->setHref($edit_uri) 1132 ->setWorkflow(true)); 1133 1134 $item->addAction( 1135 id(new PHUIListItemView()) 1136 ->setIcon('fa-times') 1137 ->setHref($delete_uri) 1138 ->setWorkflow(true)); 1139 1140 $mirror_list->addItem($item); 1141 } 1142 1143 return $mirror_list; 1144 } 1145 1146 private function getEnvConfigLink() { 1147 $config_href = '/config/edit/environment.append-paths/'; 1148 return phutil_tag( 1149 'a', 1150 array( 1151 'href' => $config_href, 1152 ), 1153 'environment.append-paths'); 1154 } 1155 1156 }
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 |