@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Swap Repository Edit UI to new code

Summary:
Ref T10748. This needs more extensive testing and is sure to have some rough edges, but seems to basically work so far.

Throwing this up so I can work through it more deliberately and make notes.

Test Plan:
- Ran migration.
- Used `bin/repository list` to list existing repositories.
- Used `bin/repository update <repository>` to update various repositories.
- Updated a migrated, hosted Git repository.
- Updated a migrated, observed Git repository.
- Converted an observed repository into a hosted repository by toggling the I/O mode of the URI.
- Conveted a hosted repository into an observed repository by toggling it back.
- Created and activated a new empty hosted Git repository.
- Created and activated an observed Git repository.
- Updated a mirrored repository.
- Cloned and pushed over HTTP.
- Tried to HTTP push a read-only repository.
- Cloned and pushed over SSH.
- Tried to SSH push a read-only repository.
- Updated several Mercurial repositories.
- Updated several Subversion repositories.
- Created and edited repositories via the API.

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T10748

Differential Revision: https://secure.phabricator.com/D15842

+328 -3897
+82
resources/sql/autopatches/20160503.repo.05.urimigrate.php
··· 1 + <?php 2 + 3 + $table = new PhabricatorRepository(); 4 + $conn_w = $table->establishConnection('w'); 5 + 6 + foreach (new LiskMigrationIterator($table) as $repository) { 7 + $uris = array(); 8 + 9 + $serve_http = $repository->getDetail('serve-over-http'); 10 + $http_io = PhabricatorRepositoryURI::IO_DEFAULT; 11 + $disable_http = false; 12 + switch ($serve_http) { 13 + case 'readwrite': 14 + break; 15 + case 'readonly': 16 + $http_io = PhabricatorRepositoryURI::IO_READ; 17 + break; 18 + case 'off': 19 + default: 20 + $disable_http = true; 21 + break; 22 + } 23 + 24 + $serve_ssh = $repository->getDetail('serve-over-ssh'); 25 + $ssh_io = PhabricatorRepositoryURI::IO_DEFAULT; 26 + $disable_ssh = false; 27 + switch ($serve_ssh) { 28 + case 'readwrite': 29 + break; 30 + case 'readonly': 31 + $ssh_io = PhabricatorRepositoryURI::IO_READ; 32 + break; 33 + case 'off': 34 + default: 35 + $disable_ssh = true; 36 + break; 37 + } 38 + 39 + $uris = $repository->newBuiltinURIs(); 40 + 41 + foreach ($uris as $uri) { 42 + $builtin_protocol = $uri->getBuiltinProtocol(); 43 + if ($builtin_protocol == PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH) { 44 + $uri->setIsDisabled((int)$disable_ssh); 45 + $uri->setIoType($ssh_io); 46 + } else { 47 + $uri->setIsDisabled((int)$disable_http); 48 + $uri->setIoType($http_io); 49 + } 50 + } 51 + 52 + if (!$repository->isHosted()) { 53 + $remote_uri = $repository->getDetail('remote-uri'); 54 + if (strlen($remote_uri)) { 55 + $uris[] = PhabricatorRepositoryURI::initializeNewURI() 56 + ->setRepositoryPHID($repository->getPHID()) 57 + ->attachRepository($repository) 58 + ->setURI($remote_uri) 59 + ->setCredentialPHID($repository->getCredentialPHID()) 60 + ->setIOType(PhabricatorRepositoryURI::IO_OBSERVE); 61 + } 62 + } 63 + 64 + foreach ($uris as $uri) { 65 + $already_exists = id(new PhabricatorRepositoryURI())->loadOneWhere( 66 + 'repositoryPHID = %s AND uri = %s LIMIT 1', 67 + $repository->getPHID(), 68 + $uri->getURI()); 69 + if ($already_exists) { 70 + continue; 71 + } 72 + 73 + $uri->save(); 74 + 75 + echo tsprintf( 76 + "%s\n", 77 + pht( 78 + 'Migrated URI "%s" for repository "%s".', 79 + $uri->getURI(), 80 + $repository->getDisplayName())); 81 + } 82 + }
-22
src/__phutil_library_map__.php
··· 749 749 'DiffusionRepositoryClusterEngine' => 'applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php', 750 750 'DiffusionRepositoryClusterEngineLogInterface' => 'applications/diffusion/protocol/DiffusionRepositoryClusterEngineLogInterface.php', 751 751 'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php', 752 - 'DiffusionRepositoryCreateController' => 'applications/diffusion/controller/DiffusionRepositoryCreateController.php', 753 752 'DiffusionRepositoryDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryDatasource.php', 754 753 'DiffusionRepositoryDefaultController' => 'applications/diffusion/controller/DiffusionRepositoryDefaultController.php', 755 - 'DiffusionRepositoryEditActionsController' => 'applications/diffusion/controller/DiffusionRepositoryEditActionsController.php', 756 754 'DiffusionRepositoryEditActivateController' => 'applications/diffusion/controller/DiffusionRepositoryEditActivateController.php', 757 - 'DiffusionRepositoryEditAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php', 758 - 'DiffusionRepositoryEditBasicController' => 'applications/diffusion/controller/DiffusionRepositoryEditBasicController.php', 759 - 'DiffusionRepositoryEditBranchesController' => 'applications/diffusion/controller/DiffusionRepositoryEditBranchesController.php', 760 755 'DiffusionRepositoryEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositoryEditConduitAPIMethod.php', 761 756 'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php', 762 757 'DiffusionRepositoryEditDangerousController' => 'applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php', 763 758 'DiffusionRepositoryEditDeleteController' => 'applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php', 764 - 'DiffusionRepositoryEditEncodingController' => 'applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php', 765 759 'DiffusionRepositoryEditEngine' => 'applications/diffusion/editor/DiffusionRepositoryEditEngine.php', 766 - 'DiffusionRepositoryEditHostingController' => 'applications/diffusion/controller/DiffusionRepositoryEditHostingController.php', 767 - 'DiffusionRepositoryEditMainController' => 'applications/diffusion/controller/DiffusionRepositoryEditMainController.php', 768 - 'DiffusionRepositoryEditStagingController' => 'applications/diffusion/controller/DiffusionRepositoryEditStagingController.php', 769 - 'DiffusionRepositoryEditStorageController' => 'applications/diffusion/controller/DiffusionRepositoryEditStorageController.php', 770 - 'DiffusionRepositoryEditSubversionController' => 'applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php', 771 760 'DiffusionRepositoryEditUpdateController' => 'applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php', 772 761 'DiffusionRepositoryEditproController' => 'applications/diffusion/controller/DiffusionRepositoryEditproController.php', 773 762 'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php', ··· 4976 4965 'DiffusionRepositoryByIDRemarkupRule' => 'PhabricatorObjectRemarkupRule', 4977 4966 'DiffusionRepositoryClusterEngine' => 'Phobject', 4978 4967 'DiffusionRepositoryController' => 'DiffusionController', 4979 - 'DiffusionRepositoryCreateController' => 'DiffusionRepositoryEditController', 4980 4968 'DiffusionRepositoryDatasource' => 'PhabricatorTypeaheadDatasource', 4981 4969 'DiffusionRepositoryDefaultController' => 'DiffusionController', 4982 - 'DiffusionRepositoryEditActionsController' => 'DiffusionRepositoryEditController', 4983 4970 'DiffusionRepositoryEditActivateController' => 'DiffusionRepositoryEditController', 4984 - 'DiffusionRepositoryEditAutomationController' => 'DiffusionRepositoryEditController', 4985 - 'DiffusionRepositoryEditBasicController' => 'DiffusionRepositoryEditController', 4986 - 'DiffusionRepositoryEditBranchesController' => 'DiffusionRepositoryEditController', 4987 4971 'DiffusionRepositoryEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 4988 4972 'DiffusionRepositoryEditController' => 'DiffusionController', 4989 4973 'DiffusionRepositoryEditDangerousController' => 'DiffusionRepositoryEditController', 4990 4974 'DiffusionRepositoryEditDeleteController' => 'DiffusionRepositoryEditController', 4991 - 'DiffusionRepositoryEditEncodingController' => 'DiffusionRepositoryEditController', 4992 4975 'DiffusionRepositoryEditEngine' => 'PhabricatorEditEngine', 4993 - 'DiffusionRepositoryEditHostingController' => 'DiffusionRepositoryEditController', 4994 - 'DiffusionRepositoryEditMainController' => 'DiffusionRepositoryEditController', 4995 - 'DiffusionRepositoryEditStagingController' => 'DiffusionRepositoryEditController', 4996 - 'DiffusionRepositoryEditStorageController' => 'DiffusionRepositoryEditController', 4997 - 'DiffusionRepositoryEditSubversionController' => 'DiffusionRepositoryEditController', 4998 4976 'DiffusionRepositoryEditUpdateController' => 'DiffusionRepositoryEditController', 4999 4977 'DiffusionRepositoryEditproController' => 'DiffusionRepositoryEditController', 5000 4978 'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel',
+1 -15
src/applications/diffusion/application/PhabricatorDiffusionApplication.php
··· 57 57 '/diffusion/' => array( 58 58 $this->getQueryRoutePattern() 59 59 => 'DiffusionRepositoryListController', 60 - $this->getEditRoutePattern('editpro/') => 60 + $this->getEditRoutePattern('edit/') => 61 61 'DiffusionRepositoryEditproController', 62 62 'new/' => 'DiffusionRepositoryNewController', 63 63 '(?P<edit>create)/' => 'DiffusionRepositoryCreateController', ··· 101 101 => 'DiffusionRepositoryURICredentialController', 102 102 ), 103 103 'edit/' => array( 104 - '' => 'DiffusionRepositoryEditMainController', 105 - 'basic/' => 'DiffusionRepositoryEditBasicController', 106 - 'encoding/' => 'DiffusionRepositoryEditEncodingController', 107 104 'activate/' => 'DiffusionRepositoryEditActivateController', 108 105 'dangerous/' => 'DiffusionRepositoryEditDangerousController', 109 - 'branches/' => 'DiffusionRepositoryEditBranchesController', 110 - 'subversion/' => 'DiffusionRepositoryEditSubversionController', 111 - 'actions/' => 'DiffusionRepositoryEditActionsController', 112 - '(?P<edit>remote)/' => 'DiffusionRepositoryCreateController', 113 - '(?P<edit>policy)/' => 'DiffusionRepositoryCreateController', 114 - 'storage/' => 'DiffusionRepositoryEditStorageController', 115 106 'delete/' => 'DiffusionRepositoryEditDeleteController', 116 - 'hosting/' => 'DiffusionRepositoryEditHostingController', 117 - '(?P<serve>serve)/' => 'DiffusionRepositoryEditHostingController', 118 107 'update/' => 'DiffusionRepositoryEditUpdateController', 119 - 'symbol/' => 'DiffusionRepositorySymbolsController', 120 - 'staging/' => 'DiffusionRepositoryEditStagingController', 121 - 'automation/' => 'DiffusionRepositoryEditAutomationController', 122 108 'testautomation/' => 'DiffusionRepositoryTestAutomationController', 123 109 ), 124 110 'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
+25 -117
src/applications/diffusion/controller/DiffusionRepositoryController.php
··· 248 248 private function buildCurtain(PhabricatorRepository $repository) { 249 249 $viewer = $this->getViewer(); 250 250 251 - $edit_uri = $repository->getPathURI('edit/'); 251 + $edit_uri = $repository->getPathURI('manage/'); 252 252 $curtain = $this->newCurtainView($repository); 253 253 254 - $can_edit = PhabricatorPolicyFilter::hasCapability( 255 - $viewer, 256 - $repository, 257 - PhabricatorPolicyCapability::CAN_EDIT); 258 - 259 254 $curtain->addAction( 260 255 id(new PhabricatorActionView()) 261 - ->setName(pht('Edit Repository')) 262 - ->setIcon('fa-pencil') 263 - ->setHref($edit_uri) 264 - ->setWorkflow(!$can_edit) 265 - ->setDisabled(!$can_edit)); 256 + ->setName(pht('Manage Repository')) 257 + ->setIcon('fa-cogs') 258 + ->setHref($edit_uri)); 266 259 267 260 if ($repository->isHosted()) { 268 261 $push_uri = $this->getApplicationURI( ··· 301 294 $view = id(new PHUIPropertyListView()) 302 295 ->setUser($viewer); 303 296 304 - if ($repository->isHosted()) { 305 - $ssh_uri = $repository->getSSHCloneURIObject(); 306 - if ($ssh_uri) { 307 - $clone_uri = $this->renderCloneCommand( 308 - $repository, 309 - $ssh_uri, 310 - $repository->getServeOverSSH(), 311 - '/settings/panel/ssh/'); 297 + $display_never = PhabricatorRepositoryURI::DISPLAY_NEVER; 312 298 313 - $view->addProperty( 314 - $repository->isSVN() 315 - ? pht('Checkout (SSH)') 316 - : pht('Clone (SSH)'), 317 - $clone_uri); 299 + $uris = $repository->getURIs(); 300 + foreach ($uris as $uri) { 301 + if ($uri->getIsDisabled()) { 302 + continue; 318 303 } 319 304 320 - $http_uri = $repository->getHTTPCloneURIObject(); 321 - if ($http_uri) { 322 - $clone_uri = $this->renderCloneCommand( 323 - $repository, 324 - $http_uri, 325 - $repository->getServeOverHTTP(), 326 - PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth') 327 - ? '/settings/panel/vcspassword/' 328 - : null); 329 - 330 - $view->addProperty( 331 - $repository->isSVN() 332 - ? pht('Checkout (HTTP)') 333 - : pht('Clone (HTTP)'), 334 - $clone_uri); 305 + if ($uri->getEffectiveDisplayType() == $display_never) { 306 + continue; 335 307 } 336 - } else { 337 - switch ($repository->getVersionControlSystem()) { 338 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 339 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 340 - $view->addProperty( 341 - pht('Clone'), 342 - $this->renderCloneCommand( 343 - $repository, 344 - $repository->getPublicCloneURI())); 345 - break; 346 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 347 - $view->addProperty( 348 - pht('Checkout'), 349 - $this->renderCloneCommand( 350 - $repository, 351 - $repository->getPublicCloneURI())); 352 - break; 308 + 309 + if ($repository->isSVN()) { 310 + $label = pht('Checkout'); 311 + } else { 312 + $label = pht('Clone'); 353 313 } 314 + 315 + $view->addProperty( 316 + $label, 317 + $this->renderCloneURI($repository, $uri)); 354 318 } 355 319 356 320 $box = id(new PHUIObjectBoxView()) ··· 701 665 ); 702 666 } 703 667 704 - private function renderCloneCommand( 668 + private function renderCloneURI( 705 669 PhabricatorRepository $repository, 706 - $uri, 707 - $serve_mode = null, 708 - $manage_uri = null) { 670 + PhabricatorRepositoryURI $uri) { 709 671 710 672 require_celerity_resource('diffusion-icons-css'); 711 673 712 - Javelin::initBehavior('select-on-click'); 713 - 714 - switch ($repository->getVersionControlSystem()) { 715 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 716 - $command = csprintf( 717 - 'git clone %R', 718 - $uri); 719 - break; 720 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 721 - $command = csprintf( 722 - 'hg clone %R', 723 - $uri); 724 - break; 725 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 726 - if ($repository->isHosted()) { 727 - $command = csprintf( 728 - 'svn checkout %R %R', 729 - $uri, 730 - $repository->getCloneName()); 731 - } else { 732 - $command = csprintf( 733 - 'svn checkout %R', 734 - $uri); 735 - } 736 - break; 737 - } 674 + $display = (string)csprintf('%R', (string)$uri->getDisplayURI()); 738 675 739 676 $input = javelin_tag( 740 677 'input', 741 678 array( 742 679 'type' => 'text', 743 - 'value' => (string)$command, 680 + 'value' => $display, 744 681 'class' => 'diffusion-clone-uri', 745 - 'sigil' => 'select-on-click', 746 682 'readonly' => 'true', 747 683 )); 748 684 749 - $extras = array(); 750 - if ($serve_mode) { 751 - if ($serve_mode === PhabricatorRepository::SERVE_READONLY) { 752 - $extras[] = pht('(Read Only)'); 753 - } 754 - } 755 - 756 - if ($manage_uri) { 757 - if ($this->getRequest()->getUser()->isLoggedIn()) { 758 - $extras[] = phutil_tag( 759 - 'a', 760 - array( 761 - 'href' => $manage_uri, 762 - ), 763 - pht('Manage Credentials')); 764 - } 765 - } 766 - 767 - if ($extras) { 768 - $extras = phutil_implode_html(' ', $extras); 769 - $extras = phutil_tag( 770 - 'div', 771 - array( 772 - 'class' => 'diffusion-clone-extras', 773 - ), 774 - $extras); 775 - } 776 - 777 - return array($input, $extras); 685 + return $input; 778 686 } 779 687 780 688 }
-849
src/applications/diffusion/controller/DiffusionRepositoryCreateController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryCreateController 4 - extends DiffusionRepositoryEditController { 5 - 6 - private $edit; 7 - private $repository; 8 - 9 - public function handleRequest(AphrontRequest $request) { 10 - $viewer = $request->getUser(); 11 - $this->edit = $request->getURIData('edit'); 12 - 13 - // NOTE: We can end up here via either "Create Repository", or via 14 - // "Import Repository", or via "Edit Remote", or via "Edit Policies". In 15 - // the latter two cases, we show only a few of the pages. 16 - 17 - $repository = null; 18 - $service = null; 19 - switch ($this->edit) { 20 - case 'remote': 21 - case 'policy': 22 - $response = $this->loadDiffusionContextForEdit(); 23 - if ($response) { 24 - return $response; 25 - } 26 - 27 - $repository = $this->getDiffusionRequest()->getRepository(); 28 - 29 - // Make sure we have CAN_EDIT. 30 - PhabricatorPolicyFilter::requireCapability( 31 - $viewer, 32 - $repository, 33 - PhabricatorPolicyCapability::CAN_EDIT); 34 - 35 - $this->setRepository($repository); 36 - 37 - $cancel_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 38 - break; 39 - case 'import': 40 - case 'create': 41 - $this->requireApplicationCapability( 42 - DiffusionCreateRepositoriesCapability::CAPABILITY); 43 - 44 - // Pick a random open service to allocate this repository on, if any 45 - // exist. If there are no services, we aren't in cluster mode and 46 - // will allocate locally. If there are services but none permit 47 - // allocations, we fail. 48 - $services = id(new AlmanacServiceQuery()) 49 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 50 - ->withServiceTypes( 51 - array( 52 - AlmanacClusterRepositoryServiceType::SERVICETYPE, 53 - )) 54 - ->needProperties(true) 55 - ->execute(); 56 - if ($services) { 57 - // Filter out services which do not permit new allocations. 58 - foreach ($services as $key => $possible_service) { 59 - if ($possible_service->getAlmanacPropertyValue('closed')) { 60 - unset($services[$key]); 61 - } 62 - } 63 - 64 - if (!$services) { 65 - throw new Exception( 66 - pht( 67 - 'This install is configured in cluster mode, but all '. 68 - 'available repository cluster services are closed to new '. 69 - 'allocations. At least one service must be open to allow '. 70 - 'new allocations to take place.')); 71 - } 72 - 73 - shuffle($services); 74 - $service = head($services); 75 - } 76 - 77 - $cancel_uri = $this->getApplicationURI('new/'); 78 - break; 79 - default: 80 - throw new Exception(pht('Invalid edit operation!')); 81 - } 82 - 83 - $form = id(new PHUIPagedFormView()) 84 - ->setUser($viewer) 85 - ->setCancelURI($cancel_uri); 86 - 87 - switch ($this->edit) { 88 - case 'remote': 89 - $title = pht('Edit Remote'); 90 - $form 91 - ->addPage('remote-uri', $this->buildRemoteURIPage()) 92 - ->addPage('auth', $this->buildAuthPage()); 93 - break; 94 - case 'policy': 95 - $title = pht('Edit Policies'); 96 - $form 97 - ->addPage('policy', $this->buildPolicyPage()); 98 - break; 99 - case 'create': 100 - $title = pht('Create Repository'); 101 - $form 102 - ->addPage('vcs', $this->buildVCSPage()) 103 - ->addPage('name', $this->buildNamePage()) 104 - ->addPage('policy', $this->buildPolicyPage()) 105 - ->addPage('done', $this->buildDonePage()); 106 - break; 107 - case 'import': 108 - $title = pht('Import Repository'); 109 - $form 110 - ->addPage('vcs', $this->buildVCSPage()) 111 - ->addPage('name', $this->buildNamePage()) 112 - ->addPage('remote-uri', $this->buildRemoteURIPage()) 113 - ->addPage('auth', $this->buildAuthPage()) 114 - ->addPage('policy', $this->buildPolicyPage()) 115 - ->addPage('done', $this->buildDonePage()); 116 - break; 117 - } 118 - 119 - if ($request->isFormPost()) { 120 - $form->readFromRequest($request); 121 - if ($form->isComplete()) { 122 - 123 - $is_create = ($this->edit === 'import' || $this->edit === 'create'); 124 - $is_auth = ($this->edit == 'import' || $this->edit == 'remote'); 125 - $is_policy = ($this->edit != 'remote'); 126 - $is_init = ($this->edit == 'create'); 127 - 128 - if ($is_create) { 129 - $repository = PhabricatorRepository::initializeNewRepository( 130 - $viewer); 131 - } 132 - 133 - $template = id(new PhabricatorRepositoryTransaction()); 134 - 135 - $type_name = PhabricatorRepositoryTransaction::TYPE_NAME; 136 - $type_vcs = PhabricatorRepositoryTransaction::TYPE_VCS; 137 - $type_activate = PhabricatorRepositoryTransaction::TYPE_ACTIVATE; 138 - $type_remote_uri = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI; 139 - $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING; 140 - $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; 141 - $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; 142 - $type_credential = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL; 143 - $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; 144 - $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; 145 - $type_space = PhabricatorTransactions::TYPE_SPACE; 146 - $type_push = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; 147 - $type_service = PhabricatorRepositoryTransaction::TYPE_SERVICE; 148 - 149 - $xactions = array(); 150 - 151 - // If we're creating a new repository, set all this core stuff. 152 - if ($is_create) { 153 - $xactions[] = id(clone $template) 154 - ->setTransactionType($type_name) 155 - ->setNewValue( 156 - $form->getPage('name')->getControl('name')->getValue()); 157 - 158 - $xactions[] = id(clone $template) 159 - ->setTransactionType($type_vcs) 160 - ->setNewValue( 161 - $form->getPage('vcs')->getControl('vcs')->getValue()); 162 - 163 - $activate = $form->getPage('done') 164 - ->getControl('activate')->getValue(); 165 - if ($activate == 'start') { 166 - $initial_status = PhabricatorRepository::STATUS_ACTIVE; 167 - } else { 168 - $initial_status = PhabricatorRepository::STATUS_INACTIVE; 169 - } 170 - 171 - $xactions[] = id(clone $template) 172 - ->setTransactionType($type_activate) 173 - ->setNewValue($initial_status); 174 - 175 - if ($service) { 176 - $xactions[] = id(clone $template) 177 - ->setTransactionType($type_service) 178 - ->setNewValue($service->getPHID()); 179 - } 180 - } 181 - 182 - if ($is_init) { 183 - $xactions[] = id(clone $template) 184 - ->setTransactionType($type_hosting) 185 - ->setNewValue(true); 186 - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); 187 - if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) { 188 - if (PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) { 189 - $v_http_mode = PhabricatorRepository::SERVE_READWRITE; 190 - } else { 191 - $v_http_mode = PhabricatorRepository::SERVE_OFF; 192 - } 193 - $xactions[] = id(clone $template) 194 - ->setTransactionType($type_http) 195 - ->setNewValue($v_http_mode); 196 - } 197 - 198 - if (PhabricatorEnv::getEnvConfig('diffusion.ssh-user')) { 199 - $v_ssh_mode = PhabricatorRepository::SERVE_READWRITE; 200 - } else { 201 - $v_ssh_mode = PhabricatorRepository::SERVE_OFF; 202 - } 203 - $xactions[] = id(clone $template) 204 - ->setTransactionType($type_ssh) 205 - ->setNewValue($v_ssh_mode); 206 - } 207 - 208 - if ($is_auth) { 209 - $xactions[] = id(clone $template) 210 - ->setTransactionType($type_remote_uri) 211 - ->setNewValue( 212 - $form->getPage('remote-uri')->getControl('remoteURI') 213 - ->getValue()); 214 - 215 - $xactions[] = id(clone $template) 216 - ->setTransactionType($type_credential) 217 - ->setNewValue( 218 - $form->getPage('auth')->getControl('credential')->getValue()); 219 - } 220 - 221 - if ($is_policy) { 222 - $policy_page = $form->getPage('policy'); 223 - 224 - $xactions[] = id(clone $template) 225 - ->setTransactionType($type_view) 226 - ->setNewValue($policy_page->getControl('viewPolicy')->getValue()); 227 - 228 - $xactions[] = id(clone $template) 229 - ->setTransactionType($type_edit) 230 - ->setNewValue($policy_page->getControl('editPolicy')->getValue()); 231 - 232 - if ($is_init || $repository->isHosted()) { 233 - $xactions[] = id(clone $template) 234 - ->setTransactionType($type_push) 235 - ->setNewValue($policy_page->getControl('pushPolicy')->getValue()); 236 - } 237 - 238 - $xactions[] = id(clone $template) 239 - ->setTransactionType($type_space) 240 - ->setNewValue( 241 - $policy_page->getControl('viewPolicy')->getSpacePHID()); 242 - } 243 - 244 - id(new PhabricatorRepositoryEditor()) 245 - ->setContinueOnNoEffect(true) 246 - ->setContentSourceFromRequest($request) 247 - ->setActor($viewer) 248 - ->applyTransactions($repository, $xactions); 249 - 250 - $repo_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 251 - return id(new AphrontRedirectResponse())->setURI($repo_uri); 252 - } 253 - } else { 254 - $dict = array(); 255 - if ($repository) { 256 - $dict = array( 257 - 'remoteURI' => $repository->getRemoteURI(), 258 - 'credential' => $repository->getCredentialPHID(), 259 - 'viewPolicy' => $repository->getViewPolicy(), 260 - 'editPolicy' => $repository->getEditPolicy(), 261 - 'pushPolicy' => $repository->getPushPolicy(), 262 - 'spacePHID' => $repository->getSpacePHID(), 263 - ); 264 - } 265 - $form->readFromObject($dict); 266 - } 267 - 268 - $crumbs = $this->buildApplicationCrumbs(); 269 - $crumbs->addTextCrumb($title); 270 - 271 - $header = id(new PHUIHeaderView()) 272 - ->setHeader($title) 273 - ->setHeaderIcon('fa-pencil'); 274 - 275 - $form_box = id(new PHUIObjectBoxView()) 276 - ->setHeaderText($title) 277 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 278 - ->setForm($form); 279 - 280 - $view = id(new PHUITwoColumnView()) 281 - ->setHeader($header) 282 - ->setFooter(array( 283 - $form, 284 - )); 285 - 286 - return $this->newPage() 287 - ->setTitle($title) 288 - ->setCrumbs($crumbs) 289 - ->appendChild($view); 290 - 291 - } 292 - 293 - 294 - /* -( Page: VCS Type )----------------------------------------------------- */ 295 - 296 - 297 - private function buildVCSPage() { 298 - 299 - $is_import = ($this->edit == 'import'); 300 - 301 - if ($is_import) { 302 - $git_str = pht( 303 - 'Import a Git repository (for example, a repository hosted '. 304 - 'on GitHub).'); 305 - $hg_str = pht( 306 - 'Import a Mercurial repository (for example, a repository '. 307 - 'hosted on Bitbucket).'); 308 - $svn_str = pht('Import a Subversion repository.'); 309 - } else { 310 - $git_str = pht('Create a new, empty Git repository.'); 311 - $hg_str = pht('Create a new, empty Mercurial repository.'); 312 - $svn_str = pht('Create a new, empty Subversion repository.'); 313 - } 314 - 315 - $control = id(new AphrontFormRadioButtonControl()) 316 - ->setName('vcs') 317 - ->setLabel(pht('Type')) 318 - ->addButton( 319 - PhabricatorRepositoryType::REPOSITORY_TYPE_GIT, 320 - pht('Git'), 321 - $git_str) 322 - ->addButton( 323 - PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL, 324 - pht('Mercurial'), 325 - $hg_str) 326 - ->addButton( 327 - PhabricatorRepositoryType::REPOSITORY_TYPE_SVN, 328 - pht('Subversion'), 329 - $svn_str); 330 - 331 - return id(new PHUIFormPageView()) 332 - ->setPageName(pht('Repository Type')) 333 - ->setUser($this->getRequest()->getUser()) 334 - ->setValidateFormPageCallback(array($this, 'validateVCSPage')) 335 - ->addControl($control); 336 - } 337 - 338 - public function validateVCSPage(PHUIFormPageView $page) { 339 - $valid = array( 340 - PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => true, 341 - PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => true, 342 - PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => true, 343 - ); 344 - 345 - $c_vcs = $page->getControl('vcs'); 346 - $v_vcs = $c_vcs->getValue(); 347 - if (!$v_vcs) { 348 - $c_vcs->setError(pht('Required')); 349 - $page->addPageError( 350 - pht('You must select a version control system.')); 351 - } else if (empty($valid[$v_vcs])) { 352 - $c_vcs->setError(pht('Invalid')); 353 - $page->addPageError( 354 - pht('You must select a valid version control system.')); 355 - } 356 - 357 - return $c_vcs->isValid(); 358 - } 359 - 360 - 361 - /* -( Page: Name )--------------------------------------------------------- */ 362 - 363 - 364 - private function buildNamePage() { 365 - return id(new PHUIFormPageView()) 366 - ->setUser($this->getRequest()->getUser()) 367 - ->setPageName(pht('Repository Name and Location')) 368 - ->setValidateFormPageCallback(array($this, 'validateNamePage')) 369 - ->addRemarkupInstructions( 370 - pht( 371 - '**Choose a human-readable name for this repository**, like '. 372 - '"CompanyName Mobile App" or "CompanyName Backend Server". You '. 373 - 'can change this later.')) 374 - ->addControl( 375 - id(new AphrontFormTextControl()) 376 - ->setName('name') 377 - ->setLabel(pht('Name'))); 378 - } 379 - 380 - public function validateNamePage(PHUIFormPageView $page) { 381 - $c_name = $page->getControl('name'); 382 - $v_name = $c_name->getValue(); 383 - if (!strlen($v_name)) { 384 - $c_name->setError(pht('Required')); 385 - $page->addPageError( 386 - pht('You must choose a name for this repository.')); 387 - } 388 - 389 - return $c_name->isValid(); 390 - } 391 - 392 - 393 - /* -( Page: Remote URI )--------------------------------------------------- */ 394 - 395 - 396 - private function buildRemoteURIPage() { 397 - return id(new PHUIFormPageView()) 398 - ->setUser($this->getRequest()->getUser()) 399 - ->setPageName(pht('Repository Remote URI')) 400 - ->setValidateFormPageCallback(array($this, 'validateRemoteURIPage')) 401 - ->setAdjustFormPageCallback(array($this, 'adjustRemoteURIPage')) 402 - ->addControl( 403 - id(new AphrontFormTextControl()) 404 - ->setName('remoteURI')); 405 - } 406 - 407 - public function adjustRemoteURIPage(PHUIFormPageView $page) { 408 - $form = $page->getForm(); 409 - 410 - $is_git = false; 411 - $is_svn = false; 412 - $is_mercurial = false; 413 - 414 - if ($this->getRepository()) { 415 - $vcs = $this->getRepository()->getVersionControlSystem(); 416 - } else { 417 - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); 418 - } 419 - 420 - switch ($vcs) { 421 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 422 - $is_git = true; 423 - break; 424 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 425 - $is_svn = true; 426 - break; 427 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 428 - $is_mercurial = true; 429 - break; 430 - default: 431 - throw new Exception(pht('Unsupported VCS!')); 432 - } 433 - 434 - $has_local = ($is_git || $is_mercurial); 435 - if ($is_git) { 436 - $uri_label = pht('Remote URI'); 437 - $instructions = pht( 438 - 'Enter the URI to clone this Git repository from. It should usually '. 439 - 'look like one of these examples:'. 440 - "\n\n". 441 - "| Example Git Remote URIs |\n". 442 - "| ----------------------- |\n". 443 - "| `git@github.com:example/example.git` |\n". 444 - "| `ssh://user@host.com/git/example.git` |\n". 445 - "| `https://example.com/repository.git` |\n"); 446 - } else if ($is_mercurial) { 447 - $uri_label = pht('Remote URI'); 448 - $instructions = pht( 449 - 'Enter the URI to clone this Mercurial repository from. It should '. 450 - 'usually look like one of these examples:'. 451 - "\n\n". 452 - "| Example Mercurial Remote URIs |\n". 453 - "| ----------------------- |\n". 454 - "| `ssh://hg@bitbucket.org/example/repository` |\n". 455 - "| `https://bitbucket.org/example/repository` |\n"); 456 - } else if ($is_svn) { 457 - $uri_label = pht('Repository Root'); 458 - $instructions = pht( 459 - 'Enter the **Repository Root** for this Subversion repository. '. 460 - 'You can figure this out by running `svn info` in a working copy '. 461 - 'and looking at the value in the `Repository Root` field. It '. 462 - 'should be a URI and will usually look like these:'. 463 - "\n\n". 464 - "| Example Subversion Repository Root URIs |\n". 465 - "| ------------------------------ |\n". 466 - "| `http://svn.example.org/svnroot/` |\n". 467 - "| `svn+ssh://svn.example.com/svnroot/` |\n". 468 - "| `svn://svn.example.net/svnroot/` |\n". 469 - "\n\n". 470 - "You **MUST** specify the root of the repository, not a ". 471 - "subdirectory. (If you want to import only part of a Subversion ". 472 - "repository, use the //Import Only// option at the end of this ". 473 - "workflow.)"); 474 - } else { 475 - throw new Exception(pht('Unsupported VCS!')); 476 - } 477 - 478 - $page->addRemarkupInstructions($instructions, 'remoteURI'); 479 - $page->getControl('remoteURI')->setLabel($uri_label); 480 - } 481 - 482 - public function validateRemoteURIPage(PHUIFormPageView $page) { 483 - $c_remote = $page->getControl('remoteURI'); 484 - $v_remote = $c_remote->getValue(); 485 - 486 - if (!strlen($v_remote)) { 487 - $c_remote->setError(pht('Required')); 488 - $page->addPageError( 489 - pht('You must specify a URI.')); 490 - } else { 491 - try { 492 - PhabricatorRepository::assertValidRemoteURI($v_remote); 493 - } catch (Exception $ex) { 494 - $c_remote->setError(pht('Invalid')); 495 - $page->addPageError($ex->getMessage()); 496 - } 497 - } 498 - 499 - return $c_remote->isValid(); 500 - } 501 - 502 - 503 - /* -( Page: Authentication )----------------------------------------------- */ 504 - 505 - 506 - public function buildAuthPage() { 507 - return id(new PHUIFormPageView()) 508 - ->setPageName(pht('Authentication')) 509 - ->setUser($this->getRequest()->getUser()) 510 - ->setAdjustFormPageCallback(array($this, 'adjustAuthPage')) 511 - ->addControl( 512 - id(new PassphraseCredentialControl()) 513 - ->setViewer($this->getViewer()) 514 - ->setName('credential')); 515 - } 516 - 517 - 518 - public function adjustAuthPage($page) { 519 - $form = $page->getForm(); 520 - 521 - if ($this->getRepository()) { 522 - $vcs = $this->getRepository()->getVersionControlSystem(); 523 - } else { 524 - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); 525 - } 526 - 527 - $remote_uri = $form->getPage('remote-uri') 528 - ->getControl('remoteURI') 529 - ->getValue(); 530 - 531 - $proto = PhabricatorRepository::getRemoteURIProtocol($remote_uri); 532 - $remote_user = $this->getRemoteURIUser($remote_uri); 533 - 534 - $c_credential = $page->getControl('credential'); 535 - $c_credential->setDefaultUsername($remote_user); 536 - 537 - if ($this->isSSHProtocol($proto)) { 538 - $c_credential->setLabel(pht('SSH Key')); 539 - $c_credential->setCredentialType( 540 - PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE); 541 - $provides_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; 542 - 543 - $page->addRemarkupInstructions( 544 - pht( 545 - 'Choose or add the SSH credentials to use to connect to the '. 546 - 'repository hosted at:'. 547 - "\n\n". 548 - " lang=text\n". 549 - " %s", 550 - $remote_uri), 551 - 'credential'); 552 - } else if ($this->isUsernamePasswordProtocol($proto)) { 553 - $c_credential->setLabel(pht('Password')); 554 - $c_credential->setAllowNull(true); 555 - $c_credential->setCredentialType( 556 - PassphrasePasswordCredentialType::CREDENTIAL_TYPE); 557 - $provides_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; 558 - 559 - $page->addRemarkupInstructions( 560 - pht( 561 - 'Choose the username and password used to connect to the '. 562 - 'repository hosted at:'. 563 - "\n\n". 564 - " lang=text\n". 565 - " %s". 566 - "\n\n". 567 - "If this repository does not require a username or password, ". 568 - "you can continue to the next step.", 569 - $remote_uri), 570 - 'credential'); 571 - } else { 572 - throw new Exception(pht('Unknown URI protocol!')); 573 - } 574 - 575 - if ($provides_type) { 576 - $viewer = $this->getRequest()->getUser(); 577 - 578 - $options = id(new PassphraseCredentialQuery()) 579 - ->setViewer($viewer) 580 - ->withIsDestroyed(false) 581 - ->withProvidesTypes(array($provides_type)) 582 - ->execute(); 583 - 584 - $c_credential->setOptions($options); 585 - } 586 - 587 - } 588 - 589 - public function validateAuthPage(PHUIFormPageView $page) { 590 - $form = $page->getForm(); 591 - $remote_uri = $form->getPage('remote')->getControl('remoteURI')->getValue(); 592 - $proto = $this->getRemoteURIProtocol($remote_uri); 593 - 594 - $c_credential = $page->getControl('credential'); 595 - $v_credential = $c_credential->getValue(); 596 - 597 - // NOTE: We're using the omnipotent user here because the viewer might be 598 - // editing a repository they're allowed to edit which uses a credential they 599 - // are not allowed to see. This is fine, as long as they don't change it. 600 - $credential = id(new PassphraseCredentialQuery()) 601 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 602 - ->withPHIDs(array($v_credential)) 603 - ->executeOne(); 604 - 605 - if ($this->isSSHProtocol($proto)) { 606 - if (!$credential) { 607 - $c_credential->setError(pht('Required')); 608 - $page->addPageError( 609 - pht('You must choose an SSH credential to connect over SSH.')); 610 - } 611 - 612 - $ssh_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; 613 - if ($credential->getProvidesType() !== $ssh_type) { 614 - $c_credential->setError(pht('Invalid')); 615 - $page->addPageError( 616 - pht( 617 - 'You must choose an SSH credential, not some other type '. 618 - 'of credential.')); 619 - } 620 - 621 - } else if ($this->isUsernamePasswordProtocol($proto)) { 622 - if ($credential) { 623 - $password_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; 624 - if ($credential->getProvidesType() !== $password_type) { 625 - $c_credential->setError(pht('Invalid')); 626 - $page->addPageError( 627 - pht( 628 - 'You must choose a username/password credential, not some other '. 629 - 'type of credential.')); 630 - } 631 - } 632 - 633 - return $c_credential->isValid(); 634 - } else { 635 - return true; 636 - } 637 - } 638 - 639 - 640 - /* -( Page: Policy )------------------------------------------------------- */ 641 - 642 - 643 - private function buildPolicyPage() { 644 - $viewer = $this->getRequest()->getUser(); 645 - if ($this->getRepository()) { 646 - $repository = $this->getRepository(); 647 - } else { 648 - $repository = PhabricatorRepository::initializeNewRepository($viewer); 649 - } 650 - 651 - $policies = id(new PhabricatorPolicyQuery()) 652 - ->setViewer($viewer) 653 - ->setObject($repository) 654 - ->execute(); 655 - 656 - $view_policy = id(new AphrontFormPolicyControl()) 657 - ->setUser($viewer) 658 - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) 659 - ->setPolicyObject($repository) 660 - ->setPolicies($policies) 661 - ->setName('viewPolicy'); 662 - 663 - $edit_policy = id(new AphrontFormPolicyControl()) 664 - ->setUser($viewer) 665 - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 666 - ->setPolicyObject($repository) 667 - ->setPolicies($policies) 668 - ->setName('editPolicy'); 669 - 670 - $push_policy = id(new AphrontFormPolicyControl()) 671 - ->setUser($viewer) 672 - ->setCapability(DiffusionPushCapability::CAPABILITY) 673 - ->setPolicyObject($repository) 674 - ->setPolicies($policies) 675 - ->setName('pushPolicy'); 676 - 677 - return id(new PHUIFormPageView()) 678 - ->setPageName(pht('Policies')) 679 - ->setValidateFormPageCallback(array($this, 'validatePolicyPage')) 680 - ->setAdjustFormPageCallback(array($this, 'adjustPolicyPage')) 681 - ->setUser($viewer) 682 - ->addRemarkupInstructions( 683 - pht('Select access policies for this repository.')) 684 - ->addControl($view_policy) 685 - ->addControl($edit_policy) 686 - ->addControl($push_policy); 687 - } 688 - 689 - public function adjustPolicyPage(PHUIFormPageView $page) { 690 - if ($this->getRepository()) { 691 - $repository = $this->getRepository(); 692 - $show_push = $repository->isHosted(); 693 - } else { 694 - $show_push = ($this->edit == 'create'); 695 - } 696 - 697 - if (!$show_push) { 698 - $c_push = $page->getControl('pushPolicy'); 699 - $c_push->setHidden(true); 700 - } 701 - } 702 - 703 - public function validatePolicyPage(PHUIFormPageView $page) { 704 - $form = $page->getForm(); 705 - $viewer = $this->getRequest()->getUser(); 706 - 707 - $c_view = $page->getControl('viewPolicy'); 708 - $c_edit = $page->getControl('editPolicy'); 709 - $c_push = $page->getControl('pushPolicy'); 710 - $v_view = $c_view->getValue(); 711 - $v_edit = $c_edit->getValue(); 712 - $v_push = $c_push->getValue(); 713 - 714 - if ($this->getRepository()) { 715 - $repository = $this->getRepository(); 716 - } else { 717 - $repository = PhabricatorRepository::initializeNewRepository($viewer); 718 - } 719 - 720 - $proxy = clone $repository; 721 - $proxy->setViewPolicy($v_view); 722 - $proxy->setEditPolicy($v_edit); 723 - 724 - $can_view = PhabricatorPolicyFilter::hasCapability( 725 - $viewer, 726 - $proxy, 727 - PhabricatorPolicyCapability::CAN_VIEW); 728 - 729 - $can_edit = PhabricatorPolicyFilter::hasCapability( 730 - $viewer, 731 - $proxy, 732 - PhabricatorPolicyCapability::CAN_EDIT); 733 - 734 - if (!$can_view) { 735 - $c_view->setError(pht('Invalid')); 736 - $page->addPageError( 737 - pht( 738 - 'You can not use the selected policy, because you would be unable '. 739 - 'to see the repository.')); 740 - } 741 - 742 - if (!$can_edit) { 743 - $c_edit->setError(pht('Invalid')); 744 - $page->addPageError( 745 - pht( 746 - 'You can not use the selected edit policy, because you would be '. 747 - 'unable to edit the repository.')); 748 - } 749 - 750 - return $c_view->isValid() && 751 - $c_edit->isValid(); 752 - } 753 - 754 - /* -( Page: Done )--------------------------------------------------------- */ 755 - 756 - 757 - private function buildDonePage() { 758 - 759 - $is_create = ($this->edit == 'create'); 760 - if ($is_create) { 761 - $now_label = pht('Create Repository Now'); 762 - $now_caption = pht( 763 - 'Create the repository right away. This will create the repository '. 764 - 'using default settings.'); 765 - 766 - $wait_label = pht('Configure More Options First'); 767 - $wait_caption = pht( 768 - 'Configure more options before creating the repository. '. 769 - 'This will let you fine-tune settings. You can create the repository '. 770 - 'whenever you are ready.'); 771 - } else { 772 - $now_label = pht('Start Import Now'); 773 - $now_caption = pht( 774 - 'Start importing the repository right away. This will import '. 775 - 'the entire repository using default settings.'); 776 - 777 - $wait_label = pht('Configure More Options First'); 778 - $wait_caption = pht( 779 - 'Configure more options before beginning the repository '. 780 - 'import. This will let you fine-tune settings. You can '. 781 - 'start the import whenever you are ready.'); 782 - } 783 - 784 - return id(new PHUIFormPageView()) 785 - ->setPageName(pht('Repository Ready!')) 786 - ->setValidateFormPageCallback(array($this, 'validateDonePage')) 787 - ->setUser($this->getRequest()->getUser()) 788 - ->addControl( 789 - id(new AphrontFormRadioButtonControl()) 790 - ->setName('activate') 791 - ->setLabel(pht('Start Now')) 792 - ->addButton( 793 - 'start', 794 - $now_label, 795 - $now_caption) 796 - ->addButton( 797 - 'wait', 798 - $wait_label, 799 - $wait_caption)); 800 - } 801 - 802 - public function validateDonePage(PHUIFormPageView $page) { 803 - $c_activate = $page->getControl('activate'); 804 - $v_activate = $c_activate->getValue(); 805 - 806 - if ($v_activate != 'start' && $v_activate != 'wait') { 807 - $c_activate->setError(pht('Required')); 808 - $page->addPageError( 809 - pht('Make a choice about repository activation.')); 810 - } 811 - 812 - return $c_activate->isValid(); 813 - } 814 - 815 - 816 - /* -( Internal )----------------------------------------------------------- */ 817 - 818 - private function getRemoteURIUser($raw_uri) { 819 - $uri = new PhutilURI($raw_uri); 820 - if ($uri->getUser()) { 821 - return $uri->getUser(); 822 - } 823 - 824 - $git_uri = new PhutilGitURI($raw_uri); 825 - if (strlen($git_uri->getDomain()) && strlen($git_uri->getPath())) { 826 - return $git_uri->getUser(); 827 - } 828 - 829 - return null; 830 - } 831 - 832 - private function isSSHProtocol($proto) { 833 - return ($proto == 'git' || $proto == 'ssh' || $proto == 'svn+ssh'); 834 - } 835 - 836 - private function isUsernamePasswordProtocol($proto) { 837 - return ($proto == 'http' || $proto == 'https' || $proto == 'svn'); 838 - } 839 - 840 - private function setRepository(PhabricatorRepository $repository) { 841 - $this->repository = $repository; 842 - return $this; 843 - } 844 - 845 - private function getRepository() { 846 - return $this->repository; 847 - } 848 - 849 - }
-121
src/applications/diffusion/controller/DiffusionRepositoryEditActionsController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditActionsController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 17 - 18 - // NOTE: We're inverting these here, because the storage is silly. 19 - $v_notify = !$repository->getHumanReadableDetail('herald-disabled'); 20 - $v_autoclose = !$repository->getHumanReadableDetail('disable-autoclose'); 21 - 22 - if ($request->isFormPost()) { 23 - $v_notify = $request->getBool('notify'); 24 - $v_autoclose = $request->getBool('autoclose'); 25 - 26 - $xactions = array(); 27 - $template = id(new PhabricatorRepositoryTransaction()); 28 - 29 - $type_notify = PhabricatorRepositoryTransaction::TYPE_NOTIFY; 30 - $type_autoclose = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE; 31 - 32 - $xactions[] = id(clone $template) 33 - ->setTransactionType($type_notify) 34 - ->setNewValue($v_notify); 35 - 36 - $xactions[] = id(clone $template) 37 - ->setTransactionType($type_autoclose) 38 - ->setNewValue($v_autoclose); 39 - 40 - id(new PhabricatorRepositoryEditor()) 41 - ->setContinueOnNoEffect(true) 42 - ->setContentSourceFromRequest($request) 43 - ->setActor($viewer) 44 - ->applyTransactions($repository, $xactions); 45 - 46 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 47 - } 48 - 49 - $content = array(); 50 - 51 - $crumbs = $this->buildApplicationCrumbs(); 52 - $crumbs->addTextCrumb(pht('Edit Actions')); 53 - 54 - $title = pht('Edit Actions (%s)', $repository->getName()); 55 - 56 - $header = id(new PHUIHeaderView()) 57 - ->setHeader($title) 58 - ->setHeaderIcon('fa-pencil'); 59 - 60 - $policies = id(new PhabricatorPolicyQuery()) 61 - ->setViewer($viewer) 62 - ->setObject($repository) 63 - ->execute(); 64 - 65 - $form = id(new AphrontFormView()) 66 - ->setUser($viewer) 67 - ->appendRemarkupInstructions( 68 - pht( 69 - "Normally, Phabricator publishes notifications when it discovers ". 70 - "new commits. You can disable publishing for this repository by ". 71 - "turning off **Notify/Publish**. This will disable notifications, ". 72 - "feed, and Herald (including audits and build plans) for this ". 73 - "repository.\n\n". 74 - "When Phabricator discovers a new commit, it can automatically ". 75 - "close associated revisions and tasks. If you don't want ". 76 - "Phabricator to close objects when it discovers new commits in ". 77 - "this repository, you can disable **Autoclose**.")) 78 - ->appendChild( 79 - id(new AphrontFormSelectControl()) 80 - ->setName('notify') 81 - ->setLabel(pht('Notify/Publish')) 82 - ->setValue((int)$v_notify) 83 - ->setOptions( 84 - array( 85 - 1 => pht('Enable Notifications, Feed and Herald'), 86 - 0 => pht('Disable Notifications, Feed and Herald'), 87 - ))) 88 - ->appendChild( 89 - id(new AphrontFormSelectControl()) 90 - ->setName('autoclose') 91 - ->setLabel(pht('Autoclose')) 92 - ->setValue((int)$v_autoclose) 93 - ->setOptions( 94 - array( 95 - 1 => pht('Enable Autoclose'), 96 - 0 => pht('Disable Autoclose'), 97 - ))) 98 - ->appendChild( 99 - id(new AphrontFormSubmitControl()) 100 - ->setValue(pht('Save Actions')) 101 - ->addCancelButton($edit_uri)); 102 - 103 - $form_box = id(new PHUIObjectBoxView()) 104 - ->setHeaderText(pht('Actions')) 105 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 106 - ->setForm($form); 107 - 108 - $view = id(new PHUITwoColumnView()) 109 - ->setHeader($header) 110 - ->setFooter(array( 111 - $form_box, 112 - )); 113 - 114 - return $this->newPage() 115 - ->setTitle($title) 116 - ->setCrumbs($crumbs) 117 - ->appendChild($view); 118 - 119 - } 120 - 121 - }
-93
src/applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditAutomationController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - if (!$repository->supportsAutomation()) { 17 - return new Aphront404Response(); 18 - } 19 - 20 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 21 - 22 - $v_blueprints = $repository->getHumanReadableDetail( 23 - 'automation.blueprintPHIDs'); 24 - 25 - if ($request->isFormPost()) { 26 - $v_blueprints = $request->getArr('blueprintPHIDs'); 27 - 28 - $xactions = array(); 29 - $template = id(new PhabricatorRepositoryTransaction()); 30 - 31 - $type_blueprints = 32 - PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS; 33 - 34 - $xactions[] = id(clone $template) 35 - ->setTransactionType($type_blueprints) 36 - ->setNewValue($v_blueprints); 37 - 38 - id(new PhabricatorRepositoryEditor()) 39 - ->setContinueOnNoEffect(true) 40 - ->setContentSourceFromRequest($request) 41 - ->setActor($viewer) 42 - ->applyTransactions($repository, $xactions); 43 - 44 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 45 - } 46 - 47 - $crumbs = $this->buildApplicationCrumbs(); 48 - $crumbs->addTextCrumb(pht('Edit Automation')); 49 - 50 - $title = pht('Edit %s', $repository->getName()); 51 - 52 - $header = id(new PHUIHeaderView()) 53 - ->setHeader($title) 54 - ->setHeaderIcon('fa-pencil'); 55 - 56 - $form = id(new AphrontFormView()) 57 - ->setUser($viewer) 58 - ->appendRemarkupInstructions( 59 - pht( 60 - "Configure **Repository Automation** to allow Phabricator to ". 61 - "write to this repository.". 62 - "\n\n". 63 - "IMPORTANT: This feature is new, experimental, and not supported. ". 64 - "Use it at your own risk.")) 65 - ->appendControl( 66 - id(new AphrontFormTokenizerControl()) 67 - ->setLabel(pht('Use Blueprints')) 68 - ->setName('blueprintPHIDs') 69 - ->setValue($v_blueprints) 70 - ->setDatasource(new DrydockBlueprintDatasource())) 71 - ->appendChild( 72 - id(new AphrontFormSubmitControl()) 73 - ->setValue(pht('Save')) 74 - ->addCancelButton($edit_uri)); 75 - 76 - $form_box = id(new PHUIObjectBoxView()) 77 - ->setHeaderText(pht('Automation')) 78 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 79 - ->setForm($form); 80 - 81 - $view = id(new PHUITwoColumnView()) 82 - ->setHeader($header) 83 - ->setFooter(array( 84 - $form_box, 85 - )); 86 - 87 - return $this->newPage() 88 - ->setTitle($title) 89 - ->setCrumbs($crumbs) 90 - ->appendChild($view); 91 - } 92 - 93 - }
-193
src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditBasicController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $request->getUser(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 17 - 18 - $v_name = $repository->getName(); 19 - $v_desc = $repository->getDetail('description'); 20 - $v_slug = $repository->getRepositorySlug(); 21 - $v_callsign = $repository->getCallsign(); 22 - $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( 23 - $repository->getPHID(), 24 - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); 25 - $e_name = true; 26 - $e_slug = null; 27 - $e_callsign = null; 28 - $errors = array(); 29 - 30 - $validation_exception = null; 31 - if ($request->isFormPost()) { 32 - $v_name = $request->getStr('name'); 33 - $v_desc = $request->getStr('description'); 34 - $v_projects = $request->getArr('projectPHIDs'); 35 - $v_slug = $request->getStr('slug'); 36 - $v_callsign = $request->getStr('callsign'); 37 - 38 - if (!strlen($v_name)) { 39 - $e_name = pht('Required'); 40 - $errors[] = pht('Repository name is required.'); 41 - } else { 42 - $e_name = null; 43 - } 44 - 45 - if (!$errors) { 46 - $xactions = array(); 47 - $template = id(new PhabricatorRepositoryTransaction()); 48 - 49 - $type_name = PhabricatorRepositoryTransaction::TYPE_NAME; 50 - $type_desc = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION; 51 - $type_edge = PhabricatorTransactions::TYPE_EDGE; 52 - $type_slug = PhabricatorRepositoryTransaction::TYPE_SLUG; 53 - $type_callsign = PhabricatorRepositoryTransaction::TYPE_CALLSIGN; 54 - 55 - $xactions[] = id(clone $template) 56 - ->setTransactionType($type_name) 57 - ->setNewValue($v_name); 58 - 59 - $xactions[] = id(clone $template) 60 - ->setTransactionType($type_desc) 61 - ->setNewValue($v_desc); 62 - 63 - $xactions[] = id(clone $template) 64 - ->setTransactionType($type_slug) 65 - ->setNewValue($v_slug); 66 - 67 - $xactions[] = id(clone $template) 68 - ->setTransactionType($type_callsign) 69 - ->setNewValue($v_callsign); 70 - 71 - $xactions[] = id(clone $template) 72 - ->setTransactionType($type_edge) 73 - ->setMetadataValue( 74 - 'edge:type', 75 - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST) 76 - ->setNewValue( 77 - array( 78 - '=' => array_fuse($v_projects), 79 - )); 80 - 81 - $editor = id(new PhabricatorRepositoryEditor()) 82 - ->setContinueOnNoEffect(true) 83 - ->setContentSourceFromRequest($request) 84 - ->setActor($viewer); 85 - 86 - try { 87 - $editor->applyTransactions($repository, $xactions); 88 - 89 - // The preferred edit URI may have changed if the callsign or slug 90 - // were adjusted, so grab a fresh copy. 91 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 92 - 93 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 94 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 95 - $validation_exception = $ex; 96 - 97 - $e_slug = $ex->getShortMessage($type_slug); 98 - $e_callsign = $ex->getShortMessage($type_callsign); 99 - } 100 - } 101 - } 102 - 103 - $crumbs = $this->buildApplicationCrumbs(); 104 - $crumbs->addTextCrumb(pht('Edit Basics')); 105 - 106 - $title = pht('Edit %s', $repository->getName()); 107 - 108 - $header = id(new PHUIHeaderView()) 109 - ->setHeader($title) 110 - ->setHeaderIcon('fa-pencil'); 111 - 112 - $form = id(new AphrontFormView()) 113 - ->setUser($viewer) 114 - ->appendChild( 115 - id(new AphrontFormTextControl()) 116 - ->setName('name') 117 - ->setLabel(pht('Name')) 118 - ->setValue($v_name) 119 - ->setError($e_name)) 120 - ->appendChild( 121 - id(new AphrontFormTextControl()) 122 - ->setName('slug') 123 - ->setLabel(pht('Short Name')) 124 - ->setValue($v_slug) 125 - ->setError($e_slug)) 126 - ->appendChild( 127 - id(new AphrontFormTextControl()) 128 - ->setName('callsign') 129 - ->setLabel(pht('Callsign')) 130 - ->setValue($v_callsign) 131 - ->setError($e_callsign)) 132 - ->appendChild( 133 - id(new PhabricatorRemarkupControl()) 134 - ->setUser($viewer) 135 - ->setName('description') 136 - ->setLabel(pht('Description')) 137 - ->setValue($v_desc)) 138 - ->appendControl( 139 - id(new AphrontFormTokenizerControl()) 140 - ->setDatasource(new PhabricatorProjectDatasource()) 141 - ->setName('projectPHIDs') 142 - ->setLabel(pht('Projects')) 143 - ->setValue($v_projects)) 144 - ->appendChild( 145 - id(new AphrontFormSubmitControl()) 146 - ->setValue(pht('Save')) 147 - ->addCancelButton($edit_uri)) 148 - ->appendChild(id(new PHUIFormDividerControl())) 149 - ->appendRemarkupInstructions($this->getReadmeInstructions()); 150 - 151 - $form_box = id(new PHUIObjectBoxView()) 152 - ->setHeaderText(pht('Basic Information')) 153 - ->setValidationException($validation_exception) 154 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 155 - ->setForm($form) 156 - ->setFormErrors($errors); 157 - 158 - $view = id(new PHUITwoColumnView()) 159 - ->setHeader($header) 160 - ->setFooter(array( 161 - $form_box, 162 - )); 163 - 164 - return $this->newPage() 165 - ->setTitle($title) 166 - ->setCrumbs($crumbs) 167 - ->appendChild($view); 168 - } 169 - 170 - private function getReadmeInstructions() { 171 - return pht(<<<EOTEXT 172 - You can also create a `%s` file at the repository root (or in any 173 - subdirectory) to provide information about the repository. These formats are 174 - supported: 175 - 176 - | File Name | Rendered As... | 177 - |-----------|-----------------| 178 - | `%s` | Plain Text | 179 - | `%s` | Plain Text | 180 - | `%s` | Remarkup | 181 - | `%s` | Remarkup | 182 - | `%s` | \xC2\xA1Fiesta! | 183 - EOTEXT 184 - , 185 - 'README', 186 - 'README', 187 - 'README.txt', 188 - 'README.remarkup', 189 - 'README.md', 190 - 'README.rainbow'); 191 - } 192 - 193 - }
-248
src/applications/diffusion/controller/DiffusionRepositoryEditBranchesController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditBranchesController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $is_git = false; 17 - $is_hg = false; 18 - 19 - switch ($repository->getVersionControlSystem()) { 20 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 21 - $is_git = true; 22 - break; 23 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 24 - $is_hg = true; 25 - break; 26 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 27 - throw new Exception( 28 - pht('Subversion does not support branches!')); 29 - default: 30 - throw new Exception( 31 - pht('Repository has unknown version control system!')); 32 - } 33 - 34 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 35 - 36 - $v_default = $repository->getHumanReadableDetail('default-branch'); 37 - $v_track = $repository->getDetail( 38 - 'branch-filter', 39 - array()); 40 - $v_track = array_keys($v_track); 41 - $v_autoclose = $repository->getDetail( 42 - 'close-commits-filter', 43 - array()); 44 - $v_autoclose = array_keys($v_autoclose); 45 - 46 - $e_track = null; 47 - $e_autoclose = null; 48 - 49 - $validation_exception = null; 50 - if ($request->isFormPost()) { 51 - $v_default = $request->getStr('default'); 52 - 53 - $v_track = $this->processBranches($request->getStr('track')); 54 - if (!$is_hg) { 55 - $v_autoclose = $this->processBranches($request->getStr('autoclose')); 56 - } 57 - 58 - $xactions = array(); 59 - $template = id(new PhabricatorRepositoryTransaction()); 60 - 61 - $type_default = PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH; 62 - $type_track = PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY; 63 - $type_autoclose = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY; 64 - 65 - $xactions[] = id(clone $template) 66 - ->setTransactionType($type_default) 67 - ->setNewValue($v_default); 68 - 69 - $xactions[] = id(clone $template) 70 - ->setTransactionType($type_track) 71 - ->setNewValue($v_track); 72 - 73 - if (!$is_hg) { 74 - $xactions[] = id(clone $template) 75 - ->setTransactionType($type_autoclose) 76 - ->setNewValue($v_autoclose); 77 - } 78 - 79 - $editor = id(new PhabricatorRepositoryEditor()) 80 - ->setContinueOnNoEffect(true) 81 - ->setContentSourceFromRequest($request) 82 - ->setActor($viewer); 83 - 84 - try { 85 - $editor->applyTransactions($repository, $xactions); 86 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 87 - } catch (PhabricatorApplicationTransactionValidationException $ex) { 88 - $validation_exception = $ex; 89 - 90 - $e_track = $validation_exception->getShortMessage($type_track); 91 - $e_autoclose = $validation_exception->getShortMessage($type_autoclose); 92 - } 93 - } 94 - 95 - $content = array(); 96 - 97 - $crumbs = $this->buildApplicationCrumbs(); 98 - $crumbs->addTextCrumb(pht('Edit Branches')); 99 - 100 - $title = pht('Edit Branches (%s)', $repository->getName()); 101 - $header = id(new PHUIHeaderView()) 102 - ->setHeader($title) 103 - ->setHeaderIcon('fa-pencil'); 104 - 105 - $policies = id(new PhabricatorPolicyQuery()) 106 - ->setViewer($viewer) 107 - ->setObject($repository) 108 - ->execute(); 109 - 110 - $rows = array(); 111 - $rows[] = array( 112 - array( 113 - 'master', 114 - ), 115 - pht('Select only master.'), 116 - ); 117 - $rows[] = array( 118 - array( 119 - 'master', 120 - 'develop', 121 - 'release', 122 - ), 123 - pht('Select %s, %s, and %s.', 'master', 'develop', 'release'), 124 - ); 125 - $rows[] = array( 126 - array( 127 - 'master', 128 - 'regexp(/^release-/)', 129 - ), 130 - pht('Select master, and all branches which start with "%s".', 'release-'), 131 - ); 132 - $rows[] = array( 133 - array( 134 - 'regexp(/^(?!temp-)/)', 135 - ), 136 - pht('Select all branches which do not start with "%s".', 'temp-'), 137 - ); 138 - 139 - foreach ($rows as $k => $row) { 140 - $rows[$k][0] = phutil_tag( 141 - 'pre', 142 - array(), 143 - implode("\n", $row[0])); 144 - } 145 - 146 - $example_table = id(new AphrontTableView($rows)) 147 - ->setHeaders( 148 - array( 149 - pht('Example'), 150 - pht('Effect'), 151 - )) 152 - ->setColumnClasses( 153 - array( 154 - '', 155 - 'wide', 156 - )); 157 - 158 - $v_track = implode("\n", $v_track); 159 - $v_autoclose = implode("\n", $v_autoclose); 160 - 161 - $form = id(new AphrontFormView()) 162 - ->setUser($viewer) 163 - ->appendRemarkupInstructions( 164 - pht('You can choose a **Default Branch** for viewing this repository.')) 165 - ->appendChild( 166 - id(new AphrontFormTextControl()) 167 - ->setName('default') 168 - ->setLabel(pht('Default Branch')) 169 - ->setValue($v_default)) 170 - ->appendRemarkupInstructions( 171 - pht( 172 - 'If you want to import only some branches into Diffusion, you can '. 173 - 'list them in **Track Only**. Other branches will be ignored. If '. 174 - 'you do not specify any branches, all branches are tracked.')); 175 - 176 - if (!$is_hg) { 177 - $form->appendRemarkupInstructions( 178 - pht( 179 - 'If you have **Autoclose** enabled for this repository, Phabricator '. 180 - 'can close tasks and revisions when corresponding commits are '. 181 - 'pushed to the repository. If you want to autoclose objects only '. 182 - 'when commits appear on specific branches, you can list those '. 183 - 'branches in **Autoclose Only**. By default, all tracked branches '. 184 - 'will autoclose objects.')); 185 - } 186 - 187 - $form 188 - ->appendRemarkupInstructions( 189 - pht( 190 - 'When specifying branches, you should enter one branch name per '. 191 - 'line. You can use regular expressions to match branches by '. 192 - 'wrapping an expression in `%s`. For example:', 193 - 'regexp(...)')) 194 - ->appendChild( 195 - id(new AphrontFormMarkupControl()) 196 - ->setValue($example_table)) 197 - ->appendChild( 198 - id(new AphrontFormTextAreaControl()) 199 - ->setName('track') 200 - ->setLabel(pht('Track Only')) 201 - ->setError($e_track) 202 - ->setValue($v_track)); 203 - 204 - if (!$is_hg) { 205 - $form->appendChild( 206 - id(new AphrontFormTextAreaControl()) 207 - ->setName('autoclose') 208 - ->setLabel(pht('Autoclose Only')) 209 - ->setError($e_autoclose) 210 - ->setValue($v_autoclose)); 211 - } 212 - 213 - $form->appendChild( 214 - id(new AphrontFormSubmitControl()) 215 - ->setValue(pht('Save Branches')) 216 - ->addCancelButton($edit_uri)); 217 - 218 - $form_box = id(new PHUIObjectBoxView()) 219 - ->setHeaderText(pht('Branches')) 220 - ->setValidationException($validation_exception) 221 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 222 - ->setForm($form); 223 - 224 - $view = id(new PHUITwoColumnView()) 225 - ->setHeader($header) 226 - ->setFooter(array( 227 - $form_box, 228 - )); 229 - 230 - return $this->newPage() 231 - ->setTitle($title) 232 - ->setCrumbs($crumbs) 233 - ->appendChild($view); 234 - } 235 - 236 - private function processBranches($string) { 237 - $lines = phutil_split_lines($string, $retain_endings = false); 238 - foreach ($lines as $key => $line) { 239 - $lines[$key] = trim($line); 240 - if (!strlen($lines[$key])) { 241 - unset($lines[$key]); 242 - } 243 - } 244 - 245 - return array_values($lines); 246 - } 247 - 248 - }
-107
src/applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditEncodingController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $user = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 17 - 18 - $v_encoding = $repository->getDetail('encoding'); 19 - $e_encoding = null; 20 - $errors = array(); 21 - 22 - if ($request->isFormPost()) { 23 - $v_encoding = $request->getStr('encoding'); 24 - 25 - if (!$errors) { 26 - $xactions = array(); 27 - $template = id(new PhabricatorRepositoryTransaction()); 28 - 29 - $type_encoding = PhabricatorRepositoryTransaction::TYPE_ENCODING; 30 - 31 - $xactions[] = id(clone $template) 32 - ->setTransactionType($type_encoding) 33 - ->setNewValue($v_encoding); 34 - 35 - try { 36 - id(new PhabricatorRepositoryEditor()) 37 - ->setContinueOnNoEffect(true) 38 - ->setContentSourceFromRequest($request) 39 - ->setActor($user) 40 - ->applyTransactions($repository, $xactions); 41 - 42 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 43 - } catch (Exception $ex) { 44 - $errors[] = $ex->getMessage(); 45 - } 46 - } 47 - } 48 - 49 - $crumbs = $this->buildApplicationCrumbs(); 50 - $crumbs->addTextCrumb(pht('Edit Encoding')); 51 - 52 - $title = pht('Edit %s', $repository->getName()); 53 - $header = id(new PHUIHeaderView()) 54 - ->setHeader($title) 55 - ->setHeaderIcon('fa-pencil'); 56 - 57 - $form = id(new AphrontFormView()) 58 - ->setUser($user) 59 - ->appendRemarkupInstructions($this->getEncodingInstructions()) 60 - ->appendChild( 61 - id(new AphrontFormTextControl()) 62 - ->setName('encoding') 63 - ->setLabel(pht('Text Encoding')) 64 - ->setValue($v_encoding) 65 - ->setError($e_encoding)) 66 - ->appendChild( 67 - id(new AphrontFormSubmitControl()) 68 - ->setValue(pht('Save Encoding')) 69 - ->addCancelButton($edit_uri)); 70 - 71 - $form_box = id(new PHUIObjectBoxView()) 72 - ->setHeaderText(pht('Encoding')) 73 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 74 - ->setForm($form) 75 - ->setFormErrors($errors); 76 - 77 - $view = id(new PHUITwoColumnView()) 78 - ->setHeader($header) 79 - ->setFooter(array( 80 - $form_box, 81 - )); 82 - 83 - return $this->newPage() 84 - ->setTitle($title) 85 - ->setCrumbs($crumbs) 86 - ->appendChild($view); 87 - } 88 - 89 - private function getEncodingInstructions() { 90 - return pht(<<<EOT 91 - If source code in this repository uses a character encoding other than UTF-8 92 - (for example, `ISO-8859-1`), specify it here. 93 - 94 - **Normally, you can leave this field blank.** If your source code is written in 95 - ASCII or UTF-8, everything will work correctly. 96 - 97 - Source files will be translated from the specified encoding to UTF-8 when they 98 - are read from the repository, before they are displayed in Diffusion. 99 - 100 - See [[%s | UTF-8 and Character Encoding]] for more information on how 101 - Phabricator handles text encodings. 102 - EOT 103 - , 104 - PhabricatorEnv::getDoclink('User Guide: UTF-8 and Character Encoding')); 105 - } 106 - 107 - }
-288
src/applications/diffusion/controller/DiffusionRepositoryEditHostingController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditHostingController 4 - extends DiffusionRepositoryEditController { 5 - 6 - private $serve; 7 - 8 - public function handleRequest(AphrontRequest $request) { 9 - $response = $this->loadDiffusionContextForEdit(); 10 - if ($response) { 11 - return $response; 12 - } 13 - 14 - $drequest = $this->getDiffusionRequest(); 15 - $repository = $drequest->getRepository(); 16 - 17 - $this->serve = $request->getURIData('serve'); 18 - 19 - if (!$this->serve) { 20 - return $this->handleHosting($repository); 21 - } else { 22 - return $this->handleProtocols($repository); 23 - } 24 - } 25 - 26 - public function handleHosting(PhabricatorRepository $repository) { 27 - $request = $this->getRequest(); 28 - $user = $request->getUser(); 29 - 30 - $v_hosting = $repository->isHosted(); 31 - 32 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 33 - $next_uri = $this->getRepositoryControllerURI($repository, 'edit/serve/'); 34 - 35 - if ($request->isFormPost()) { 36 - $v_hosting = $request->getBool('hosting'); 37 - 38 - $xactions = array(); 39 - $template = id(new PhabricatorRepositoryTransaction()); 40 - 41 - $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING; 42 - 43 - $xactions[] = id(clone $template) 44 - ->setTransactionType($type_hosting) 45 - ->setNewValue($v_hosting); 46 - 47 - id(new PhabricatorRepositoryEditor()) 48 - ->setContinueOnNoEffect(true) 49 - ->setContentSourceFromRequest($request) 50 - ->setActor($user) 51 - ->applyTransactions($repository, $xactions); 52 - 53 - return id(new AphrontRedirectResponse())->setURI($next_uri); 54 - } 55 - 56 - $crumbs = $this->buildApplicationCrumbs(); 57 - $crumbs->addTextCrumb(pht('Edit Hosting')); 58 - 59 - $title = pht('Edit Hosting (%s)', $repository->getName()); 60 - $header = id(new PHUIHeaderView()) 61 - ->setHeader($title) 62 - ->setHeaderIcon('fa-pencil'); 63 - 64 - $hosted_control = id(new AphrontFormRadioButtonControl()) 65 - ->setName('hosting') 66 - ->setLabel(pht('Hosting')) 67 - ->addButton( 68 - true, 69 - pht('Host Repository on Phabricator'), 70 - pht( 71 - 'Phabricator will host this repository. Users will be able to '. 72 - 'push commits to Phabricator. Phabricator will not pull '. 73 - 'changes from elsewhere.')) 74 - ->addButton( 75 - false, 76 - pht('Host Repository Elsewhere'), 77 - pht( 78 - 'Phabricator will pull updates to this repository from a master '. 79 - 'repository elsewhere (for example, on GitHub or Bitbucket). '. 80 - 'Users will not be able to push commits to this repository.')) 81 - ->setValue($v_hosting); 82 - 83 - $doc_href = PhabricatorEnv::getDoclink( 84 - 'Diffusion User Guide: Repository Hosting'); 85 - 86 - $form = id(new AphrontFormView()) 87 - ->setUser($user) 88 - ->appendRemarkupInstructions( 89 - pht( 90 - 'Phabricator can host repositories, or it can track repositories '. 91 - 'hosted elsewhere (like on GitHub or Bitbucket). For information '. 92 - 'on configuring hosting, see [[ %s | Diffusion User Guide: '. 93 - 'Repository Hosting]]', 94 - $doc_href)) 95 - ->appendChild($hosted_control) 96 - ->appendChild( 97 - id(new AphrontFormSubmitControl()) 98 - ->setValue(pht('Save and Continue')) 99 - ->addCancelButton($edit_uri)); 100 - 101 - $form_box = id(new PHUIObjectBoxView()) 102 - ->setHeaderText(pht('Hosting')) 103 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 104 - ->setForm($form); 105 - 106 - $view = id(new PHUITwoColumnView()) 107 - ->setHeader($header) 108 - ->setFooter(array( 109 - $form_box, 110 - )); 111 - 112 - return $this->newPage() 113 - ->setTitle($title) 114 - ->setCrumbs($crumbs) 115 - ->appendChild($view); 116 - } 117 - 118 - public function handleProtocols(PhabricatorRepository $repository) { 119 - $request = $this->getRequest(); 120 - $user = $request->getUser(); 121 - 122 - $type = $repository->getVersionControlSystem(); 123 - $is_svn = ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN); 124 - 125 - $v_http_mode = $repository->getDetail( 126 - 'serve-over-http', 127 - PhabricatorRepository::SERVE_OFF); 128 - $v_ssh_mode = $repository->getDetail( 129 - 'serve-over-ssh', 130 - PhabricatorRepository::SERVE_OFF); 131 - 132 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 133 - $prev_uri = $this->getRepositoryControllerURI($repository, 'edit/hosting/'); 134 - 135 - if ($request->isFormPost()) { 136 - $v_http_mode = $request->getStr('http'); 137 - $v_ssh_mode = $request->getStr('ssh'); 138 - 139 - $xactions = array(); 140 - $template = id(new PhabricatorRepositoryTransaction()); 141 - 142 - $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; 143 - $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; 144 - 145 - if (!$is_svn) { 146 - $xactions[] = id(clone $template) 147 - ->setTransactionType($type_http) 148 - ->setNewValue($v_http_mode); 149 - } 150 - 151 - $xactions[] = id(clone $template) 152 - ->setTransactionType($type_ssh) 153 - ->setNewValue($v_ssh_mode); 154 - 155 - id(new PhabricatorRepositoryEditor()) 156 - ->setContinueOnNoEffect(true) 157 - ->setContentSourceFromRequest($request) 158 - ->setActor($user) 159 - ->applyTransactions($repository, $xactions); 160 - 161 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 162 - } 163 - 164 - $crumbs = $this->buildApplicationCrumbs(); 165 - $crumbs->addTextCrumb(pht('Edit Protocols')); 166 - 167 - $title = pht('Edit Protocols (%s)', $repository->getName()); 168 - $header = id(new PHUIHeaderView()) 169 - ->setHeader($title) 170 - ->setHeaderIcon('fa-pencil'); 171 - 172 - $rw_message = pht( 173 - 'Phabricator will serve a read-write copy of this repository.'); 174 - 175 - if (!$repository->isHosted()) { 176 - $rw_message = array( 177 - $rw_message, 178 - phutil_tag('br'), 179 - phutil_tag('br'), 180 - pht( 181 - '%s: This repository is hosted elsewhere, so Phabricator can not '. 182 - 'perform writes. This mode will act like "Read Only" for '. 183 - 'repositories hosted elsewhere.', 184 - phutil_tag('strong', array(), pht('WARNING'))), 185 - ); 186 - } 187 - 188 - $ssh_control = 189 - id(new AphrontFormRadioButtonControl()) 190 - ->setName('ssh') 191 - ->setLabel(pht('SSH')) 192 - ->setValue($v_ssh_mode) 193 - ->addButton( 194 - PhabricatorRepository::SERVE_OFF, 195 - PhabricatorRepository::getProtocolAvailabilityName( 196 - PhabricatorRepository::SERVE_OFF), 197 - pht('Phabricator will not serve this repository over SSH.')) 198 - ->addButton( 199 - PhabricatorRepository::SERVE_READONLY, 200 - PhabricatorRepository::getProtocolAvailabilityName( 201 - PhabricatorRepository::SERVE_READONLY), 202 - pht( 203 - 'Phabricator will serve a read-only copy of this repository '. 204 - 'over SSH.')) 205 - ->addButton( 206 - PhabricatorRepository::SERVE_READWRITE, 207 - PhabricatorRepository::getProtocolAvailabilityName( 208 - PhabricatorRepository::SERVE_READWRITE), 209 - $rw_message); 210 - 211 - $http_control = 212 - id(new AphrontFormRadioButtonControl()) 213 - ->setName('http') 214 - ->setLabel(pht('HTTP')) 215 - ->setValue($v_http_mode) 216 - ->addButton( 217 - PhabricatorRepository::SERVE_OFF, 218 - PhabricatorRepository::getProtocolAvailabilityName( 219 - PhabricatorRepository::SERVE_OFF), 220 - pht('Phabricator will not serve this repository over HTTP.')) 221 - ->addButton( 222 - PhabricatorRepository::SERVE_READONLY, 223 - PhabricatorRepository::getProtocolAvailabilityName( 224 - PhabricatorRepository::SERVE_READONLY), 225 - pht( 226 - 'Phabricator will serve a read-only copy of this repository '. 227 - 'over HTTP.')) 228 - ->addButton( 229 - PhabricatorRepository::SERVE_READWRITE, 230 - PhabricatorRepository::getProtocolAvailabilityName( 231 - PhabricatorRepository::SERVE_READWRITE), 232 - $rw_message); 233 - 234 - if ($is_svn) { 235 - $http_control = id(new AphrontFormMarkupControl()) 236 - ->setLabel(pht('HTTP')) 237 - ->setValue( 238 - phutil_tag( 239 - 'em', 240 - array(), 241 - pht( 242 - 'Phabricator does not currently support HTTP access to '. 243 - 'Subversion repositories.'))); 244 - } 245 - 246 - $form = id(new AphrontFormView()) 247 - ->setUser($user) 248 - ->appendRemarkupInstructions( 249 - pht( 250 - 'Phabricator can serve repositories over various protocols. You can '. 251 - 'configure server protocols here.')) 252 - ->appendChild($ssh_control); 253 - 254 - if (!PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) { 255 - $form->appendRemarkupInstructions( 256 - pht( 257 - 'NOTE: The configuration setting [[ %s | %s ]] is currently '. 258 - 'disabled. You must enable it to activate authenticated access '. 259 - 'to repositories over HTTP.', 260 - '/config/edit/diffusion.allow-http-auth/', 261 - 'diffusion.allow-http-auth')); 262 - } 263 - 264 - $form 265 - ->appendChild($http_control) 266 - ->appendChild( 267 - id(new AphrontFormSubmitControl()) 268 - ->setValue(pht('Save Changes')) 269 - ->addCancelButton($prev_uri, pht('Back'))); 270 - 271 - $form_box = id(new PHUIObjectBoxView()) 272 - ->setHeaderText(pht('Protocols')) 273 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 274 - ->setForm($form); 275 - 276 - $view = id(new PHUITwoColumnView()) 277 - ->setHeader($header) 278 - ->setFooter(array( 279 - $form_box, 280 - )); 281 - 282 - return $this->newPage() 283 - ->setTitle($title) 284 - ->setCrumbs($crumbs) 285 - ->appendChild($view); 286 - } 287 - 288 - }
-1221
src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditMainController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $is_svn = false; 17 - $is_git = false; 18 - $is_hg = false; 19 - switch ($repository->getVersionControlSystem()) { 20 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 21 - $is_git = true; 22 - break; 23 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 24 - $is_svn = true; 25 - break; 26 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 27 - $is_hg = true; 28 - break; 29 - } 30 - 31 - $has_branches = ($is_git || $is_hg); 32 - $has_local = $repository->usesLocalWorkingCopy(); 33 - $supports_staging = $repository->supportsStaging(); 34 - $supports_automation = $repository->supportsAutomation(); 35 - 36 - $crumbs = $this->buildApplicationCrumbs($is_main = true); 37 - 38 - $title = pht('Edit %s', $repository->getName()); 39 - 40 - $header = id(new PHUIHeaderView()) 41 - ->setHeader($title) 42 - ->setHeaderIcon('fa-pencil'); 43 - if ($repository->isTracked()) { 44 - $header->setStatus('fa-check', 'bluegrey', pht('Active')); 45 - } else { 46 - $header->setStatus('fa-ban', 'dark', pht('Inactive')); 47 - } 48 - 49 - $curtain = $this->buildCurtain($repository); 50 - $basic_properties = $this->buildBasicProperties($repository); 51 - 52 - $policy_actions = $this->buildPolicyActions($repository); 53 - $policy_properties = 54 - $this->buildPolicyProperties($repository, $policy_actions); 55 - 56 - $remote_properties = null; 57 - if (!$repository->isHosted()) { 58 - $remote_properties = $this->buildRemoteProperties( 59 - $repository, 60 - $this->buildRemoteActions($repository)); 61 - } 62 - 63 - $encoding_actions = $this->buildEncodingActions($repository); 64 - $encoding_properties = 65 - $this->buildEncodingProperties($repository, $encoding_actions); 66 - 67 - $symbols_actions = $this->buildSymbolsActions($repository); 68 - $symbols_properties = 69 - $this->buildSymbolsProperties($repository, $symbols_actions); 70 - 71 - $hosting_properties = $this->buildHostingProperties( 72 - $repository, 73 - $this->buildHostingActions($repository)); 74 - 75 - 76 - $branches_properties = null; 77 - if ($has_branches) { 78 - $branches_properties = $this->buildBranchesProperties( 79 - $repository, 80 - $this->buildBranchesActions($repository)); 81 - } 82 - 83 - $subversion_properties = null; 84 - if ($is_svn) { 85 - $subversion_properties = $this->buildSubversionProperties( 86 - $repository, 87 - $this->buildSubversionActions($repository)); 88 - } 89 - 90 - $storage_properties = null; 91 - if ($has_local) { 92 - $storage_properties = $this->buildStorageProperties( 93 - $repository, 94 - $this->buildStorageActions($repository)); 95 - } 96 - 97 - $staging_properties = null; 98 - if ($supports_staging) { 99 - $staging_properties = $this->buildStagingProperties( 100 - $repository, 101 - $this->buildStagingActions($repository)); 102 - } 103 - 104 - $automation_properties = null; 105 - if ($supports_automation) { 106 - $automation_properties = $this->buildAutomationProperties( 107 - $repository, 108 - $this->buildAutomationActions($repository)); 109 - } 110 - 111 - $actions_properties = $this->buildActionsProperties( 112 - $repository, 113 - $this->buildActionsActions($repository)); 114 - 115 - $timeline = $this->buildTransactionTimeline( 116 - $repository, 117 - new PhabricatorRepositoryTransactionQuery()); 118 - $timeline->setShouldTerminate(true); 119 - 120 - $boxes = array(); 121 - 122 - $boxes[] = id(new PHUIObjectBoxView()) 123 - ->setHeaderText(pht('Policies')) 124 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 125 - ->addPropertyList($policy_properties); 126 - 127 - $boxes[] = id(new PHUIObjectBoxView()) 128 - ->setHeaderText(pht('Hosting')) 129 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 130 - ->addPropertyList($hosting_properties); 131 - 132 - if ($remote_properties) { 133 - $boxes[] = id(new PHUIObjectBoxView()) 134 - ->setHeaderText(pht('Remote')) 135 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 136 - ->addPropertyList($remote_properties); 137 - } 138 - 139 - if ($storage_properties) { 140 - $boxes[] = id(new PHUIObjectBoxView()) 141 - ->setHeaderText(pht('Storage')) 142 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 143 - ->addPropertyList($storage_properties); 144 - } 145 - 146 - if ($staging_properties) { 147 - $boxes[] = id(new PHUIObjectBoxView()) 148 - ->setHeaderText(pht('Staging')) 149 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 150 - ->addPropertyList($staging_properties); 151 - } 152 - 153 - if ($automation_properties) { 154 - $boxes[] = id(new PHUIObjectBoxView()) 155 - ->setHeaderText(pht('Automation')) 156 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 157 - ->addPropertyList($automation_properties); 158 - } 159 - 160 - $boxes[] = id(new PHUIObjectBoxView()) 161 - ->setHeaderText(pht('Text Encoding')) 162 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 163 - ->addPropertyList($encoding_properties); 164 - 165 - $boxes[] = id(new PHUIObjectBoxView()) 166 - ->setHeaderText(pht('Symbols')) 167 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 168 - ->addPropertyList($symbols_properties); 169 - 170 - if ($branches_properties) { 171 - $boxes[] = id(new PHUIObjectBoxView()) 172 - ->setHeaderText(pht('Branches')) 173 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 174 - ->addPropertyList($branches_properties); 175 - } 176 - 177 - if ($subversion_properties) { 178 - $boxes[] = id(new PHUIObjectBoxView()) 179 - ->setHeaderText(pht('Subversion')) 180 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 181 - ->addPropertyList($subversion_properties); 182 - } 183 - 184 - $boxes[] = id(new PHUIObjectBoxView()) 185 - ->setHeaderText(pht('Actions')) 186 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 187 - ->addPropertyList($actions_properties); 188 - 189 - $crumbs->setBorder(true); 190 - 191 - $view = id(new PHUITwoColumnView()) 192 - ->setHeader($header) 193 - ->setCurtain($curtain) 194 - ->addPropertySection(pht('Properties'), $basic_properties) 195 - ->setMainColumn(array( 196 - $boxes, 197 - $timeline, 198 - )); 199 - 200 - return $this->newPage() 201 - ->setTitle($title) 202 - ->setCrumbs($crumbs) 203 - ->appendChild($view); 204 - 205 - } 206 - 207 - private function buildCurtain(PhabricatorRepository $repository) { 208 - $viewer = $this->getViewer(); 209 - 210 - $curtain = $this->newCurtainView($repository); 211 - 212 - $edit = id(new PhabricatorActionView()) 213 - ->setIcon('fa-pencil') 214 - ->setName(pht('Edit Basic Information')) 215 - ->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/')); 216 - $curtain->addAction($edit); 217 - 218 - $edit = id(new PhabricatorActionView()) 219 - ->setIcon('fa-refresh') 220 - ->setName(pht('Update Now')) 221 - ->setWorkflow(true) 222 - ->setHref( 223 - $this->getRepositoryControllerURI($repository, 'edit/update/')); 224 - $curtain->addAction($edit); 225 - 226 - $activate = id(new PhabricatorActionView()) 227 - ->setHref( 228 - $this->getRepositoryControllerURI($repository, 'edit/activate/')) 229 - ->setWorkflow(true); 230 - 231 - if ($repository->isTracked()) { 232 - $activate 233 - ->setIcon('fa-pause') 234 - ->setName(pht('Deactivate Repository')); 235 - } else { 236 - $activate 237 - ->setIcon('fa-play') 238 - ->setName(pht('Activate Repository')); 239 - } 240 - 241 - $curtain->addAction($activate); 242 - 243 - $curtain->addAction( 244 - id(new PhabricatorActionView()) 245 - ->setName(pht('Delete Repository')) 246 - ->setIcon('fa-times') 247 - ->setHref( 248 - $this->getRepositoryControllerURI($repository, 'edit/delete/')) 249 - ->setDisabled(true) 250 - ->setWorkflow(true)); 251 - 252 - return $curtain; 253 - } 254 - 255 - private function buildBasicProperties( 256 - PhabricatorRepository $repository) { 257 - 258 - $viewer = $this->getViewer(); 259 - 260 - $view = id(new PHUIPropertyListView()) 261 - ->setUser($viewer); 262 - 263 - $type = PhabricatorRepositoryType::getNameForRepositoryType( 264 - $repository->getVersionControlSystem()); 265 - 266 - $view->addProperty(pht('Type'), $type); 267 - 268 - $callsign = $repository->getCallsign(); 269 - if (!strlen($callsign)) { 270 - $callsign = phutil_tag('em', array(), pht('No Callsign')); 271 - } 272 - $view->addProperty(pht('Callsign'), $callsign); 273 - 274 - $short_name = $repository->getRepositorySlug(); 275 - if ($short_name === null) { 276 - $short_name = $repository->getCloneName(); 277 - $short_name = phutil_tag('em', array(), $short_name); 278 - } 279 - $view->addProperty(pht('Short Name'), $short_name); 280 - 281 - $view->invokeWillRenderEvent(); 282 - 283 - $view->addProperty( 284 - pht('Status'), 285 - $this->buildRepositoryStatus($repository)); 286 - 287 - $view->addProperty( 288 - pht('Update Frequency'), 289 - $this->buildRepositoryUpdateInterval($repository)); 290 - 291 - $description = $repository->getDetail('description'); 292 - $view->addSectionHeader( 293 - pht('Description'), PHUIPropertyListView::ICON_SUMMARY); 294 - if (!strlen($description)) { 295 - $description = phutil_tag('em', array(), pht('No description provided.')); 296 - } else { 297 - $description = new PHUIRemarkupView($viewer, $description); 298 - } 299 - $view->addTextContent($description); 300 - 301 - return $view; 302 - } 303 - 304 - private function buildEncodingActions(PhabricatorRepository $repository) { 305 - $viewer = $this->getViewer(); 306 - 307 - $view = id(new PhabricatorActionListView()) 308 - ->setUser($viewer); 309 - 310 - $edit = id(new PhabricatorActionView()) 311 - ->setIcon('fa-pencil') 312 - ->setName(pht('Edit Text Encoding')) 313 - ->setHref( 314 - $this->getRepositoryControllerURI($repository, 'edit/encoding/')); 315 - $view->addAction($edit); 316 - 317 - return $view; 318 - } 319 - 320 - private function buildEncodingProperties( 321 - PhabricatorRepository $repository, 322 - PhabricatorActionListView $actions) { 323 - 324 - $viewer = $this->getViewer(); 325 - 326 - $view = id(new PHUIPropertyListView()) 327 - ->setUser($viewer) 328 - ->setActionList($actions); 329 - 330 - $encoding = $repository->getDetail('encoding'); 331 - if (!$encoding) { 332 - $encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)')); 333 - } 334 - 335 - $view->addProperty(pht('Encoding'), $encoding); 336 - 337 - return $view; 338 - } 339 - 340 - private function buildPolicyActions(PhabricatorRepository $repository) { 341 - $viewer = $this->getViewer(); 342 - 343 - $view = id(new PhabricatorActionListView()) 344 - ->setUser($viewer); 345 - 346 - $edit = id(new PhabricatorActionView()) 347 - ->setIcon('fa-pencil') 348 - ->setName(pht('Edit Policies')) 349 - ->setHref( 350 - $this->getRepositoryControllerURI($repository, 'edit/policy/')); 351 - $view->addAction($edit); 352 - 353 - return $view; 354 - } 355 - 356 - private function buildPolicyProperties( 357 - PhabricatorRepository $repository, 358 - PhabricatorActionListView $actions) { 359 - 360 - $viewer = $this->getViewer(); 361 - 362 - $view = id(new PHUIPropertyListView()) 363 - ->setUser($viewer) 364 - ->setActionList($actions); 365 - 366 - $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( 367 - $viewer, 368 - $repository); 369 - 370 - $view_parts = array(); 371 - if (PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { 372 - $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( 373 - $repository); 374 - $view_parts[] = $viewer->renderHandle($space_phid); 375 - } 376 - $view_parts[] = $descriptions[PhabricatorPolicyCapability::CAN_VIEW]; 377 - 378 - $view->addProperty( 379 - pht('Visible To'), 380 - phutil_implode_html(" \xC2\xB7 ", $view_parts)); 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->getViewer(); 396 - 397 - $view = id(new PhabricatorActionListView()) 398 - ->setUser($viewer); 399 - 400 - $edit = id(new PhabricatorActionView()) 401 - ->setIcon('fa-pencil') 402 - ->setName(pht('Edit Branches')) 403 - ->setHref( 404 - $this->getRepositoryControllerURI($repository, 'edit/branches/')); 405 - $view->addAction($edit); 406 - 407 - return $view; 408 - } 409 - 410 - private function buildBranchesProperties( 411 - PhabricatorRepository $repository, 412 - PhabricatorActionListView $actions) { 413 - 414 - $viewer = $this->getViewer(); 415 - 416 - $view = id(new PHUIPropertyListView()) 417 - ->setUser($viewer) 418 - ->setActionList($actions); 419 - 420 - $default_branch = nonempty( 421 - $repository->getHumanReadableDetail('default-branch'), 422 - phutil_tag('em', array(), $repository->getDefaultBranch())); 423 - $view->addProperty(pht('Default Branch'), $default_branch); 424 - 425 - $track_only = nonempty( 426 - $repository->getHumanReadableDetail('branch-filter', array()), 427 - phutil_tag('em', array(), pht('Track All Branches'))); 428 - $view->addProperty(pht('Track Only'), $track_only); 429 - 430 - $autoclose_only = nonempty( 431 - $repository->getHumanReadableDetail('close-commits-filter', array()), 432 - phutil_tag('em', array(), pht('Autoclose On All Branches'))); 433 - 434 - if ($repository->getDetail('disable-autoclose')) { 435 - $autoclose_only = phutil_tag('em', array(), pht('Disabled')); 436 - } 437 - 438 - $view->addProperty(pht('Autoclose Only'), $autoclose_only); 439 - 440 - return $view; 441 - } 442 - 443 - private function buildSubversionActions(PhabricatorRepository $repository) { 444 - $viewer = $this->getViewer(); 445 - 446 - $view = id(new PhabricatorActionListView()) 447 - ->setUser($viewer); 448 - 449 - $edit = id(new PhabricatorActionView()) 450 - ->setIcon('fa-pencil') 451 - ->setName(pht('Edit Subversion Info')) 452 - ->setHref( 453 - $this->getRepositoryControllerURI($repository, 'edit/subversion/')); 454 - $view->addAction($edit); 455 - 456 - return $view; 457 - } 458 - 459 - private function buildSubversionProperties( 460 - PhabricatorRepository $repository, 461 - PhabricatorActionListView $actions) { 462 - 463 - $viewer = $this->getViewer(); 464 - 465 - $view = id(new PHUIPropertyListView()) 466 - ->setUser($viewer) 467 - ->setActionList($actions); 468 - 469 - $svn_uuid = nonempty( 470 - $repository->getUUID(), 471 - phutil_tag('em', array(), pht('Not Configured'))); 472 - $view->addProperty(pht('Subversion UUID'), $svn_uuid); 473 - 474 - $svn_subpath = nonempty( 475 - $repository->getHumanReadableDetail('svn-subpath'), 476 - phutil_tag('em', array(), pht('Import Entire Repository'))); 477 - $view->addProperty(pht('Import Only'), $svn_subpath); 478 - 479 - return $view; 480 - } 481 - 482 - private function buildActionsActions(PhabricatorRepository $repository) { 483 - $viewer = $this->getViewer(); 484 - 485 - $view = id(new PhabricatorActionListView()) 486 - ->setUser($viewer); 487 - 488 - $edit = id(new PhabricatorActionView()) 489 - ->setIcon('fa-pencil') 490 - ->setName(pht('Edit Actions')) 491 - ->setHref( 492 - $this->getRepositoryControllerURI($repository, 'edit/actions/')); 493 - $view->addAction($edit); 494 - 495 - return $view; 496 - } 497 - 498 - private function buildActionsProperties( 499 - PhabricatorRepository $repository, 500 - PhabricatorActionListView $actions) { 501 - 502 - $viewer = $this->getViewer(); 503 - 504 - $view = id(new PHUIPropertyListView()) 505 - ->setUser($viewer) 506 - ->setActionList($actions); 507 - 508 - $notify = $repository->getDetail('herald-disabled') 509 - ? pht('Off') 510 - : pht('On'); 511 - $notify = phutil_tag('em', array(), $notify); 512 - $view->addProperty(pht('Publish/Notify'), $notify); 513 - 514 - $autoclose = $repository->getDetail('disable-autoclose') 515 - ? pht('Off') 516 - : pht('On'); 517 - $autoclose = phutil_tag('em', array(), $autoclose); 518 - $view->addProperty(pht('Autoclose'), $autoclose); 519 - 520 - return $view; 521 - } 522 - 523 - private function buildRemoteActions(PhabricatorRepository $repository) { 524 - $viewer = $this->getViewer(); 525 - 526 - $view = id(new PhabricatorActionListView()) 527 - ->setUser($viewer); 528 - 529 - $edit = id(new PhabricatorActionView()) 530 - ->setIcon('fa-pencil') 531 - ->setName(pht('Edit Remote')) 532 - ->setHref( 533 - $this->getRepositoryControllerURI($repository, 'edit/remote/')); 534 - $view->addAction($edit); 535 - 536 - return $view; 537 - } 538 - 539 - private function buildRemoteProperties( 540 - PhabricatorRepository $repository, 541 - PhabricatorActionListView $actions) { 542 - 543 - $viewer = $this->getViewer(); 544 - 545 - $view = id(new PHUIPropertyListView()) 546 - ->setUser($viewer) 547 - ->setActionList($actions); 548 - 549 - $view->addProperty( 550 - pht('Remote URI'), 551 - $repository->getHumanReadableDetail('remote-uri')); 552 - 553 - $credential_phid = $repository->getCredentialPHID(); 554 - if ($credential_phid) { 555 - $view->addProperty( 556 - pht('Credential'), 557 - $viewer->renderHandle($credential_phid)); 558 - } 559 - 560 - return $view; 561 - } 562 - 563 - private function buildStorageActions(PhabricatorRepository $repository) { 564 - $viewer = $this->getViewer(); 565 - 566 - $view = id(new PhabricatorActionListView()) 567 - ->setUser($viewer); 568 - 569 - $edit = id(new PhabricatorActionView()) 570 - ->setIcon('fa-pencil') 571 - ->setName(pht('Edit Storage')) 572 - ->setHref( 573 - $this->getRepositoryControllerURI($repository, 'edit/storage/')); 574 - $view->addAction($edit); 575 - 576 - return $view; 577 - } 578 - 579 - private function buildStorageProperties( 580 - PhabricatorRepository $repository, 581 - PhabricatorActionListView $actions) { 582 - 583 - $viewer = $this->getViewer(); 584 - 585 - $view = id(new PHUIPropertyListView()) 586 - ->setUser($viewer) 587 - ->setActionList($actions); 588 - 589 - $service_phid = $repository->getAlmanacServicePHID(); 590 - if ($service_phid) { 591 - $v_service = $viewer->renderHandle($service_phid); 592 - } else { 593 - $v_service = phutil_tag( 594 - 'em', 595 - array(), 596 - pht('Local')); 597 - } 598 - 599 - $view->addProperty( 600 - pht('Storage Service'), 601 - $v_service); 602 - 603 - $view->addProperty(pht('Storage Path'), $repository->getLocalPath()); 604 - 605 - return $view; 606 - } 607 - 608 - private function buildStagingActions(PhabricatorRepository $repository) { 609 - $viewer = $this->getViewer(); 610 - 611 - $view = id(new PhabricatorActionListView()) 612 - ->setUser($viewer); 613 - 614 - $edit = id(new PhabricatorActionView()) 615 - ->setIcon('fa-pencil') 616 - ->setName(pht('Edit Staging')) 617 - ->setHref( 618 - $this->getRepositoryControllerURI($repository, 'edit/staging/')); 619 - $view->addAction($edit); 620 - 621 - return $view; 622 - } 623 - 624 - private function buildStagingProperties( 625 - PhabricatorRepository $repository, 626 - PhabricatorActionListView $actions) { 627 - $viewer = $this->getViewer(); 628 - 629 - $view = id(new PHUIPropertyListView()) 630 - ->setUser($viewer) 631 - ->setActionList($actions); 632 - 633 - $staging_uri = $repository->getStagingURI(); 634 - if (!$staging_uri) { 635 - $staging_uri = phutil_tag('em', array(), pht('No Staging Area')); 636 - } 637 - 638 - $view->addProperty( 639 - pht('Staging Area'), 640 - $staging_uri); 641 - 642 - return $view; 643 - } 644 - 645 - private function buildAutomationActions(PhabricatorRepository $repository) { 646 - $viewer = $this->getViewer(); 647 - 648 - $view = id(new PhabricatorActionListView()) 649 - ->setUser($viewer); 650 - 651 - $edit = id(new PhabricatorActionView()) 652 - ->setIcon('fa-pencil') 653 - ->setName(pht('Edit Automation')) 654 - ->setHref( 655 - $this->getRepositoryControllerURI($repository, 'edit/automation/')); 656 - $view->addAction($edit); 657 - 658 - $can_test = $repository->canPerformAutomation(); 659 - 660 - $test = id(new PhabricatorActionView()) 661 - ->setIcon('fa-gamepad') 662 - ->setName(pht('Test Configuration')) 663 - ->setWorkflow(true) 664 - ->setDisabled(!$can_test) 665 - ->setHref( 666 - $this->getRepositoryControllerURI( 667 - $repository, 668 - 'edit/testautomation/')); 669 - $view->addAction($test); 670 - 671 - return $view; 672 - } 673 - 674 - private function buildAutomationProperties( 675 - PhabricatorRepository $repository, 676 - PhabricatorActionListView $actions) { 677 - $viewer = $this->getViewer(); 678 - 679 - $view = id(new PHUIPropertyListView()) 680 - ->setUser($viewer) 681 - ->setActionList($actions); 682 - 683 - $blueprint_phids = $repository->getAutomationBlueprintPHIDs(); 684 - if (!$blueprint_phids) { 685 - $blueprint_view = phutil_tag('em', array(), pht('Not Configured')); 686 - } else { 687 - $blueprint_view = id(new DrydockObjectAuthorizationView()) 688 - ->setUser($viewer) 689 - ->setObjectPHID($repository->getPHID()) 690 - ->setBlueprintPHIDs($blueprint_phids); 691 - } 692 - 693 - $view->addProperty(pht('Automation'), $blueprint_view); 694 - 695 - return $view; 696 - } 697 - 698 - private function buildHostingActions(PhabricatorRepository $repository) { 699 - $user = $this->getRequest()->getUser(); 700 - 701 - $view = id(new PhabricatorActionListView()) 702 - ->setUser($user); 703 - 704 - $edit = id(new PhabricatorActionView()) 705 - ->setIcon('fa-pencil') 706 - ->setName(pht('Edit Hosting')) 707 - ->setHref( 708 - $this->getRepositoryControllerURI($repository, 'edit/hosting/')); 709 - $view->addAction($edit); 710 - 711 - if ($repository->canAllowDangerousChanges()) { 712 - if ($repository->shouldAllowDangerousChanges()) { 713 - $changes = id(new PhabricatorActionView()) 714 - ->setIcon('fa-shield') 715 - ->setName(pht('Prevent Dangerous Changes')) 716 - ->setHref( 717 - $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) 718 - ->setWorkflow(true); 719 - } else { 720 - $changes = id(new PhabricatorActionView()) 721 - ->setIcon('fa-bullseye') 722 - ->setName(pht('Allow Dangerous Changes')) 723 - ->setHref( 724 - $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) 725 - ->setWorkflow(true); 726 - } 727 - $view->addAction($changes); 728 - } 729 - 730 - return $view; 731 - } 732 - 733 - private function buildHostingProperties( 734 - PhabricatorRepository $repository, 735 - PhabricatorActionListView $actions) { 736 - 737 - $user = $this->getRequest()->getUser(); 738 - 739 - $view = id(new PHUIPropertyListView()) 740 - ->setUser($user) 741 - ->setActionList($actions); 742 - 743 - $hosting = $repository->isHosted() 744 - ? pht('Hosted on Phabricator') 745 - : pht('Hosted Elsewhere'); 746 - $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting)); 747 - 748 - $view->addProperty( 749 - pht('Serve over HTTP'), 750 - phutil_tag( 751 - 'em', 752 - array(), 753 - PhabricatorRepository::getProtocolAvailabilityName( 754 - $repository->getServeOverHTTP()))); 755 - 756 - $view->addProperty( 757 - pht('Serve over SSH'), 758 - phutil_tag( 759 - 'em', 760 - array(), 761 - PhabricatorRepository::getProtocolAvailabilityName( 762 - $repository->getServeOverSSH()))); 763 - 764 - if ($repository->canAllowDangerousChanges()) { 765 - if ($repository->shouldAllowDangerousChanges()) { 766 - $description = pht('Allowed'); 767 - } else { 768 - $description = pht('Not Allowed'); 769 - } 770 - 771 - $view->addProperty( 772 - pht('Dangerous Changes'), 773 - $description); 774 - } 775 - 776 - return $view; 777 - } 778 - 779 - private function buildRepositoryStatus( 780 - PhabricatorRepository $repository) { 781 - 782 - $viewer = $this->getViewer(); 783 - $is_cluster = $repository->getAlmanacServicePHID(); 784 - 785 - $view = new PHUIStatusListView(); 786 - 787 - $messages = id(new PhabricatorRepositoryStatusMessage()) 788 - ->loadAllWhere('repositoryID = %d', $repository->getID()); 789 - $messages = mpull($messages, null, 'getStatusType'); 790 - 791 - if ($repository->isTracked()) { 792 - $view->addItem( 793 - id(new PHUIStatusItemView()) 794 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 795 - ->setTarget(pht('Repository Active'))); 796 - } else { 797 - $view->addItem( 798 - id(new PHUIStatusItemView()) 799 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') 800 - ->setTarget(pht('Repository Inactive')) 801 - ->setNote( 802 - pht('Activate this repository to begin or resume import.'))); 803 - return $view; 804 - } 805 - 806 - $binaries = array(); 807 - $svnlook_check = false; 808 - switch ($repository->getVersionControlSystem()) { 809 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 810 - $binaries[] = 'git'; 811 - break; 812 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 813 - $binaries[] = 'svn'; 814 - break; 815 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 816 - $binaries[] = 'hg'; 817 - break; 818 - } 819 - 820 - if ($repository->isHosted()) { 821 - if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { 822 - switch ($repository->getVersionControlSystem()) { 823 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 824 - $binaries[] = 'git-http-backend'; 825 - break; 826 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 827 - $binaries[] = 'svnserve'; 828 - $binaries[] = 'svnadmin'; 829 - $binaries[] = 'svnlook'; 830 - $svnlook_check = true; 831 - break; 832 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 833 - $binaries[] = 'hg'; 834 - break; 835 - } 836 - } 837 - if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { 838 - switch ($repository->getVersionControlSystem()) { 839 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 840 - $binaries[] = 'git-receive-pack'; 841 - $binaries[] = 'git-upload-pack'; 842 - break; 843 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 844 - $binaries[] = 'svnserve'; 845 - $binaries[] = 'svnadmin'; 846 - $binaries[] = 'svnlook'; 847 - $svnlook_check = true; 848 - break; 849 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 850 - $binaries[] = 'hg'; 851 - break; 852 - } 853 - } 854 - } 855 - 856 - $binaries = array_unique($binaries); 857 - if (!$is_cluster) { 858 - // We're only checking for binaries if we aren't running with a cluster 859 - // configuration. In theory, we could check for binaries on the 860 - // repository host machine, but we'd need to make this more complicated 861 - // to do that. 862 - 863 - foreach ($binaries as $binary) { 864 - $where = Filesystem::resolveBinary($binary); 865 - if (!$where) { 866 - $view->addItem( 867 - id(new PHUIStatusItemView()) 868 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 869 - ->setTarget( 870 - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) 871 - ->setNote(pht( 872 - "Unable to find this binary in the webserver's PATH. You may ". 873 - "need to configure %s.", 874 - $this->getEnvConfigLink()))); 875 - } else { 876 - $view->addItem( 877 - id(new PHUIStatusItemView()) 878 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 879 - ->setTarget( 880 - pht('Found Binary %s', phutil_tag('tt', array(), $binary))) 881 - ->setNote(phutil_tag('tt', array(), $where))); 882 - } 883 - } 884 - 885 - // This gets checked generically above. However, for svn commit hooks, we 886 - // need this to be in environment.append-paths because subversion strips 887 - // PATH. 888 - if ($svnlook_check) { 889 - $where = Filesystem::resolveBinary('svnlook'); 890 - if ($where) { 891 - $path = substr($where, 0, strlen($where) - strlen('svnlook')); 892 - $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); 893 - $in_path = false; 894 - foreach ($dirs as $dir) { 895 - if (Filesystem::isDescendant($path, $dir)) { 896 - $in_path = true; 897 - break; 898 - } 899 - } 900 - if (!$in_path) { 901 - $view->addItem( 902 - id(new PHUIStatusItemView()) 903 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 904 - ->setTarget( 905 - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) 906 - ->setNote(pht( 907 - 'Unable to find this binary in `%s`. '. 908 - 'You need to configure %s and include %s.', 909 - 'environment.append-paths', 910 - $this->getEnvConfigLink(), 911 - $path))); 912 - } 913 - } 914 - } 915 - } 916 - 917 - $doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd'); 918 - 919 - $daemon_instructions = pht( 920 - 'Use %s to start daemons. See %s.', 921 - phutil_tag('tt', array(), 'bin/phd start'), 922 - phutil_tag( 923 - 'a', 924 - array( 925 - 'href' => $doc_href, 926 - ), 927 - pht('Managing Daemons with phd'))); 928 - 929 - 930 - $pull_daemon = id(new PhabricatorDaemonLogQuery()) 931 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 932 - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) 933 - ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) 934 - ->setLimit(1) 935 - ->execute(); 936 - 937 - if ($pull_daemon) { 938 - 939 - // TODO: In a cluster environment, we need a daemon on this repository's 940 - // host, specifically, and we aren't checking for that right now. This 941 - // is a reasonable proxy for things being more-or-less correctly set up, 942 - // though. 943 - 944 - $view->addItem( 945 - id(new PHUIStatusItemView()) 946 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 947 - ->setTarget(pht('Pull Daemon Running'))); 948 - } else { 949 - $view->addItem( 950 - id(new PHUIStatusItemView()) 951 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 952 - ->setTarget(pht('Pull Daemon Not Running')) 953 - ->setNote($daemon_instructions)); 954 - } 955 - 956 - 957 - $task_daemon = id(new PhabricatorDaemonLogQuery()) 958 - ->setViewer(PhabricatorUser::getOmnipotentUser()) 959 - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) 960 - ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) 961 - ->setLimit(1) 962 - ->execute(); 963 - if ($task_daemon) { 964 - $view->addItem( 965 - id(new PHUIStatusItemView()) 966 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 967 - ->setTarget(pht('Task Daemon Running'))); 968 - } else { 969 - $view->addItem( 970 - id(new PHUIStatusItemView()) 971 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 972 - ->setTarget(pht('Task Daemon Not Running')) 973 - ->setNote($daemon_instructions)); 974 - } 975 - 976 - 977 - if ($is_cluster) { 978 - // Just omit this status check for now in cluster environments. We 979 - // could make a service call and pull it from the repository host 980 - // eventually. 981 - } else if ($repository->usesLocalWorkingCopy()) { 982 - $local_parent = dirname($repository->getLocalPath()); 983 - if (Filesystem::pathExists($local_parent)) { 984 - $view->addItem( 985 - id(new PHUIStatusItemView()) 986 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 987 - ->setTarget(pht('Storage Directory OK')) 988 - ->setNote(phutil_tag('tt', array(), $local_parent))); 989 - } else { 990 - $view->addItem( 991 - id(new PHUIStatusItemView()) 992 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 993 - ->setTarget(pht('No Storage Directory')) 994 - ->setNote( 995 - pht( 996 - 'Storage directory %s does not exist, or is not readable by '. 997 - 'the webserver. Create this directory or make it readable.', 998 - phutil_tag('tt', array(), $local_parent)))); 999 - return $view; 1000 - } 1001 - 1002 - $local_path = $repository->getLocalPath(); 1003 - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); 1004 - if ($message) { 1005 - switch ($message->getStatusCode()) { 1006 - case PhabricatorRepositoryStatusMessage::CODE_ERROR: 1007 - $view->addItem( 1008 - id(new PHUIStatusItemView()) 1009 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 1010 - ->setTarget(pht('Initialization Error')) 1011 - ->setNote($message->getParameter('message'))); 1012 - return $view; 1013 - case PhabricatorRepositoryStatusMessage::CODE_OKAY: 1014 - if (Filesystem::pathExists($local_path)) { 1015 - $view->addItem( 1016 - id(new PHUIStatusItemView()) 1017 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 1018 - ->setTarget(pht('Working Copy OK')) 1019 - ->setNote(phutil_tag('tt', array(), $local_path))); 1020 - } else { 1021 - $view->addItem( 1022 - id(new PHUIStatusItemView()) 1023 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 1024 - ->setTarget(pht('Working Copy Error')) 1025 - ->setNote( 1026 - pht( 1027 - 'Working copy %s has been deleted, or is not '. 1028 - 'readable by the webserver. Make this directory '. 1029 - 'readable. If it has been deleted, the daemons should '. 1030 - 'restore it automatically.', 1031 - phutil_tag('tt', array(), $local_path)))); 1032 - return $view; 1033 - } 1034 - break; 1035 - case PhabricatorRepositoryStatusMessage::CODE_WORKING: 1036 - $view->addItem( 1037 - id(new PHUIStatusItemView()) 1038 - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') 1039 - ->setTarget(pht('Initializing Working Copy')) 1040 - ->setNote(pht('Daemons are initializing the working copy.'))); 1041 - return $view; 1042 - default: 1043 - $view->addItem( 1044 - id(new PHUIStatusItemView()) 1045 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 1046 - ->setTarget(pht('Unknown Init Status')) 1047 - ->setNote($message->getStatusCode())); 1048 - return $view; 1049 - } 1050 - } else { 1051 - $view->addItem( 1052 - id(new PHUIStatusItemView()) 1053 - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') 1054 - ->setTarget(pht('No Working Copy Yet')) 1055 - ->setNote( 1056 - pht('Waiting for daemons to build a working copy.'))); 1057 - return $view; 1058 - } 1059 - } 1060 - 1061 - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); 1062 - if ($message) { 1063 - switch ($message->getStatusCode()) { 1064 - case PhabricatorRepositoryStatusMessage::CODE_ERROR: 1065 - $message = $message->getParameter('message'); 1066 - 1067 - $suggestion = null; 1068 - if (preg_match('/Permission denied \(publickey\)./', $message)) { 1069 - $suggestion = pht( 1070 - 'Public Key Error: This error usually indicates that the '. 1071 - 'keypair you have configured does not have permission to '. 1072 - 'access the repository.'); 1073 - } 1074 - 1075 - $message = phutil_escape_html_newlines($message); 1076 - 1077 - if ($suggestion !== null) { 1078 - $message = array( 1079 - phutil_tag('strong', array(), $suggestion), 1080 - phutil_tag('br'), 1081 - phutil_tag('br'), 1082 - phutil_tag('em', array(), pht('Raw Error')), 1083 - phutil_tag('br'), 1084 - $message, 1085 - ); 1086 - } 1087 - 1088 - $view->addItem( 1089 - id(new PHUIStatusItemView()) 1090 - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') 1091 - ->setTarget(pht('Update Error')) 1092 - ->setNote($message)); 1093 - return $view; 1094 - case PhabricatorRepositoryStatusMessage::CODE_OKAY: 1095 - $ago = (PhabricatorTime::getNow() - $message->getEpoch()); 1096 - $view->addItem( 1097 - id(new PHUIStatusItemView()) 1098 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 1099 - ->setTarget(pht('Updates OK')) 1100 - ->setNote( 1101 - pht( 1102 - 'Last updated %s (%s ago).', 1103 - phabricator_datetime($message->getEpoch(), $viewer), 1104 - phutil_format_relative_time_detailed($ago)))); 1105 - break; 1106 - } 1107 - } else { 1108 - $view->addItem( 1109 - id(new PHUIStatusItemView()) 1110 - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') 1111 - ->setTarget(pht('Waiting For Update')) 1112 - ->setNote( 1113 - pht('Waiting for daemons to read updates.'))); 1114 - } 1115 - 1116 - if ($repository->isImporting()) { 1117 - $ratio = $repository->loadImportProgress(); 1118 - $percentage = sprintf('%.2f%%', 100 * $ratio); 1119 - 1120 - $view->addItem( 1121 - id(new PHUIStatusItemView()) 1122 - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') 1123 - ->setTarget(pht('Importing')) 1124 - ->setNote( 1125 - pht('%s Complete', $percentage))); 1126 - } else { 1127 - $view->addItem( 1128 - id(new PHUIStatusItemView()) 1129 - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') 1130 - ->setTarget(pht('Fully Imported'))); 1131 - } 1132 - 1133 - if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { 1134 - $view->addItem( 1135 - id(new PHUIStatusItemView()) 1136 - ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') 1137 - ->setTarget(pht('Prioritized')) 1138 - ->setNote(pht('This repository will be updated soon!'))); 1139 - } 1140 - 1141 - return $view; 1142 - } 1143 - 1144 - private function buildRepositoryUpdateInterval( 1145 - PhabricatorRepository $repository) { 1146 - 1147 - $smart_wait = $repository->loadUpdateInterval(); 1148 - 1149 - $doc_href = PhabricatorEnv::getDoclink( 1150 - 'Diffusion User Guide: Repository Updates'); 1151 - 1152 - return array( 1153 - phutil_format_relative_time_detailed($smart_wait), 1154 - " \xC2\xB7 ", 1155 - phutil_tag( 1156 - 'a', 1157 - array( 1158 - 'href' => $doc_href, 1159 - 'target' => '_blank', 1160 - ), 1161 - pht('Learn More')), 1162 - ); 1163 - } 1164 - 1165 - private function buildSymbolsActions(PhabricatorRepository $repository) { 1166 - $viewer = $this->getViewer(); 1167 - 1168 - $view = id(new PhabricatorActionListView()) 1169 - ->setUser($viewer); 1170 - 1171 - $edit = id(new PhabricatorActionView()) 1172 - ->setIcon('fa-pencil') 1173 - ->setName(pht('Edit Symbols')) 1174 - ->setHref( 1175 - $this->getRepositoryControllerURI($repository, 'edit/symbol/')); 1176 - $view->addAction($edit); 1177 - 1178 - return $view; 1179 - } 1180 - 1181 - private function buildSymbolsProperties( 1182 - PhabricatorRepository $repository, 1183 - PhabricatorActionListView $actions) { 1184 - 1185 - $viewer = $this->getViewer(); 1186 - 1187 - $view = id(new PHUIPropertyListView()) 1188 - ->setUser($viewer) 1189 - ->setActionList($actions); 1190 - 1191 - $languages = $repository->getSymbolLanguages(); 1192 - 1193 - if ($languages) { 1194 - $languages = implode(', ', $languages); 1195 - } else { 1196 - $languages = phutil_tag('em', array(), pht('Any')); 1197 - } 1198 - $view->addProperty(pht('Languages'), $languages); 1199 - 1200 - $sources = $repository->getSymbolSources(); 1201 - if ($sources) { 1202 - $handles = $viewer->loadHandles($sources); 1203 - $sources = $handles->renderList(); 1204 - } else { 1205 - $sources = phutil_tag('em', array(), pht('This Repository Only')); 1206 - } 1207 - $view->addProperty(pht('Use Symbols From'), $sources); 1208 - return $view; 1209 - } 1210 - 1211 - private function getEnvConfigLink() { 1212 - $config_href = '/config/edit/environment.append-paths/'; 1213 - return phutil_tag( 1214 - 'a', 1215 - array( 1216 - 'href' => $config_href, 1217 - ), 1218 - 'environment.append-paths'); 1219 - } 1220 - 1221 - }
-91
src/applications/diffusion/controller/DiffusionRepositoryEditStagingController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditStagingController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - 17 - if (!$repository->supportsStaging()) { 18 - return new Aphront404Response(); 19 - } 20 - 21 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 22 - 23 - $v_area = $repository->getHumanReadableDetail('staging-uri'); 24 - if ($request->isFormPost()) { 25 - $v_area = $request->getStr('area'); 26 - 27 - $xactions = array(); 28 - $template = id(new PhabricatorRepositoryTransaction()); 29 - 30 - $type_encoding = PhabricatorRepositoryTransaction::TYPE_STAGING_URI; 31 - 32 - $xactions[] = id(clone $template) 33 - ->setTransactionType($type_encoding) 34 - ->setNewValue($v_area); 35 - 36 - id(new PhabricatorRepositoryEditor()) 37 - ->setContinueOnNoEffect(true) 38 - ->setContentSourceFromRequest($request) 39 - ->setActor($viewer) 40 - ->applyTransactions($repository, $xactions); 41 - 42 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 43 - } 44 - 45 - $crumbs = $this->buildApplicationCrumbs(); 46 - $crumbs->addTextCrumb(pht('Edit Staging')); 47 - 48 - $title = pht('Edit Staging (%s)', $repository->getName()); 49 - $header = id(new PHUIHeaderView()) 50 - ->setHeader($title) 51 - ->setHeaderIcon('fa-pencil'); 52 - 53 - $form = id(new AphrontFormView()) 54 - ->setUser($viewer) 55 - ->appendRemarkupInstructions( 56 - pht( 57 - "To make it easier to run integration tests and builds on code ". 58 - "under review, you can configure a **Staging Area**. When `arc` ". 59 - "creates a diff, it will push a copy of the changes to the ". 60 - "configured staging area with a corresponding tag.". 61 - "\n\n". 62 - "IMPORTANT: This feature is new, experimental, and not supported. ". 63 - "Use it at your own risk.")) 64 - ->appendChild( 65 - id(new AphrontFormTextControl()) 66 - ->setLabel(pht('Staging Area URI')) 67 - ->setName('area') 68 - ->setValue($v_area)) 69 - ->appendChild( 70 - id(new AphrontFormSubmitControl()) 71 - ->setValue(pht('Save')) 72 - ->addCancelButton($edit_uri)); 73 - 74 - $form_box = id(new PHUIObjectBoxView()) 75 - ->setHeaderText(pht('Staging')) 76 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 77 - ->setForm($form); 78 - 79 - $view = id(new PHUITwoColumnView()) 80 - ->setHeader($header) 81 - ->setFooter(array( 82 - $form_box, 83 - )); 84 - 85 - return $this->newPage() 86 - ->setTitle($title) 87 - ->setCrumbs($crumbs) 88 - ->appendChild($view); 89 - } 90 - 91 - }
-76
src/applications/diffusion/controller/DiffusionRepositoryEditStorageController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditStorageController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 17 - 18 - $v_local = $repository->getLocalPath(); 19 - $errors = array(); 20 - 21 - $crumbs = $this->buildApplicationCrumbs(); 22 - $crumbs->addTextCrumb(pht('Edit Storage')); 23 - 24 - $title = pht('Edit %s', $repository->getName()); 25 - $header = id(new PHUIHeaderView()) 26 - ->setHeader($title) 27 - ->setHeaderIcon('fa-pencil'); 28 - 29 - $service_phid = $repository->getAlmanacServicePHID(); 30 - if ($service_phid) { 31 - $handles = $this->loadViewerHandles(array($service_phid)); 32 - $v_service = $handles[$service_phid]->renderLink(); 33 - } else { 34 - $v_service = phutil_tag( 35 - 'em', 36 - array(), 37 - pht('Local')); 38 - } 39 - 40 - $form = id(new AphrontFormView()) 41 - ->setUser($viewer) 42 - ->appendChild( 43 - id(new AphrontFormMarkupControl()) 44 - ->setLabel(pht('Storage Service')) 45 - ->setValue($v_service)) 46 - ->appendChild( 47 - id(new AphrontFormMarkupControl()) 48 - ->setName('local') 49 - ->setLabel(pht('Storage Path')) 50 - ->setValue($v_local)) 51 - ->appendRemarkupInstructions( 52 - pht( 53 - "You can not adjust the local path for this repository from the ". 54 - 'web interface.')) 55 - ->appendChild( 56 - id(new AphrontFormSubmitControl()) 57 - ->addCancelButton($edit_uri, pht('Done'))); 58 - 59 - $form_box = id(new PHUIObjectBoxView()) 60 - ->setHeaderText(pht('Storage')) 61 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 62 - ->setForm($form); 63 - 64 - $view = id(new PHUITwoColumnView()) 65 - ->setHeader($header) 66 - ->setFooter(array( 67 - $form_box, 68 - )); 69 - 70 - return $this->newPage() 71 - ->setTitle($title) 72 - ->setCrumbs($crumbs) 73 - ->appendChild($view); 74 - } 75 - 76 - }
-118
src/applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php
··· 1 - <?php 2 - 3 - final class DiffusionRepositoryEditSubversionController 4 - extends DiffusionRepositoryEditController { 5 - 6 - public function handleRequest(AphrontRequest $request) { 7 - $response = $this->loadDiffusionContextForEdit(); 8 - if ($response) { 9 - return $response; 10 - } 11 - 12 - $viewer = $this->getViewer(); 13 - $drequest = $this->getDiffusionRequest(); 14 - $repository = $drequest->getRepository(); 15 - 16 - switch ($repository->getVersionControlSystem()) { 17 - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 18 - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: 19 - throw new Exception( 20 - pht('Git and Mercurial do not support editing SVN properties!')); 21 - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: 22 - break; 23 - default: 24 - throw new Exception( 25 - pht('Repository has unknown version control system!')); 26 - } 27 - 28 - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); 29 - 30 - $v_subpath = $repository->getHumanReadableDetail('svn-subpath'); 31 - $v_uuid = $repository->getUUID(); 32 - 33 - if ($request->isFormPost()) { 34 - $v_subpath = $request->getStr('subpath'); 35 - $v_uuid = $request->getStr('uuid'); 36 - 37 - $xactions = array(); 38 - $template = id(new PhabricatorRepositoryTransaction()); 39 - 40 - $type_subpath = PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH; 41 - $type_uuid = PhabricatorRepositoryTransaction::TYPE_UUID; 42 - 43 - $xactions[] = id(clone $template) 44 - ->setTransactionType($type_subpath) 45 - ->setNewValue($v_subpath); 46 - 47 - $xactions[] = id(clone $template) 48 - ->setTransactionType($type_uuid) 49 - ->setNewValue($v_uuid); 50 - 51 - id(new PhabricatorRepositoryEditor()) 52 - ->setContinueOnNoEffect(true) 53 - ->setContentSourceFromRequest($request) 54 - ->setActor($viewer) 55 - ->applyTransactions($repository, $xactions); 56 - 57 - return id(new AphrontRedirectResponse())->setURI($edit_uri); 58 - } 59 - 60 - $content = array(); 61 - 62 - $crumbs = $this->buildApplicationCrumbs(); 63 - $crumbs->addTextCrumb(pht('Edit Subversion Info')); 64 - 65 - $title = pht('Edit Subversion Info (%s)', $repository->getName()); 66 - $header = id(new PHUIHeaderView()) 67 - ->setHeader($title) 68 - ->setHeaderIcon('fa-pencil'); 69 - 70 - $policies = id(new PhabricatorPolicyQuery()) 71 - ->setViewer($viewer) 72 - ->setObject($repository) 73 - ->execute(); 74 - 75 - $form = id(new AphrontFormView()) 76 - ->setUser($viewer) 77 - ->appendRemarkupInstructions( 78 - pht( 79 - "You can set the **Repository UUID**, which will help Phabriactor ". 80 - "provide better context in some cases. You can find the UUID of a ". 81 - "repository by running `%s`.\n\n". 82 - "If you want to import only part of a repository, like `trunk/`, ". 83 - "you can set a path in **Import Only**. Phabricator will ignore ". 84 - "commits which do not affect this path.", 85 - 'svn info')) 86 - ->appendChild( 87 - id(new AphrontFormTextControl()) 88 - ->setName('uuid') 89 - ->setLabel(pht('Repository UUID')) 90 - ->setValue($v_uuid)) 91 - ->appendChild( 92 - id(new AphrontFormTextControl()) 93 - ->setName('subpath') 94 - ->setLabel(pht('Import Only')) 95 - ->setValue($v_subpath)) 96 - ->appendChild( 97 - id(new AphrontFormSubmitControl()) 98 - ->setValue(pht('Save Subversion Info')) 99 - ->addCancelButton($edit_uri)); 100 - 101 - $form_box = id(new PHUIObjectBoxView()) 102 - ->setHeaderText(pht('Subversion')) 103 - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) 104 - ->setForm($form); 105 - 106 - $view = id(new PHUITwoColumnView()) 107 - ->setHeader($header) 108 - ->setFooter(array( 109 - $form_box, 110 - )); 111 - 112 - return $this->newPage() 113 - ->setTitle($title) 114 - ->setCrumbs($crumbs) 115 - ->appendChild($view); 116 - } 117 - 118 - }
+3 -10
src/applications/diffusion/controller/DiffusionRepositoryListController.php
··· 15 15 protected function buildApplicationCrumbs() { 16 16 $crumbs = parent::buildApplicationCrumbs(); 17 17 18 - $can_create = $this->hasApplicationCapability( 19 - DiffusionCreateRepositoriesCapability::CAPABILITY); 20 - 21 - $crumbs->addAction( 22 - id(new PHUIListItemView()) 23 - ->setName(pht('New Repository')) 24 - ->setHref($this->getApplicationURI('new/')) 25 - ->setDisabled(!$can_create) 26 - ->setWorkflow(!$can_create) 27 - ->setIcon('fa-plus-square')); 18 + id(new DiffusionRepositoryEditEngine()) 19 + ->setViewer($this->getViewer()) 20 + ->addActionToCrumbs($crumbs); 28 21 29 22 return $crumbs; 30 23 }
+18 -14
src/applications/diffusion/controller/DiffusionServeController.php
··· 219 219 $repository = id(new PhabricatorRepositoryQuery()) 220 220 ->setViewer($viewer) 221 221 ->withIdentifiers(array($identifier)) 222 + ->needURIs(true) 222 223 ->executeOne(); 223 224 if (!$repository) { 224 225 return new PhabricatorVCSResponse( ··· 266 267 // token from SSH. If they're using HTTP username + password auth, they 267 268 // have to obey the normal HTTP rules. 268 269 } else { 269 - switch ($repository->getServeOverHTTP()) { 270 - case PhabricatorRepository::SERVE_READONLY: 271 - if ($is_push) { 272 - return new PhabricatorVCSResponse( 273 - 403, 274 - pht('This repository is read-only over HTTP.')); 275 - } 276 - break; 277 - case PhabricatorRepository::SERVE_READWRITE: 278 - // We'll check for push capability below. 279 - break; 280 - case PhabricatorRepository::SERVE_OFF: 281 - default: 270 + if ($request->isHTTPS()) { 271 + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; 272 + } else { 273 + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; 274 + } 275 + 276 + if (!$repository->canServeProtocol($protocol, false)) { 277 + return new PhabricatorVCSResponse( 278 + 403, 279 + pht('This repository is not available over HTTP.')); 280 + } 281 + 282 + if ($is_push) { 283 + $can_write = $repository->canServeProtocol($protocol, true); 284 + if (!$can_write) { 282 285 return new PhabricatorVCSResponse( 283 286 403, 284 - pht('This repository is not available over HTTP.')); 287 + pht('This repository is read-only over HTTP.')); 288 + } 285 289 } 286 290 } 287 291
+40
src/applications/diffusion/editor/DiffusionURIEditor.php
··· 410 410 return $errors; 411 411 } 412 412 413 + protected function applyFinalEffects( 414 + PhabricatorLiskDAO $object, 415 + array $xactions) { 416 + 417 + // Synchronize the repository state based on the presence of an "Observe" 418 + // URI. 419 + $repository = $object->getRepository(); 420 + 421 + $uris = id(new PhabricatorRepositoryURIQuery()) 422 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 423 + ->withRepositories(array($repository)) 424 + ->execute(); 425 + 426 + $observe_uri = null; 427 + foreach ($uris as $uri) { 428 + if ($uri->getIoType() != PhabricatorRepositoryURI::IO_OBSERVE) { 429 + continue; 430 + } 431 + 432 + $observe_uri = $uri; 433 + break; 434 + } 435 + 436 + if ($observe_uri) { 437 + $repository 438 + ->setHosted(false) 439 + ->setDetail('remote-uri', (string)$observe_uri->getEffectiveURI()) 440 + ->setCredentialPHID($observe_uri->getCredentialPHID()); 441 + } else { 442 + $repository 443 + ->setHosted(true) 444 + ->setDetail('remote-uri', null) 445 + ->setCredentialPHID(null); 446 + } 447 + 448 + $repository->save(); 449 + 450 + return $xactions; 451 + } 452 + 413 453 }
+1 -1
src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php
··· 136 136 137 137 $repository = $this->getRepository(); 138 138 $id = $repository->getID(); 139 - return "/diffusion/editpro/{$id}/page/{$page}/"; 139 + return "/diffusion/edit/{$id}/page/{$page}/"; 140 140 } 141 141 142 142
+12 -2
src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php
··· 135 135 } 136 136 137 137 if ($repository->isHosted()) { 138 - if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { 138 + $proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; 139 + $proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; 140 + $can_http = $repository->canServeProtocol($proto_http, false) || 141 + $repository->canServeProtocol($proto_https, false); 142 + 143 + if ($can_http) { 139 144 switch ($repository->getVersionControlSystem()) { 140 145 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 141 146 $binaries[] = 'git-http-backend'; ··· 151 156 break; 152 157 } 153 158 } 154 - if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { 159 + 160 + 161 + $proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; 162 + $can_ssh = $repository->canServeProtocol($proto_ssh, false); 163 + 164 + if ($can_ssh) { 155 165 switch ($repository->getVersionControlSystem()) { 156 166 case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: 157 167 $binaries[] = 'git-receive-pack';
+27 -40
src/applications/diffusion/ssh/DiffusionSSHWorkflow.php
··· 185 185 $repository = id(new PhabricatorRepositoryQuery()) 186 186 ->setViewer($viewer) 187 187 ->withIdentifiers(array($identifier)) 188 + ->needURIs(true) 188 189 ->executeOne(); 189 190 if (!$repository) { 190 191 throw new Exception( 191 192 pht('No repository "%s" exists!', $identifier)); 192 193 } 193 194 194 - switch ($repository->getServeOverSSH()) { 195 - case PhabricatorRepository::SERVE_READONLY: 196 - case PhabricatorRepository::SERVE_READWRITE: 197 - // If we have read or read/write access, proceed for now. We will 198 - // check write access when the user actually issues a write command. 199 - break; 200 - case PhabricatorRepository::SERVE_OFF: 201 - default: 202 - throw new Exception( 203 - pht( 204 - 'This repository ("%s") is not available over SSH.', 205 - $repository->getDisplayName())); 195 + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; 196 + if (!$repository->canServeProtocol($protocol, false)) { 197 + throw new Exception( 198 + pht( 199 + 'This repository ("%s") is not available over SSH.', 200 + $repository->getDisplayName())); 206 201 } 207 202 208 203 return $repository; ··· 224 219 'user account.')); 225 220 } 226 221 227 - switch ($repository->getServeOverSSH()) { 228 - case PhabricatorRepository::SERVE_READONLY: 229 - if ($protocol_command !== null) { 230 - throw new Exception( 231 - pht( 232 - 'This repository is read-only over SSH (tried to execute '. 233 - 'protocol command "%s").', 234 - $protocol_command)); 235 - } else { 236 - throw new Exception( 237 - pht('This repository is read-only over SSH.')); 238 - } 239 - break; 240 - case PhabricatorRepository::SERVE_READWRITE: 241 - $can_push = PhabricatorPolicyFilter::hasCapability( 242 - $viewer, 243 - $repository, 244 - DiffusionPushCapability::CAPABILITY); 245 - if (!$can_push) { 246 - throw new Exception( 247 - pht('You do not have permission to push to this repository.')); 248 - } 249 - break; 250 - case PhabricatorRepository::SERVE_OFF: 251 - default: 252 - // This shouldn't be reachable because we don't get this far if the 253 - // repository isn't enabled, but kick them out anyway. 222 + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; 223 + if ($repository->canServeProtocol($protocol, true)) { 224 + $can_push = PhabricatorPolicyFilter::hasCapability( 225 + $viewer, 226 + $repository, 227 + DiffusionPushCapability::CAPABILITY); 228 + if (!$can_push) { 229 + throw new Exception( 230 + pht('You do not have permission to push to this repository.')); 231 + } 232 + } else { 233 + if ($protocol_command !== null) { 234 + throw new Exception( 235 + pht( 236 + 'This repository is read-only over SSH (tried to execute '. 237 + 'protocol command "%s").', 238 + $protocol_command)); 239 + } else { 254 240 throw new Exception( 255 - pht('This repository is not available over SSH.')); 241 + pht('This repository is read-only over SSH.')); 242 + } 256 243 } 257 244 258 245 $this->hasWriteAccess = true;
+11 -112
src/applications/repository/editor/PhabricatorRepositoryEditor.php
··· 26 26 $types[] = PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH; 27 27 $types[] = PhabricatorRepositoryTransaction::TYPE_NOTIFY; 28 28 $types[] = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE; 29 - $types[] = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI; 30 - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN; 31 - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_KEY; 32 - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE; 33 - $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN; 34 - $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_PASS; 35 - $types[] = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH; 36 - $types[] = PhabricatorRepositoryTransaction::TYPE_HOSTING; 37 - $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; 38 - $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; 39 29 $types[] = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; 40 - $types[] = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL; 41 30 $types[] = PhabricatorRepositoryTransaction::TYPE_DANGEROUS; 42 31 $types[] = PhabricatorRepositoryTransaction::TYPE_SLUG; 43 32 $types[] = PhabricatorRepositoryTransaction::TYPE_SERVICE; ··· 83 72 return (int)!$object->getDetail('herald-disabled'); 84 73 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: 85 74 return (int)!$object->getDetail('disable-autoclose'); 86 - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: 87 - return $object->getDetail('remote-uri'); 88 - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: 89 - return $object->getLocalPath(); 90 - case PhabricatorRepositoryTransaction::TYPE_HOSTING: 91 - return $object->isHosted(); 92 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: 93 - return $object->getServeOverHTTP(); 94 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: 95 - return $object->getServeOverSSH(); 96 75 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 97 76 return $object->getPushPolicy(); 98 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 99 - return $object->getCredentialPHID(); 100 77 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 101 78 return $object->shouldAllowDangerousChanges(); 102 79 case PhabricatorRepositoryTransaction::TYPE_SLUG: ··· 130 107 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: 131 108 case PhabricatorRepositoryTransaction::TYPE_UUID: 132 109 case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: 133 - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: 134 - case PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN: 135 - case PhabricatorRepositoryTransaction::TYPE_SSH_KEY: 136 - case PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE: 137 - case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN: 138 - case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS: 139 - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: 140 110 case PhabricatorRepositoryTransaction::TYPE_VCS: 141 - case PhabricatorRepositoryTransaction::TYPE_HOSTING: 142 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: 143 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: 144 111 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 145 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 146 112 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 147 113 case PhabricatorRepositoryTransaction::TYPE_SERVICE: 148 114 case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE: ··· 205 171 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: 206 172 $object->setDetail('disable-autoclose', (int)!$xaction->getNewValue()); 207 173 break; 208 - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: 209 - $object->setDetail('remote-uri', $xaction->getNewValue()); 210 - break; 211 - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: 212 - $object->setLocalPath($xaction->getNewValue()); 213 - break; 214 - case PhabricatorRepositoryTransaction::TYPE_HOSTING: 215 - return $object->setHosted($xaction->getNewValue()); 216 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: 217 - return $object->setServeOverHTTP($xaction->getNewValue()); 218 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: 219 - return $object->setServeOverSSH($xaction->getNewValue()); 220 174 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 221 175 return $object->setPushPolicy($xaction->getNewValue()); 222 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 223 - return $object->setCredentialPHID($xaction->getNewValue()); 224 176 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 225 177 $object->setDetail('allow-dangerous-changes', $xaction->getNewValue()); 226 178 return; ··· 258 210 PhabricatorApplicationTransaction $xaction) { 259 211 260 212 switch ($xaction->getTransactionType()) { 261 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 262 - // Adjust the object <-> credential edge for this repository. 263 - 264 - $old_phid = $xaction->getOldValue(); 265 - $new_phid = $xaction->getNewValue(); 266 - 267 - $editor = new PhabricatorEdgeEditor(); 268 - 269 - $edge_type = PhabricatorObjectUsesCredentialsEdgeType::EDGECONST; 270 - $src_phid = $object->getPHID(); 271 - 272 - if ($old_phid) { 273 - $editor->removeEdge($src_phid, $edge_type, $old_phid); 274 - } 275 - 276 - if ($new_phid) { 277 - $editor->addEdge($src_phid, $edge_type, $new_phid); 278 - } 279 - 280 - $editor->save(); 281 - break; 282 213 case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: 283 214 DrydockAuthorization::applyAuthorizationChanges( 284 215 $this->getActor(), ··· 304 235 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: 305 236 case PhabricatorRepositoryTransaction::TYPE_UUID: 306 237 case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: 307 - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: 308 - case PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN: 309 - case PhabricatorRepositoryTransaction::TYPE_SSH_KEY: 310 - case PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE: 311 - case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN: 312 - case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS: 313 - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: 314 238 case PhabricatorRepositoryTransaction::TYPE_VCS: 315 239 case PhabricatorRepositoryTransaction::TYPE_NOTIFY: 316 240 case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: 317 - case PhabricatorRepositoryTransaction::TYPE_HOSTING: 318 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: 319 - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: 320 241 case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: 321 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 322 242 case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: 323 243 case PhabricatorRepositoryTransaction::TYPE_SLUG: 324 244 case PhabricatorRepositoryTransaction::TYPE_SERVICE: ··· 384 304 break; 385 305 } 386 306 } 387 - } 388 - } 389 - break; 390 - 391 - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: 392 - foreach ($xactions as $xaction) { 393 - $new_uri = $xaction->getNewValue(); 394 - try { 395 - PhabricatorRepository::assertValidRemoteURI($new_uri); 396 - } catch (Exception $ex) { 397 - $errors[] = new PhabricatorApplicationTransactionValidationError( 398 - $type, 399 - pht('Invalid'), 400 - $ex->getMessage(), 401 - $xaction); 402 - } 403 - } 404 - break; 405 - 406 - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: 407 - $ok = PassphraseCredentialControl::validateTransactions( 408 - $this->getActor(), 409 - $xactions); 410 - if (!$ok) { 411 - foreach ($xactions as $xaction) { 412 - $errors[] = new PhabricatorApplicationTransactionValidationError( 413 - $type, 414 - pht('Invalid'), 415 - pht( 416 - 'The selected credential does not exist, or you do not have '. 417 - 'permission to use it.'), 418 - $xaction); 419 307 } 420 308 } 421 309 break; ··· 721 609 } 722 610 723 611 if ($this->getIsNewObject()) { 612 + // The default state of repositories is to be hosted, if they are 613 + // enabled without configuring any "Observe" URIs. 614 + $object->setHosted(true); 615 + $object->save(); 616 + 617 + // Create this repository's builtin URIs. 618 + $builtin_uris = $object->newBuiltinURIs(); 619 + foreach ($builtin_uris as $uri) { 620 + $uri->save(); 621 + } 622 + 724 623 id(new DiffusionRepositoryClusterEngine()) 725 624 ->setViewer($this->getActor()) 726 625 ->setRepository($object)
+1
src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php
··· 12 12 13 13 $query = id(new PhabricatorRepositoryQuery()) 14 14 ->setViewer($this->getViewer()) 15 + ->needURIs(true) 15 16 ->withIdentifiers($identifiers); 16 17 17 18 $query->execute();
+74 -154
src/applications/repository/storage/PhabricatorRepository.php
··· 35 35 const TABLE_PARENTS = 'repository_parents'; 36 36 const TABLE_COVERAGE = 'repository_coverage'; 37 37 38 - const SERVE_OFF = 'off'; 39 - const SERVE_READONLY = 'readonly'; 40 - const SERVE_READWRITE = 'readwrite'; 41 - 42 38 const BECAUSE_REPOSITORY_IMPORTING = 'auto/importing'; 43 39 const BECAUSE_AUTOCLOSE_DISABLED = 'auto/disabled'; 44 40 const BECAUSE_NOT_ON_AUTOCLOSE_BRANCH = 'auto/nobranch'; ··· 1201 1197 * @task uri 1202 1198 */ 1203 1199 public function getPublicCloneURI() { 1204 - $uri = $this->getCloneURIObject(); 1205 - 1206 - // Make sure we don't leak anything if this repo is using HTTP Basic Auth 1207 - // with the credentials in the URI or something zany like that. 1208 - 1209 - // If repository is not accessed over SSH we remove both username and 1210 - // password. 1211 - if (!$this->isHosted()) { 1212 - if (!$this->shouldUseSSH()) { 1213 - $uri->setUser(null); 1214 - 1215 - // This might be a Git URI or a normal URI. If it's Git, there's no 1216 - // password support. 1217 - if ($uri instanceof PhutilURI) { 1218 - $uri->setPass(null); 1219 - } 1220 - } 1221 - } 1222 - 1223 - return (string)$uri; 1200 + return (string)$this->getCloneURIObject(); 1224 1201 } 1225 1202 1226 1203 ··· 1303 1280 } 1304 1281 } 1305 1282 1306 - // Choose the best URI: pick a read/write URI over a URI which is not 1307 - // read/write, and SSH over HTTP. 1308 - 1309 - $serve_ssh = $this->getServeOverSSH(); 1310 - $serve_http = $this->getServeOverHTTP(); 1311 - 1312 - if ($serve_ssh === self::SERVE_READWRITE) { 1313 - return $this->getSSHCloneURIObject(); 1314 - } else if ($serve_http === self::SERVE_READWRITE) { 1315 - return $this->getHTTPCloneURIObject(); 1316 - } else if ($serve_ssh !== self::SERVE_OFF) { 1317 - return $this->getSSHCloneURIObject(); 1318 - } else if ($serve_http !== self::SERVE_OFF) { 1319 - return $this->getHTTPCloneURIObject(); 1320 - } else { 1321 - return null; 1322 - } 1323 - } 1324 - 1325 - 1326 - /** 1327 - * Get the repository's SSH clone/checkout URI, if one exists. 1328 - */ 1329 - public function getSSHCloneURIObject() { 1330 - if (!$this->isHosted()) { 1331 - if ($this->shouldUseSSH()) { 1332 - return $this->getRemoteURIObject(); 1333 - } else { 1334 - return null; 1335 - } 1336 - } 1337 - 1338 - $serve_ssh = $this->getServeOverSSH(); 1339 - if ($serve_ssh === self::SERVE_OFF) { 1340 - return null; 1341 - } 1342 - 1343 - $uri = new PhutilURI(PhabricatorEnv::getProductionURI($this->getURI())); 1344 - 1345 - if ($this->isSVN()) { 1346 - $uri->setProtocol('svn+ssh'); 1347 - } else { 1348 - $uri->setProtocol('ssh'); 1349 - } 1350 - 1351 - if ($this->isGit()) { 1352 - $uri->setPath($uri->getPath().$this->getCloneName().'.git'); 1353 - } else if ($this->isHg()) { 1354 - $uri->setPath($uri->getPath().$this->getCloneName().'/'); 1355 - } 1356 - 1357 - $ssh_user = AlmanacKeys::getClusterSSHUser(); 1358 - if (strlen($ssh_user)) { 1359 - $uri->setUser($ssh_user); 1360 - } 1361 - 1362 - $ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host'); 1363 - if (strlen($ssh_host)) { 1364 - $uri->setDomain($ssh_host); 1365 - } 1366 - 1367 - $uri->setPort(PhabricatorEnv::getEnvConfig('diffusion.ssh-port')); 1368 - 1369 - return $uri; 1370 - } 1283 + // TODO: This should be cleaned up to deal with all the new URI handling. 1284 + $another_copy = id(new PhabricatorRepositoryQuery()) 1285 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 1286 + ->withPHIDs(array($this->getPHID())) 1287 + ->needURIs(true) 1288 + ->executeOne(); 1371 1289 1372 - 1373 - /** 1374 - * Get the repository's HTTP clone/checkout URI, if one exists. 1375 - */ 1376 - public function getHTTPCloneURIObject() { 1377 - if (!$this->isHosted()) { 1378 - if ($this->shouldUseHTTP()) { 1379 - return $this->getRemoteURIObject(); 1380 - } else { 1381 - return null; 1382 - } 1383 - } 1384 - 1385 - $serve_http = $this->getServeOverHTTP(); 1386 - if ($serve_http === self::SERVE_OFF) { 1290 + $clone_uris = $another_copy->getCloneURIs(); 1291 + if (!$clone_uris) { 1387 1292 return null; 1388 1293 } 1389 1294 1390 - return $this->getRawHTTPCloneURIObject(); 1295 + return head($clone_uris); 1391 1296 } 1392 1297 1393 1298 private function getRawHTTPCloneURIObject() { ··· 1554 1459 return $this->setDetail('hosting-enabled', $enabled); 1555 1460 } 1556 1461 1557 - public function getServeOverHTTP() { 1558 - if ($this->isSVN()) { 1559 - return self::SERVE_OFF; 1462 + public function canServeProtocol($protocol, $write) { 1463 + if (!$this->isTracked()) { 1464 + return false; 1560 1465 } 1561 - $serve = $this->getDetail('serve-over-http', self::SERVE_OFF); 1562 - return $this->normalizeServeConfigSetting($serve); 1563 - } 1564 1466 1565 - public function setServeOverHTTP($mode) { 1566 - return $this->setDetail('serve-over-http', $mode); 1567 - } 1467 + $clone_uris = $this->getCloneURIs(); 1468 + foreach ($clone_uris as $uri) { 1469 + if ($uri->getBuiltinProtocol() !== $protocol) { 1470 + continue; 1471 + } 1568 1472 1569 - public function getServeOverSSH() { 1570 - $serve = $this->getDetail('serve-over-ssh', self::SERVE_OFF); 1571 - return $this->normalizeServeConfigSetting($serve); 1572 - } 1473 + $io_type = $uri->getEffectiveIoType(); 1474 + if ($io_type == PhabricatorRepositoryURI::IO_READWRITE) { 1475 + return true; 1476 + } 1573 1477 1574 - public function setServeOverSSH($mode) { 1575 - return $this->setDetail('serve-over-ssh', $mode); 1576 - } 1577 - 1578 - public static function getProtocolAvailabilityName($constant) { 1579 - switch ($constant) { 1580 - case self::SERVE_OFF: 1581 - return pht('Off'); 1582 - case self::SERVE_READONLY: 1583 - return pht('Read Only'); 1584 - case self::SERVE_READWRITE: 1585 - return pht('Read/Write'); 1586 - default: 1587 - return pht('Unknown'); 1478 + if (!$write) { 1479 + if ($io_type == PhabricatorRepositoryURI::IO_READ) { 1480 + return true; 1481 + } 1482 + } 1588 1483 } 1589 - } 1590 1484 1591 - private function normalizeServeConfigSetting($value) { 1592 - switch ($value) { 1593 - case self::SERVE_OFF: 1594 - case self::SERVE_READONLY: 1595 - return $value; 1596 - case self::SERVE_READWRITE: 1597 - if ($this->isHosted()) { 1598 - return self::SERVE_READWRITE; 1599 - } else { 1600 - return self::SERVE_READONLY; 1601 - } 1602 - default: 1603 - return self::SERVE_OFF; 1604 - } 1485 + return false; 1605 1486 } 1606 - 1607 1487 1608 1488 /** 1609 1489 * Raise more useful errors when there are basic filesystem problems. ··· 2133 2013 continue; 2134 2014 } 2135 2015 2136 - // If we don't have a persisted version of the URI, add the builtin 2137 - // version. 2138 - if (empty($custom_map[$builtin_key])) { 2139 - $uris[] = $builtin_uri; 2016 + // If the URI exists, make sure it's marked as not being disabled. 2017 + if (isset($custom_map[$builtin_key])) { 2018 + $uris[$custom_map[$builtin_key]]->setIsDisabled(false); 2140 2019 } 2141 2020 } 2142 2021 ··· 2156 2035 return $this->assertAttached($this->uris); 2157 2036 } 2158 2037 2159 - protected function newBuiltinURIs() { 2038 + public function getCloneURIs() { 2039 + $uris = $this->getURIs(); 2040 + 2041 + $clone = array(); 2042 + foreach ($uris as $uri) { 2043 + if (!$uri->isBuiltin()) { 2044 + continue; 2045 + } 2046 + 2047 + if ($uri->getIsDisabled()) { 2048 + continue; 2049 + } 2050 + 2051 + $io_type = $uri->getEffectiveIoType(); 2052 + $is_clone = 2053 + ($io_type == PhabricatorRepositoryURI::IO_READ) || 2054 + ($io_type == PhabricatorRepositoryURI::IO_READWRITE); 2055 + 2056 + if (!$is_clone) { 2057 + continue; 2058 + } 2059 + 2060 + $clone[] = $uri; 2061 + } 2062 + 2063 + return msort($clone, 'getURIScore'); 2064 + } 2065 + 2066 + 2067 + public function newBuiltinURIs() { 2160 2068 $has_callsign = ($this->getCallsign() !== null); 2161 2069 $has_shortname = ($this->getRepositorySlug() !== null); 2162 2070 2071 + // TODO: For now, never enable these because they don't work yet. 2072 + $has_shortname = false; 2073 + 2163 2074 $identifier_map = array( 2164 2075 PhabricatorRepositoryURI::BUILTIN_IDENTIFIER_CALLSIGN => $has_callsign, 2165 2076 PhabricatorRepositoryURI::BUILTIN_IDENTIFIER_SHORTNAME => $has_shortname, ··· 2175 2086 2176 2087 $has_http = !PhabricatorEnv::getEnvConfig('security.require-https'); 2177 2088 $has_http = ($has_http && $allow_http); 2089 + 2090 + // HTTP is not supported for Subversion. 2091 + if ($this->isSVN()) { 2092 + $has_http = false; 2093 + } 2178 2094 2179 2095 // TODO: Maybe allow users to disable this by default somehow? 2180 2096 $has_ssh = true; ··· 2188 2104 $uris = array(); 2189 2105 foreach ($protocol_map as $protocol => $proto_supported) { 2190 2106 foreach ($identifier_map as $identifier => $id_supported) { 2107 + // This is just a dummy value because it can't be empty; we'll force 2108 + // it to a proper value when using it in the UI. 2109 + $builtin_uri = "{$protocol}://{$identifier}"; 2191 2110 $uris[] = PhabricatorRepositoryURI::initializeNewURI() 2192 2111 ->setRepositoryPHID($this->getPHID()) 2193 2112 ->attachRepository($this) 2194 2113 ->setBuiltinProtocol($protocol) 2195 2114 ->setBuiltinIdentifier($identifier) 2196 - ->setIsDisabled(!$proto_supported || !$id_supported); 2115 + ->setURI($builtin_uri) 2116 + ->setIsDisabled((int)(!$proto_supported || !$id_supported)); 2197 2117 } 2198 2118 } 2199 2119
+4 -4
src/applications/repository/storage/PhabricatorRepositoryTransaction.php
··· 351 351 '%s changed the availability of this repository over HTTP from '. 352 352 '"%s" to "%s".', 353 353 $this->renderHandleLink($author_phid), 354 - PhabricatorRepository::getProtocolAvailabilityName($old), 355 - PhabricatorRepository::getProtocolAvailabilityName($new)); 354 + $old, 355 + $new); 356 356 case self::TYPE_PROTOCOL_SSH: 357 357 return pht( 358 358 '%s changed the availability of this repository over SSH from '. 359 359 '"%s" to "%s".', 360 360 $this->renderHandleLink($author_phid), 361 - PhabricatorRepository::getProtocolAvailabilityName($old), 362 - PhabricatorRepository::getProtocolAvailabilityName($new)); 361 + $old, 362 + $new); 363 363 case self::TYPE_PUSH_POLICY: 364 364 return pht( 365 365 '%s changed the push policy of this repository from "%s" to "%s".',
+25 -1
src/applications/repository/storage/PhabricatorRepositoryURI.php
··· 246 246 ); 247 247 248 248 $uri = new PhutilURI($raw_uri); 249 + 250 + // Make sure to remove any password from the URI before we do anything 251 + // with it; this should always be provided by the associated credential. 252 + $uri->setPass(null); 253 + 249 254 if (!$uri->getProtocol()) { 250 255 $git_uri = new PhutilGitURI($raw_uri); 251 256 ··· 409 414 410 415 if ($this->isBuiltin()) { 411 416 $options[] = self::IO_READ; 412 - $options[] = self::IO_WRITE; 417 + $options[] = self::IO_READWRITE; 413 418 } else { 414 419 $options[] = self::IO_OBSERVE; 415 420 $options[] = self::IO_MIRROR; ··· 534 539 return DiffusionCommandEngine::newCommandEngine($repository) 535 540 ->setCredentialPHID($this->getCredentialPHID()) 536 541 ->setProtocol($protocol); 542 + } 543 + 544 + public function getURIScore() { 545 + $score = 0; 546 + 547 + $io_points = array( 548 + self::IO_READWRITE => 20, 549 + self::IO_READ => 10, 550 + ); 551 + $score += idx($io_points, $this->getEffectiveIoType(), 0); 552 + 553 + $protocol_points = array( 554 + self::BUILTIN_PROTOCOL_SSH => 3, 555 + self::BUILTIN_PROTOCOL_HTTPS => 2, 556 + self::BUILTIN_PROTOCOL_HTTP => 1, 557 + ); 558 + $score += idx($protocol_points, $this->getBuiltinProtocol(), 0); 559 + 560 + return $score; 537 561 } 538 562 539 563
+4
src/applications/transactions/editengine/PhabricatorEditEngine.php
··· 2035 2035 return $fields; 2036 2036 } 2037 2037 2038 + if (!$this->getSelectedPage()) { 2039 + return $fields; 2040 + } 2041 + 2038 2042 $page_picks = array(); 2039 2043 $default_key = head($pages)->getKey(); 2040 2044 foreach ($pages as $page_key => $page) {