diff --git a/resources/sql/autopatches/20160503.repo.05.urimigrate.php b/resources/sql/autopatches/20160503.repo.05.urimigrate.php new file mode 100644 index 0000000000..d48afd4f66 --- /dev/null +++ b/resources/sql/autopatches/20160503.repo.05.urimigrate.php @@ -0,0 +1,82 @@ +establishConnection('w'); + +foreach (new LiskMigrationIterator($table) as $repository) { + $uris = array(); + + $serve_http = $repository->getDetail('serve-over-http'); + $http_io = PhabricatorRepositoryURI::IO_DEFAULT; + $disable_http = false; + switch ($serve_http) { + case 'readwrite': + break; + case 'readonly': + $http_io = PhabricatorRepositoryURI::IO_READ; + break; + case 'off': + default: + $disable_http = true; + break; + } + + $serve_ssh = $repository->getDetail('serve-over-ssh'); + $ssh_io = PhabricatorRepositoryURI::IO_DEFAULT; + $disable_ssh = false; + switch ($serve_ssh) { + case 'readwrite': + break; + case 'readonly': + $ssh_io = PhabricatorRepositoryURI::IO_READ; + break; + case 'off': + default: + $disable_ssh = true; + break; + } + + $uris = $repository->newBuiltinURIs(); + + foreach ($uris as $uri) { + $builtin_protocol = $uri->getBuiltinProtocol(); + if ($builtin_protocol == PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH) { + $uri->setIsDisabled((int)$disable_ssh); + $uri->setIoType($ssh_io); + } else { + $uri->setIsDisabled((int)$disable_http); + $uri->setIoType($http_io); + } + } + + if (!$repository->isHosted()) { + $remote_uri = $repository->getDetail('remote-uri'); + if (strlen($remote_uri)) { + $uris[] = PhabricatorRepositoryURI::initializeNewURI() + ->setRepositoryPHID($repository->getPHID()) + ->attachRepository($repository) + ->setURI($remote_uri) + ->setCredentialPHID($repository->getCredentialPHID()) + ->setIOType(PhabricatorRepositoryURI::IO_OBSERVE); + } + } + + foreach ($uris as $uri) { + $already_exists = id(new PhabricatorRepositoryURI())->loadOneWhere( + 'repositoryPHID = %s AND uri = %s LIMIT 1', + $repository->getPHID(), + $uri->getURI()); + if ($already_exists) { + continue; + } + + $uri->save(); + + echo tsprintf( + "%s\n", + pht( + 'Migrated URI "%s" for repository "%s".', + $uri->getURI(), + $repository->getDisplayName())); + } +} diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index c41fc1f0ba..b4f3aff738 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -749,25 +749,14 @@ phutil_register_library_map(array( 'DiffusionRepositoryClusterEngine' => 'applications/diffusion/protocol/DiffusionRepositoryClusterEngine.php', 'DiffusionRepositoryClusterEngineLogInterface' => 'applications/diffusion/protocol/DiffusionRepositoryClusterEngineLogInterface.php', 'DiffusionRepositoryController' => 'applications/diffusion/controller/DiffusionRepositoryController.php', - 'DiffusionRepositoryCreateController' => 'applications/diffusion/controller/DiffusionRepositoryCreateController.php', 'DiffusionRepositoryDatasource' => 'applications/diffusion/typeahead/DiffusionRepositoryDatasource.php', 'DiffusionRepositoryDefaultController' => 'applications/diffusion/controller/DiffusionRepositoryDefaultController.php', - 'DiffusionRepositoryEditActionsController' => 'applications/diffusion/controller/DiffusionRepositoryEditActionsController.php', 'DiffusionRepositoryEditActivateController' => 'applications/diffusion/controller/DiffusionRepositoryEditActivateController.php', - 'DiffusionRepositoryEditAutomationController' => 'applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php', - 'DiffusionRepositoryEditBasicController' => 'applications/diffusion/controller/DiffusionRepositoryEditBasicController.php', - 'DiffusionRepositoryEditBranchesController' => 'applications/diffusion/controller/DiffusionRepositoryEditBranchesController.php', 'DiffusionRepositoryEditConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRepositoryEditConduitAPIMethod.php', 'DiffusionRepositoryEditController' => 'applications/diffusion/controller/DiffusionRepositoryEditController.php', 'DiffusionRepositoryEditDangerousController' => 'applications/diffusion/controller/DiffusionRepositoryEditDangerousController.php', 'DiffusionRepositoryEditDeleteController' => 'applications/diffusion/controller/DiffusionRepositoryEditDeleteController.php', - 'DiffusionRepositoryEditEncodingController' => 'applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php', 'DiffusionRepositoryEditEngine' => 'applications/diffusion/editor/DiffusionRepositoryEditEngine.php', - 'DiffusionRepositoryEditHostingController' => 'applications/diffusion/controller/DiffusionRepositoryEditHostingController.php', - 'DiffusionRepositoryEditMainController' => 'applications/diffusion/controller/DiffusionRepositoryEditMainController.php', - 'DiffusionRepositoryEditStagingController' => 'applications/diffusion/controller/DiffusionRepositoryEditStagingController.php', - 'DiffusionRepositoryEditStorageController' => 'applications/diffusion/controller/DiffusionRepositoryEditStorageController.php', - 'DiffusionRepositoryEditSubversionController' => 'applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php', 'DiffusionRepositoryEditUpdateController' => 'applications/diffusion/controller/DiffusionRepositoryEditUpdateController.php', 'DiffusionRepositoryEditproController' => 'applications/diffusion/controller/DiffusionRepositoryEditproController.php', 'DiffusionRepositoryHistoryManagementPanel' => 'applications/diffusion/management/DiffusionRepositoryHistoryManagementPanel.php', @@ -4976,25 +4965,14 @@ phutil_register_library_map(array( 'DiffusionRepositoryByIDRemarkupRule' => 'PhabricatorObjectRemarkupRule', 'DiffusionRepositoryClusterEngine' => 'Phobject', 'DiffusionRepositoryController' => 'DiffusionController', - 'DiffusionRepositoryCreateController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryDatasource' => 'PhabricatorTypeaheadDatasource', 'DiffusionRepositoryDefaultController' => 'DiffusionController', - 'DiffusionRepositoryEditActionsController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditActivateController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditAutomationController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditBasicController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditBranchesController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditConduitAPIMethod' => 'PhabricatorEditEngineAPIMethod', 'DiffusionRepositoryEditController' => 'DiffusionController', 'DiffusionRepositoryEditDangerousController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditDeleteController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditEncodingController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditEngine' => 'PhabricatorEditEngine', - 'DiffusionRepositoryEditHostingController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditMainController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditStagingController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditStorageController' => 'DiffusionRepositoryEditController', - 'DiffusionRepositoryEditSubversionController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditUpdateController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryEditproController' => 'DiffusionRepositoryEditController', 'DiffusionRepositoryHistoryManagementPanel' => 'DiffusionRepositoryManagementPanel', diff --git a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php index a7b7a51874..c644365556 100644 --- a/src/applications/diffusion/application/PhabricatorDiffusionApplication.php +++ b/src/applications/diffusion/application/PhabricatorDiffusionApplication.php @@ -57,7 +57,7 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { '/diffusion/' => array( $this->getQueryRoutePattern() => 'DiffusionRepositoryListController', - $this->getEditRoutePattern('editpro/') => + $this->getEditRoutePattern('edit/') => 'DiffusionRepositoryEditproController', 'new/' => 'DiffusionRepositoryNewController', '(?Pcreate)/' => 'DiffusionRepositoryCreateController', @@ -101,24 +101,10 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication { => 'DiffusionRepositoryURICredentialController', ), 'edit/' => array( - '' => 'DiffusionRepositoryEditMainController', - 'basic/' => 'DiffusionRepositoryEditBasicController', - 'encoding/' => 'DiffusionRepositoryEditEncodingController', 'activate/' => 'DiffusionRepositoryEditActivateController', 'dangerous/' => 'DiffusionRepositoryEditDangerousController', - 'branches/' => 'DiffusionRepositoryEditBranchesController', - 'subversion/' => 'DiffusionRepositoryEditSubversionController', - 'actions/' => 'DiffusionRepositoryEditActionsController', - '(?Premote)/' => 'DiffusionRepositoryCreateController', - '(?Ppolicy)/' => 'DiffusionRepositoryCreateController', - 'storage/' => 'DiffusionRepositoryEditStorageController', 'delete/' => 'DiffusionRepositoryEditDeleteController', - 'hosting/' => 'DiffusionRepositoryEditHostingController', - '(?Pserve)/' => 'DiffusionRepositoryEditHostingController', 'update/' => 'DiffusionRepositoryEditUpdateController', - 'symbol/' => 'DiffusionRepositorySymbolsController', - 'staging/' => 'DiffusionRepositoryEditStagingController', - 'automation/' => 'DiffusionRepositoryEditAutomationController', 'testautomation/' => 'DiffusionRepositoryTestAutomationController', ), 'pathtree/(?P.*)' => 'DiffusionPathTreeController', diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php index b9e8fa40c6..9aad7f1c5b 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php @@ -248,21 +248,14 @@ final class DiffusionRepositoryController extends DiffusionController { private function buildCurtain(PhabricatorRepository $repository) { $viewer = $this->getViewer(); - $edit_uri = $repository->getPathURI('edit/'); + $edit_uri = $repository->getPathURI('manage/'); $curtain = $this->newCurtainView($repository); - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - $curtain->addAction( id(new PhabricatorActionView()) - ->setName(pht('Edit Repository')) - ->setIcon('fa-pencil') - ->setHref($edit_uri) - ->setWorkflow(!$can_edit) - ->setDisabled(!$can_edit)); + ->setName(pht('Manage Repository')) + ->setIcon('fa-cogs') + ->setHref($edit_uri)); if ($repository->isHosted()) { $push_uri = $this->getApplicationURI( @@ -301,56 +294,27 @@ final class DiffusionRepositoryController extends DiffusionController { $view = id(new PHUIPropertyListView()) ->setUser($viewer); - if ($repository->isHosted()) { - $ssh_uri = $repository->getSSHCloneURIObject(); - if ($ssh_uri) { - $clone_uri = $this->renderCloneCommand( - $repository, - $ssh_uri, - $repository->getServeOverSSH(), - '/settings/panel/ssh/'); + $display_never = PhabricatorRepositoryURI::DISPLAY_NEVER; - $view->addProperty( - $repository->isSVN() - ? pht('Checkout (SSH)') - : pht('Clone (SSH)'), - $clone_uri); + $uris = $repository->getURIs(); + foreach ($uris as $uri) { + if ($uri->getIsDisabled()) { + continue; } - $http_uri = $repository->getHTTPCloneURIObject(); - if ($http_uri) { - $clone_uri = $this->renderCloneCommand( - $repository, - $http_uri, - $repository->getServeOverHTTP(), - PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth') - ? '/settings/panel/vcspassword/' - : null); + if ($uri->getEffectiveDisplayType() == $display_never) { + continue; + } - $view->addProperty( - $repository->isSVN() - ? pht('Checkout (HTTP)') - : pht('Clone (HTTP)'), - $clone_uri); - } - } else { - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $view->addProperty( - pht('Clone'), - $this->renderCloneCommand( - $repository, - $repository->getPublicCloneURI())); - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $view->addProperty( - pht('Checkout'), - $this->renderCloneCommand( - $repository, - $repository->getPublicCloneURI())); - break; + if ($repository->isSVN()) { + $label = pht('Checkout'); + } else { + $label = pht('Clone'); } + + $view->addProperty( + $label, + $this->renderCloneURI($repository, $uri)); } $box = id(new PHUIObjectBoxView()) @@ -701,80 +665,24 @@ final class DiffusionRepositoryController extends DiffusionController { ); } - private function renderCloneCommand( + private function renderCloneURI( PhabricatorRepository $repository, - $uri, - $serve_mode = null, - $manage_uri = null) { + PhabricatorRepositoryURI $uri) { require_celerity_resource('diffusion-icons-css'); - Javelin::initBehavior('select-on-click'); - - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $command = csprintf( - 'git clone %R', - $uri); - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $command = csprintf( - 'hg clone %R', - $uri); - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - if ($repository->isHosted()) { - $command = csprintf( - 'svn checkout %R %R', - $uri, - $repository->getCloneName()); - } else { - $command = csprintf( - 'svn checkout %R', - $uri); - } - break; - } + $display = (string)csprintf('%R', (string)$uri->getDisplayURI()); $input = javelin_tag( 'input', array( 'type' => 'text', - 'value' => (string)$command, + 'value' => $display, 'class' => 'diffusion-clone-uri', - 'sigil' => 'select-on-click', 'readonly' => 'true', )); - $extras = array(); - if ($serve_mode) { - if ($serve_mode === PhabricatorRepository::SERVE_READONLY) { - $extras[] = pht('(Read Only)'); - } - } - - if ($manage_uri) { - if ($this->getRequest()->getUser()->isLoggedIn()) { - $extras[] = phutil_tag( - 'a', - array( - 'href' => $manage_uri, - ), - pht('Manage Credentials')); - } - } - - if ($extras) { - $extras = phutil_implode_html(' ', $extras); - $extras = phutil_tag( - 'div', - array( - 'class' => 'diffusion-clone-extras', - ), - $extras); - } - - return array($input, $extras); + return $input; } } diff --git a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php b/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php deleted file mode 100644 index 580f021257..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryCreateController.php +++ /dev/null @@ -1,849 +0,0 @@ -getUser(); - $this->edit = $request->getURIData('edit'); - - // NOTE: We can end up here via either "Create Repository", or via - // "Import Repository", or via "Edit Remote", or via "Edit Policies". In - // the latter two cases, we show only a few of the pages. - - $repository = null; - $service = null; - switch ($this->edit) { - case 'remote': - case 'policy': - $response = $this->loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $repository = $this->getDiffusionRequest()->getRepository(); - - // Make sure we have CAN_EDIT. - PhabricatorPolicyFilter::requireCapability( - $viewer, - $repository, - PhabricatorPolicyCapability::CAN_EDIT); - - $this->setRepository($repository); - - $cancel_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - break; - case 'import': - case 'create': - $this->requireApplicationCapability( - DiffusionCreateRepositoriesCapability::CAPABILITY); - - // Pick a random open service to allocate this repository on, if any - // exist. If there are no services, we aren't in cluster mode and - // will allocate locally. If there are services but none permit - // allocations, we fail. - $services = id(new AlmanacServiceQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withServiceTypes( - array( - AlmanacClusterRepositoryServiceType::SERVICETYPE, - )) - ->needProperties(true) - ->execute(); - if ($services) { - // Filter out services which do not permit new allocations. - foreach ($services as $key => $possible_service) { - if ($possible_service->getAlmanacPropertyValue('closed')) { - unset($services[$key]); - } - } - - if (!$services) { - throw new Exception( - pht( - 'This install is configured in cluster mode, but all '. - 'available repository cluster services are closed to new '. - 'allocations. At least one service must be open to allow '. - 'new allocations to take place.')); - } - - shuffle($services); - $service = head($services); - } - - $cancel_uri = $this->getApplicationURI('new/'); - break; - default: - throw new Exception(pht('Invalid edit operation!')); - } - - $form = id(new PHUIPagedFormView()) - ->setUser($viewer) - ->setCancelURI($cancel_uri); - - switch ($this->edit) { - case 'remote': - $title = pht('Edit Remote'); - $form - ->addPage('remote-uri', $this->buildRemoteURIPage()) - ->addPage('auth', $this->buildAuthPage()); - break; - case 'policy': - $title = pht('Edit Policies'); - $form - ->addPage('policy', $this->buildPolicyPage()); - break; - case 'create': - $title = pht('Create Repository'); - $form - ->addPage('vcs', $this->buildVCSPage()) - ->addPage('name', $this->buildNamePage()) - ->addPage('policy', $this->buildPolicyPage()) - ->addPage('done', $this->buildDonePage()); - break; - case 'import': - $title = pht('Import Repository'); - $form - ->addPage('vcs', $this->buildVCSPage()) - ->addPage('name', $this->buildNamePage()) - ->addPage('remote-uri', $this->buildRemoteURIPage()) - ->addPage('auth', $this->buildAuthPage()) - ->addPage('policy', $this->buildPolicyPage()) - ->addPage('done', $this->buildDonePage()); - break; - } - - if ($request->isFormPost()) { - $form->readFromRequest($request); - if ($form->isComplete()) { - - $is_create = ($this->edit === 'import' || $this->edit === 'create'); - $is_auth = ($this->edit == 'import' || $this->edit == 'remote'); - $is_policy = ($this->edit != 'remote'); - $is_init = ($this->edit == 'create'); - - if ($is_create) { - $repository = PhabricatorRepository::initializeNewRepository( - $viewer); - } - - $template = id(new PhabricatorRepositoryTransaction()); - - $type_name = PhabricatorRepositoryTransaction::TYPE_NAME; - $type_vcs = PhabricatorRepositoryTransaction::TYPE_VCS; - $type_activate = PhabricatorRepositoryTransaction::TYPE_ACTIVATE; - $type_remote_uri = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI; - $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING; - $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; - $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; - $type_credential = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL; - $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY; - $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY; - $type_space = PhabricatorTransactions::TYPE_SPACE; - $type_push = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; - $type_service = PhabricatorRepositoryTransaction::TYPE_SERVICE; - - $xactions = array(); - - // If we're creating a new repository, set all this core stuff. - if ($is_create) { - $xactions[] = id(clone $template) - ->setTransactionType($type_name) - ->setNewValue( - $form->getPage('name')->getControl('name')->getValue()); - - $xactions[] = id(clone $template) - ->setTransactionType($type_vcs) - ->setNewValue( - $form->getPage('vcs')->getControl('vcs')->getValue()); - - $activate = $form->getPage('done') - ->getControl('activate')->getValue(); - if ($activate == 'start') { - $initial_status = PhabricatorRepository::STATUS_ACTIVE; - } else { - $initial_status = PhabricatorRepository::STATUS_INACTIVE; - } - - $xactions[] = id(clone $template) - ->setTransactionType($type_activate) - ->setNewValue($initial_status); - - if ($service) { - $xactions[] = id(clone $template) - ->setTransactionType($type_service) - ->setNewValue($service->getPHID()); - } - } - - if ($is_init) { - $xactions[] = id(clone $template) - ->setTransactionType($type_hosting) - ->setNewValue(true); - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); - if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) { - if (PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) { - $v_http_mode = PhabricatorRepository::SERVE_READWRITE; - } else { - $v_http_mode = PhabricatorRepository::SERVE_OFF; - } - $xactions[] = id(clone $template) - ->setTransactionType($type_http) - ->setNewValue($v_http_mode); - } - - if (PhabricatorEnv::getEnvConfig('diffusion.ssh-user')) { - $v_ssh_mode = PhabricatorRepository::SERVE_READWRITE; - } else { - $v_ssh_mode = PhabricatorRepository::SERVE_OFF; - } - $xactions[] = id(clone $template) - ->setTransactionType($type_ssh) - ->setNewValue($v_ssh_mode); - } - - if ($is_auth) { - $xactions[] = id(clone $template) - ->setTransactionType($type_remote_uri) - ->setNewValue( - $form->getPage('remote-uri')->getControl('remoteURI') - ->getValue()); - - $xactions[] = id(clone $template) - ->setTransactionType($type_credential) - ->setNewValue( - $form->getPage('auth')->getControl('credential')->getValue()); - } - - if ($is_policy) { - $policy_page = $form->getPage('policy'); - - $xactions[] = id(clone $template) - ->setTransactionType($type_view) - ->setNewValue($policy_page->getControl('viewPolicy')->getValue()); - - $xactions[] = id(clone $template) - ->setTransactionType($type_edit) - ->setNewValue($policy_page->getControl('editPolicy')->getValue()); - - if ($is_init || $repository->isHosted()) { - $xactions[] = id(clone $template) - ->setTransactionType($type_push) - ->setNewValue($policy_page->getControl('pushPolicy')->getValue()); - } - - $xactions[] = id(clone $template) - ->setTransactionType($type_space) - ->setNewValue( - $policy_page->getControl('viewPolicy')->getSpacePHID()); - } - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer) - ->applyTransactions($repository, $xactions); - - $repo_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - return id(new AphrontRedirectResponse())->setURI($repo_uri); - } - } else { - $dict = array(); - if ($repository) { - $dict = array( - 'remoteURI' => $repository->getRemoteURI(), - 'credential' => $repository->getCredentialPHID(), - 'viewPolicy' => $repository->getViewPolicy(), - 'editPolicy' => $repository->getEditPolicy(), - 'pushPolicy' => $repository->getPushPolicy(), - 'spacePHID' => $repository->getSpacePHID(), - ); - } - $form->readFromObject($dict); - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb($title); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText($title) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - - } - - -/* -( Page: VCS Type )----------------------------------------------------- */ - - - private function buildVCSPage() { - - $is_import = ($this->edit == 'import'); - - if ($is_import) { - $git_str = pht( - 'Import a Git repository (for example, a repository hosted '. - 'on GitHub).'); - $hg_str = pht( - 'Import a Mercurial repository (for example, a repository '. - 'hosted on Bitbucket).'); - $svn_str = pht('Import a Subversion repository.'); - } else { - $git_str = pht('Create a new, empty Git repository.'); - $hg_str = pht('Create a new, empty Mercurial repository.'); - $svn_str = pht('Create a new, empty Subversion repository.'); - } - - $control = id(new AphrontFormRadioButtonControl()) - ->setName('vcs') - ->setLabel(pht('Type')) - ->addButton( - PhabricatorRepositoryType::REPOSITORY_TYPE_GIT, - pht('Git'), - $git_str) - ->addButton( - PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL, - pht('Mercurial'), - $hg_str) - ->addButton( - PhabricatorRepositoryType::REPOSITORY_TYPE_SVN, - pht('Subversion'), - $svn_str); - - return id(new PHUIFormPageView()) - ->setPageName(pht('Repository Type')) - ->setUser($this->getRequest()->getUser()) - ->setValidateFormPageCallback(array($this, 'validateVCSPage')) - ->addControl($control); - } - - public function validateVCSPage(PHUIFormPageView $page) { - $valid = array( - PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => true, - PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => true, - PhabricatorRepositoryType::REPOSITORY_TYPE_SVN => true, - ); - - $c_vcs = $page->getControl('vcs'); - $v_vcs = $c_vcs->getValue(); - if (!$v_vcs) { - $c_vcs->setError(pht('Required')); - $page->addPageError( - pht('You must select a version control system.')); - } else if (empty($valid[$v_vcs])) { - $c_vcs->setError(pht('Invalid')); - $page->addPageError( - pht('You must select a valid version control system.')); - } - - return $c_vcs->isValid(); - } - - -/* -( Page: Name )--------------------------------------------------------- */ - - - private function buildNamePage() { - return id(new PHUIFormPageView()) - ->setUser($this->getRequest()->getUser()) - ->setPageName(pht('Repository Name and Location')) - ->setValidateFormPageCallback(array($this, 'validateNamePage')) - ->addRemarkupInstructions( - pht( - '**Choose a human-readable name for this repository**, like '. - '"CompanyName Mobile App" or "CompanyName Backend Server". You '. - 'can change this later.')) - ->addControl( - id(new AphrontFormTextControl()) - ->setName('name') - ->setLabel(pht('Name'))); - } - - public function validateNamePage(PHUIFormPageView $page) { - $c_name = $page->getControl('name'); - $v_name = $c_name->getValue(); - if (!strlen($v_name)) { - $c_name->setError(pht('Required')); - $page->addPageError( - pht('You must choose a name for this repository.')); - } - - return $c_name->isValid(); - } - - -/* -( Page: Remote URI )--------------------------------------------------- */ - - - private function buildRemoteURIPage() { - return id(new PHUIFormPageView()) - ->setUser($this->getRequest()->getUser()) - ->setPageName(pht('Repository Remote URI')) - ->setValidateFormPageCallback(array($this, 'validateRemoteURIPage')) - ->setAdjustFormPageCallback(array($this, 'adjustRemoteURIPage')) - ->addControl( - id(new AphrontFormTextControl()) - ->setName('remoteURI')); - } - - public function adjustRemoteURIPage(PHUIFormPageView $page) { - $form = $page->getForm(); - - $is_git = false; - $is_svn = false; - $is_mercurial = false; - - if ($this->getRepository()) { - $vcs = $this->getRepository()->getVersionControlSystem(); - } else { - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); - } - - switch ($vcs) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $is_git = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $is_svn = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $is_mercurial = true; - break; - default: - throw new Exception(pht('Unsupported VCS!')); - } - - $has_local = ($is_git || $is_mercurial); - if ($is_git) { - $uri_label = pht('Remote URI'); - $instructions = pht( - 'Enter the URI to clone this Git repository from. It should usually '. - 'look like one of these examples:'. - "\n\n". - "| Example Git Remote URIs |\n". - "| ----------------------- |\n". - "| `git@github.com:example/example.git` |\n". - "| `ssh://user@host.com/git/example.git` |\n". - "| `https://example.com/repository.git` |\n"); - } else if ($is_mercurial) { - $uri_label = pht('Remote URI'); - $instructions = pht( - 'Enter the URI to clone this Mercurial repository from. It should '. - 'usually look like one of these examples:'. - "\n\n". - "| Example Mercurial Remote URIs |\n". - "| ----------------------- |\n". - "| `ssh://hg@bitbucket.org/example/repository` |\n". - "| `https://bitbucket.org/example/repository` |\n"); - } else if ($is_svn) { - $uri_label = pht('Repository Root'); - $instructions = pht( - 'Enter the **Repository Root** for this Subversion repository. '. - 'You can figure this out by running `svn info` in a working copy '. - 'and looking at the value in the `Repository Root` field. It '. - 'should be a URI and will usually look like these:'. - "\n\n". - "| Example Subversion Repository Root URIs |\n". - "| ------------------------------ |\n". - "| `http://svn.example.org/svnroot/` |\n". - "| `svn+ssh://svn.example.com/svnroot/` |\n". - "| `svn://svn.example.net/svnroot/` |\n". - "\n\n". - "You **MUST** specify the root of the repository, not a ". - "subdirectory. (If you want to import only part of a Subversion ". - "repository, use the //Import Only// option at the end of this ". - "workflow.)"); - } else { - throw new Exception(pht('Unsupported VCS!')); - } - - $page->addRemarkupInstructions($instructions, 'remoteURI'); - $page->getControl('remoteURI')->setLabel($uri_label); - } - - public function validateRemoteURIPage(PHUIFormPageView $page) { - $c_remote = $page->getControl('remoteURI'); - $v_remote = $c_remote->getValue(); - - if (!strlen($v_remote)) { - $c_remote->setError(pht('Required')); - $page->addPageError( - pht('You must specify a URI.')); - } else { - try { - PhabricatorRepository::assertValidRemoteURI($v_remote); - } catch (Exception $ex) { - $c_remote->setError(pht('Invalid')); - $page->addPageError($ex->getMessage()); - } - } - - return $c_remote->isValid(); - } - - -/* -( Page: Authentication )----------------------------------------------- */ - - - public function buildAuthPage() { - return id(new PHUIFormPageView()) - ->setPageName(pht('Authentication')) - ->setUser($this->getRequest()->getUser()) - ->setAdjustFormPageCallback(array($this, 'adjustAuthPage')) - ->addControl( - id(new PassphraseCredentialControl()) - ->setViewer($this->getViewer()) - ->setName('credential')); - } - - - public function adjustAuthPage($page) { - $form = $page->getForm(); - - if ($this->getRepository()) { - $vcs = $this->getRepository()->getVersionControlSystem(); - } else { - $vcs = $form->getPage('vcs')->getControl('vcs')->getValue(); - } - - $remote_uri = $form->getPage('remote-uri') - ->getControl('remoteURI') - ->getValue(); - - $proto = PhabricatorRepository::getRemoteURIProtocol($remote_uri); - $remote_user = $this->getRemoteURIUser($remote_uri); - - $c_credential = $page->getControl('credential'); - $c_credential->setDefaultUsername($remote_user); - - if ($this->isSSHProtocol($proto)) { - $c_credential->setLabel(pht('SSH Key')); - $c_credential->setCredentialType( - PassphraseSSHPrivateKeyTextCredentialType::CREDENTIAL_TYPE); - $provides_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; - - $page->addRemarkupInstructions( - pht( - 'Choose or add the SSH credentials to use to connect to the '. - 'repository hosted at:'. - "\n\n". - " lang=text\n". - " %s", - $remote_uri), - 'credential'); - } else if ($this->isUsernamePasswordProtocol($proto)) { - $c_credential->setLabel(pht('Password')); - $c_credential->setAllowNull(true); - $c_credential->setCredentialType( - PassphrasePasswordCredentialType::CREDENTIAL_TYPE); - $provides_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; - - $page->addRemarkupInstructions( - pht( - 'Choose the username and password used to connect to the '. - 'repository hosted at:'. - "\n\n". - " lang=text\n". - " %s". - "\n\n". - "If this repository does not require a username or password, ". - "you can continue to the next step.", - $remote_uri), - 'credential'); - } else { - throw new Exception(pht('Unknown URI protocol!')); - } - - if ($provides_type) { - $viewer = $this->getRequest()->getUser(); - - $options = id(new PassphraseCredentialQuery()) - ->setViewer($viewer) - ->withIsDestroyed(false) - ->withProvidesTypes(array($provides_type)) - ->execute(); - - $c_credential->setOptions($options); - } - - } - - public function validateAuthPage(PHUIFormPageView $page) { - $form = $page->getForm(); - $remote_uri = $form->getPage('remote')->getControl('remoteURI')->getValue(); - $proto = $this->getRemoteURIProtocol($remote_uri); - - $c_credential = $page->getControl('credential'); - $v_credential = $c_credential->getValue(); - - // NOTE: We're using the omnipotent user here because the viewer might be - // editing a repository they're allowed to edit which uses a credential they - // are not allowed to see. This is fine, as long as they don't change it. - $credential = id(new PassphraseCredentialQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withPHIDs(array($v_credential)) - ->executeOne(); - - if ($this->isSSHProtocol($proto)) { - if (!$credential) { - $c_credential->setError(pht('Required')); - $page->addPageError( - pht('You must choose an SSH credential to connect over SSH.')); - } - - $ssh_type = PassphraseSSHPrivateKeyCredentialType::PROVIDES_TYPE; - if ($credential->getProvidesType() !== $ssh_type) { - $c_credential->setError(pht('Invalid')); - $page->addPageError( - pht( - 'You must choose an SSH credential, not some other type '. - 'of credential.')); - } - - } else if ($this->isUsernamePasswordProtocol($proto)) { - if ($credential) { - $password_type = PassphrasePasswordCredentialType::PROVIDES_TYPE; - if ($credential->getProvidesType() !== $password_type) { - $c_credential->setError(pht('Invalid')); - $page->addPageError( - pht( - 'You must choose a username/password credential, not some other '. - 'type of credential.')); - } - } - - return $c_credential->isValid(); - } else { - return true; - } - } - - -/* -( Page: Policy )------------------------------------------------------- */ - - - private function buildPolicyPage() { - $viewer = $this->getRequest()->getUser(); - if ($this->getRepository()) { - $repository = $this->getRepository(); - } else { - $repository = PhabricatorRepository::initializeNewRepository($viewer); - } - - $policies = id(new PhabricatorPolicyQuery()) - ->setViewer($viewer) - ->setObject($repository) - ->execute(); - - $view_policy = id(new AphrontFormPolicyControl()) - ->setUser($viewer) - ->setCapability(PhabricatorPolicyCapability::CAN_VIEW) - ->setPolicyObject($repository) - ->setPolicies($policies) - ->setName('viewPolicy'); - - $edit_policy = id(new AphrontFormPolicyControl()) - ->setUser($viewer) - ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) - ->setPolicyObject($repository) - ->setPolicies($policies) - ->setName('editPolicy'); - - $push_policy = id(new AphrontFormPolicyControl()) - ->setUser($viewer) - ->setCapability(DiffusionPushCapability::CAPABILITY) - ->setPolicyObject($repository) - ->setPolicies($policies) - ->setName('pushPolicy'); - - return id(new PHUIFormPageView()) - ->setPageName(pht('Policies')) - ->setValidateFormPageCallback(array($this, 'validatePolicyPage')) - ->setAdjustFormPageCallback(array($this, 'adjustPolicyPage')) - ->setUser($viewer) - ->addRemarkupInstructions( - pht('Select access policies for this repository.')) - ->addControl($view_policy) - ->addControl($edit_policy) - ->addControl($push_policy); - } - - public function adjustPolicyPage(PHUIFormPageView $page) { - if ($this->getRepository()) { - $repository = $this->getRepository(); - $show_push = $repository->isHosted(); - } else { - $show_push = ($this->edit == 'create'); - } - - if (!$show_push) { - $c_push = $page->getControl('pushPolicy'); - $c_push->setHidden(true); - } - } - - public function validatePolicyPage(PHUIFormPageView $page) { - $form = $page->getForm(); - $viewer = $this->getRequest()->getUser(); - - $c_view = $page->getControl('viewPolicy'); - $c_edit = $page->getControl('editPolicy'); - $c_push = $page->getControl('pushPolicy'); - $v_view = $c_view->getValue(); - $v_edit = $c_edit->getValue(); - $v_push = $c_push->getValue(); - - if ($this->getRepository()) { - $repository = $this->getRepository(); - } else { - $repository = PhabricatorRepository::initializeNewRepository($viewer); - } - - $proxy = clone $repository; - $proxy->setViewPolicy($v_view); - $proxy->setEditPolicy($v_edit); - - $can_view = PhabricatorPolicyFilter::hasCapability( - $viewer, - $proxy, - PhabricatorPolicyCapability::CAN_VIEW); - - $can_edit = PhabricatorPolicyFilter::hasCapability( - $viewer, - $proxy, - PhabricatorPolicyCapability::CAN_EDIT); - - if (!$can_view) { - $c_view->setError(pht('Invalid')); - $page->addPageError( - pht( - 'You can not use the selected policy, because you would be unable '. - 'to see the repository.')); - } - - if (!$can_edit) { - $c_edit->setError(pht('Invalid')); - $page->addPageError( - pht( - 'You can not use the selected edit policy, because you would be '. - 'unable to edit the repository.')); - } - - return $c_view->isValid() && - $c_edit->isValid(); - } - -/* -( Page: Done )--------------------------------------------------------- */ - - - private function buildDonePage() { - - $is_create = ($this->edit == 'create'); - if ($is_create) { - $now_label = pht('Create Repository Now'); - $now_caption = pht( - 'Create the repository right away. This will create the repository '. - 'using default settings.'); - - $wait_label = pht('Configure More Options First'); - $wait_caption = pht( - 'Configure more options before creating the repository. '. - 'This will let you fine-tune settings. You can create the repository '. - 'whenever you are ready.'); - } else { - $now_label = pht('Start Import Now'); - $now_caption = pht( - 'Start importing the repository right away. This will import '. - 'the entire repository using default settings.'); - - $wait_label = pht('Configure More Options First'); - $wait_caption = pht( - 'Configure more options before beginning the repository '. - 'import. This will let you fine-tune settings. You can '. - 'start the import whenever you are ready.'); - } - - return id(new PHUIFormPageView()) - ->setPageName(pht('Repository Ready!')) - ->setValidateFormPageCallback(array($this, 'validateDonePage')) - ->setUser($this->getRequest()->getUser()) - ->addControl( - id(new AphrontFormRadioButtonControl()) - ->setName('activate') - ->setLabel(pht('Start Now')) - ->addButton( - 'start', - $now_label, - $now_caption) - ->addButton( - 'wait', - $wait_label, - $wait_caption)); - } - - public function validateDonePage(PHUIFormPageView $page) { - $c_activate = $page->getControl('activate'); - $v_activate = $c_activate->getValue(); - - if ($v_activate != 'start' && $v_activate != 'wait') { - $c_activate->setError(pht('Required')); - $page->addPageError( - pht('Make a choice about repository activation.')); - } - - return $c_activate->isValid(); - } - - -/* -( Internal )----------------------------------------------------------- */ - - private function getRemoteURIUser($raw_uri) { - $uri = new PhutilURI($raw_uri); - if ($uri->getUser()) { - return $uri->getUser(); - } - - $git_uri = new PhutilGitURI($raw_uri); - if (strlen($git_uri->getDomain()) && strlen($git_uri->getPath())) { - return $git_uri->getUser(); - } - - return null; - } - - private function isSSHProtocol($proto) { - return ($proto == 'git' || $proto == 'ssh' || $proto == 'svn+ssh'); - } - - private function isUsernamePasswordProtocol($proto) { - return ($proto == 'http' || $proto == 'https' || $proto == 'svn'); - } - - private function setRepository(PhabricatorRepository $repository) { - $this->repository = $repository; - return $this; - } - - private function getRepository() { - return $this->repository; - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditActionsController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditActionsController.php deleted file mode 100644 index b8f95f36fc..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditActionsController.php +++ /dev/null @@ -1,121 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - // NOTE: We're inverting these here, because the storage is silly. - $v_notify = !$repository->getHumanReadableDetail('herald-disabled'); - $v_autoclose = !$repository->getHumanReadableDetail('disable-autoclose'); - - if ($request->isFormPost()) { - $v_notify = $request->getBool('notify'); - $v_autoclose = $request->getBool('autoclose'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_notify = PhabricatorRepositoryTransaction::TYPE_NOTIFY; - $type_autoclose = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE; - - $xactions[] = id(clone $template) - ->setTransactionType($type_notify) - ->setNewValue($v_notify); - - $xactions[] = id(clone $template) - ->setTransactionType($type_autoclose) - ->setNewValue($v_autoclose); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } - - $content = array(); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Actions')); - - $title = pht('Edit Actions (%s)', $repository->getName()); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $policies = id(new PhabricatorPolicyQuery()) - ->setViewer($viewer) - ->setObject($repository) - ->execute(); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendRemarkupInstructions( - pht( - "Normally, Phabricator publishes notifications when it discovers ". - "new commits. You can disable publishing for this repository by ". - "turning off **Notify/Publish**. This will disable notifications, ". - "feed, and Herald (including audits and build plans) for this ". - "repository.\n\n". - "When Phabricator discovers a new commit, it can automatically ". - "close associated revisions and tasks. If you don't want ". - "Phabricator to close objects when it discovers new commits in ". - "this repository, you can disable **Autoclose**.")) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('notify') - ->setLabel(pht('Notify/Publish')) - ->setValue((int)$v_notify) - ->setOptions( - array( - 1 => pht('Enable Notifications, Feed and Herald'), - 0 => pht('Disable Notifications, Feed and Herald'), - ))) - ->appendChild( - id(new AphrontFormSelectControl()) - ->setName('autoclose') - ->setLabel(pht('Autoclose')) - ->setValue((int)$v_autoclose) - ->setOptions( - array( - 1 => pht('Enable Autoclose'), - 0 => pht('Disable Autoclose'), - ))) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Actions')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Actions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php deleted file mode 100644 index 038cc0f0cd..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditAutomationController.php +++ /dev/null @@ -1,93 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - if (!$repository->supportsAutomation()) { - return new Aphront404Response(); - } - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_blueprints = $repository->getHumanReadableDetail( - 'automation.blueprintPHIDs'); - - if ($request->isFormPost()) { - $v_blueprints = $request->getArr('blueprintPHIDs'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_blueprints = - PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS; - - $xactions[] = id(clone $template) - ->setTransactionType($type_blueprints) - ->setNewValue($v_blueprints); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Automation')); - - $title = pht('Edit %s', $repository->getName()); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendRemarkupInstructions( - pht( - "Configure **Repository Automation** to allow Phabricator to ". - "write to this repository.". - "\n\n". - "IMPORTANT: This feature is new, experimental, and not supported. ". - "Use it at your own risk.")) - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setLabel(pht('Use Blueprints')) - ->setName('blueprintPHIDs') - ->setValue($v_blueprints) - ->setDatasource(new DrydockBlueprintDatasource())) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Automation')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php deleted file mode 100644 index 10f4b13ef9..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php +++ /dev/null @@ -1,193 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $request->getUser(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_name = $repository->getName(); - $v_desc = $repository->getDetail('description'); - $v_slug = $repository->getRepositorySlug(); - $v_callsign = $repository->getCallsign(); - $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs( - $repository->getPHID(), - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST); - $e_name = true; - $e_slug = null; - $e_callsign = null; - $errors = array(); - - $validation_exception = null; - if ($request->isFormPost()) { - $v_name = $request->getStr('name'); - $v_desc = $request->getStr('description'); - $v_projects = $request->getArr('projectPHIDs'); - $v_slug = $request->getStr('slug'); - $v_callsign = $request->getStr('callsign'); - - if (!strlen($v_name)) { - $e_name = pht('Required'); - $errors[] = pht('Repository name is required.'); - } else { - $e_name = null; - } - - if (!$errors) { - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_name = PhabricatorRepositoryTransaction::TYPE_NAME; - $type_desc = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION; - $type_edge = PhabricatorTransactions::TYPE_EDGE; - $type_slug = PhabricatorRepositoryTransaction::TYPE_SLUG; - $type_callsign = PhabricatorRepositoryTransaction::TYPE_CALLSIGN; - - $xactions[] = id(clone $template) - ->setTransactionType($type_name) - ->setNewValue($v_name); - - $xactions[] = id(clone $template) - ->setTransactionType($type_desc) - ->setNewValue($v_desc); - - $xactions[] = id(clone $template) - ->setTransactionType($type_slug) - ->setNewValue($v_slug); - - $xactions[] = id(clone $template) - ->setTransactionType($type_callsign) - ->setNewValue($v_callsign); - - $xactions[] = id(clone $template) - ->setTransactionType($type_edge) - ->setMetadataValue( - 'edge:type', - PhabricatorProjectObjectHasProjectEdgeType::EDGECONST) - ->setNewValue( - array( - '=' => array_fuse($v_projects), - )); - - $editor = id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer); - - try { - $editor->applyTransactions($repository, $xactions); - - // The preferred edit URI may have changed if the callsign or slug - // were adjusted, so grab a fresh copy. - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } catch (PhabricatorApplicationTransactionValidationException $ex) { - $validation_exception = $ex; - - $e_slug = $ex->getShortMessage($type_slug); - $e_callsign = $ex->getShortMessage($type_callsign); - } - } - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Basics')); - - $title = pht('Edit %s', $repository->getName()); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('name') - ->setLabel(pht('Name')) - ->setValue($v_name) - ->setError($e_name)) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('slug') - ->setLabel(pht('Short Name')) - ->setValue($v_slug) - ->setError($e_slug)) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('callsign') - ->setLabel(pht('Callsign')) - ->setValue($v_callsign) - ->setError($e_callsign)) - ->appendChild( - id(new PhabricatorRemarkupControl()) - ->setUser($viewer) - ->setName('description') - ->setLabel(pht('Description')) - ->setValue($v_desc)) - ->appendControl( - id(new AphrontFormTokenizerControl()) - ->setDatasource(new PhabricatorProjectDatasource()) - ->setName('projectPHIDs') - ->setLabel(pht('Projects')) - ->setValue($v_projects)) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save')) - ->addCancelButton($edit_uri)) - ->appendChild(id(new PHUIFormDividerControl())) - ->appendRemarkupInstructions($this->getReadmeInstructions()); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Basic Information')) - ->setValidationException($validation_exception) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form) - ->setFormErrors($errors); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - - private function getReadmeInstructions() { - return pht(<<loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $is_git = false; - $is_hg = false; - - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $is_git = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $is_hg = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - throw new Exception( - pht('Subversion does not support branches!')); - default: - throw new Exception( - pht('Repository has unknown version control system!')); - } - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_default = $repository->getHumanReadableDetail('default-branch'); - $v_track = $repository->getDetail( - 'branch-filter', - array()); - $v_track = array_keys($v_track); - $v_autoclose = $repository->getDetail( - 'close-commits-filter', - array()); - $v_autoclose = array_keys($v_autoclose); - - $e_track = null; - $e_autoclose = null; - - $validation_exception = null; - if ($request->isFormPost()) { - $v_default = $request->getStr('default'); - - $v_track = $this->processBranches($request->getStr('track')); - if (!$is_hg) { - $v_autoclose = $this->processBranches($request->getStr('autoclose')); - } - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_default = PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH; - $type_track = PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY; - $type_autoclose = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY; - - $xactions[] = id(clone $template) - ->setTransactionType($type_default) - ->setNewValue($v_default); - - $xactions[] = id(clone $template) - ->setTransactionType($type_track) - ->setNewValue($v_track); - - if (!$is_hg) { - $xactions[] = id(clone $template) - ->setTransactionType($type_autoclose) - ->setNewValue($v_autoclose); - } - - $editor = id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer); - - try { - $editor->applyTransactions($repository, $xactions); - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } catch (PhabricatorApplicationTransactionValidationException $ex) { - $validation_exception = $ex; - - $e_track = $validation_exception->getShortMessage($type_track); - $e_autoclose = $validation_exception->getShortMessage($type_autoclose); - } - } - - $content = array(); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Branches')); - - $title = pht('Edit Branches (%s)', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $policies = id(new PhabricatorPolicyQuery()) - ->setViewer($viewer) - ->setObject($repository) - ->execute(); - - $rows = array(); - $rows[] = array( - array( - 'master', - ), - pht('Select only master.'), - ); - $rows[] = array( - array( - 'master', - 'develop', - 'release', - ), - pht('Select %s, %s, and %s.', 'master', 'develop', 'release'), - ); - $rows[] = array( - array( - 'master', - 'regexp(/^release-/)', - ), - pht('Select master, and all branches which start with "%s".', 'release-'), - ); - $rows[] = array( - array( - 'regexp(/^(?!temp-)/)', - ), - pht('Select all branches which do not start with "%s".', 'temp-'), - ); - - foreach ($rows as $k => $row) { - $rows[$k][0] = phutil_tag( - 'pre', - array(), - implode("\n", $row[0])); - } - - $example_table = id(new AphrontTableView($rows)) - ->setHeaders( - array( - pht('Example'), - pht('Effect'), - )) - ->setColumnClasses( - array( - '', - 'wide', - )); - - $v_track = implode("\n", $v_track); - $v_autoclose = implode("\n", $v_autoclose); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendRemarkupInstructions( - pht('You can choose a **Default Branch** for viewing this repository.')) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('default') - ->setLabel(pht('Default Branch')) - ->setValue($v_default)) - ->appendRemarkupInstructions( - pht( - 'If you want to import only some branches into Diffusion, you can '. - 'list them in **Track Only**. Other branches will be ignored. If '. - 'you do not specify any branches, all branches are tracked.')); - - if (!$is_hg) { - $form->appendRemarkupInstructions( - pht( - 'If you have **Autoclose** enabled for this repository, Phabricator '. - 'can close tasks and revisions when corresponding commits are '. - 'pushed to the repository. If you want to autoclose objects only '. - 'when commits appear on specific branches, you can list those '. - 'branches in **Autoclose Only**. By default, all tracked branches '. - 'will autoclose objects.')); - } - - $form - ->appendRemarkupInstructions( - pht( - 'When specifying branches, you should enter one branch name per '. - 'line. You can use regular expressions to match branches by '. - 'wrapping an expression in `%s`. For example:', - 'regexp(...)')) - ->appendChild( - id(new AphrontFormMarkupControl()) - ->setValue($example_table)) - ->appendChild( - id(new AphrontFormTextAreaControl()) - ->setName('track') - ->setLabel(pht('Track Only')) - ->setError($e_track) - ->setValue($v_track)); - - if (!$is_hg) { - $form->appendChild( - id(new AphrontFormTextAreaControl()) - ->setName('autoclose') - ->setLabel(pht('Autoclose Only')) - ->setError($e_autoclose) - ->setValue($v_autoclose)); - } - - $form->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Branches')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Branches')) - ->setValidationException($validation_exception) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - - private function processBranches($string) { - $lines = phutil_split_lines($string, $retain_endings = false); - foreach ($lines as $key => $line) { - $lines[$key] = trim($line); - if (!strlen($lines[$key])) { - unset($lines[$key]); - } - } - - return array_values($lines); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php deleted file mode 100644 index 256e69ac59..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditEncodingController.php +++ /dev/null @@ -1,107 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $user = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_encoding = $repository->getDetail('encoding'); - $e_encoding = null; - $errors = array(); - - if ($request->isFormPost()) { - $v_encoding = $request->getStr('encoding'); - - if (!$errors) { - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_encoding = PhabricatorRepositoryTransaction::TYPE_ENCODING; - - $xactions[] = id(clone $template) - ->setTransactionType($type_encoding) - ->setNewValue($v_encoding); - - try { - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($user) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } catch (Exception $ex) { - $errors[] = $ex->getMessage(); - } - } - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Encoding')); - - $title = pht('Edit %s', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $form = id(new AphrontFormView()) - ->setUser($user) - ->appendRemarkupInstructions($this->getEncodingInstructions()) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('encoding') - ->setLabel(pht('Text Encoding')) - ->setValue($v_encoding) - ->setError($e_encoding)) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Encoding')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Encoding')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form) - ->setFormErrors($errors); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - - private function getEncodingInstructions() { - return pht(<<loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $this->serve = $request->getURIData('serve'); - - if (!$this->serve) { - return $this->handleHosting($repository); - } else { - return $this->handleProtocols($repository); - } - } - - public function handleHosting(PhabricatorRepository $repository) { - $request = $this->getRequest(); - $user = $request->getUser(); - - $v_hosting = $repository->isHosted(); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - $next_uri = $this->getRepositoryControllerURI($repository, 'edit/serve/'); - - if ($request->isFormPost()) { - $v_hosting = $request->getBool('hosting'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_hosting = PhabricatorRepositoryTransaction::TYPE_HOSTING; - - $xactions[] = id(clone $template) - ->setTransactionType($type_hosting) - ->setNewValue($v_hosting); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($user) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($next_uri); - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Hosting')); - - $title = pht('Edit Hosting (%s)', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $hosted_control = id(new AphrontFormRadioButtonControl()) - ->setName('hosting') - ->setLabel(pht('Hosting')) - ->addButton( - true, - pht('Host Repository on Phabricator'), - pht( - 'Phabricator will host this repository. Users will be able to '. - 'push commits to Phabricator. Phabricator will not pull '. - 'changes from elsewhere.')) - ->addButton( - false, - pht('Host Repository Elsewhere'), - pht( - 'Phabricator will pull updates to this repository from a master '. - 'repository elsewhere (for example, on GitHub or Bitbucket). '. - 'Users will not be able to push commits to this repository.')) - ->setValue($v_hosting); - - $doc_href = PhabricatorEnv::getDoclink( - 'Diffusion User Guide: Repository Hosting'); - - $form = id(new AphrontFormView()) - ->setUser($user) - ->appendRemarkupInstructions( - pht( - 'Phabricator can host repositories, or it can track repositories '. - 'hosted elsewhere (like on GitHub or Bitbucket). For information '. - 'on configuring hosting, see [[ %s | Diffusion User Guide: '. - 'Repository Hosting]]', - $doc_href)) - ->appendChild($hosted_control) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save and Continue')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Hosting')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - - public function handleProtocols(PhabricatorRepository $repository) { - $request = $this->getRequest(); - $user = $request->getUser(); - - $type = $repository->getVersionControlSystem(); - $is_svn = ($type == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN); - - $v_http_mode = $repository->getDetail( - 'serve-over-http', - PhabricatorRepository::SERVE_OFF); - $v_ssh_mode = $repository->getDetail( - 'serve-over-ssh', - PhabricatorRepository::SERVE_OFF); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - $prev_uri = $this->getRepositoryControllerURI($repository, 'edit/hosting/'); - - if ($request->isFormPost()) { - $v_http_mode = $request->getStr('http'); - $v_ssh_mode = $request->getStr('ssh'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_http = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; - $type_ssh = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; - - if (!$is_svn) { - $xactions[] = id(clone $template) - ->setTransactionType($type_http) - ->setNewValue($v_http_mode); - } - - $xactions[] = id(clone $template) - ->setTransactionType($type_ssh) - ->setNewValue($v_ssh_mode); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($user) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Protocols')); - - $title = pht('Edit Protocols (%s)', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $rw_message = pht( - 'Phabricator will serve a read-write copy of this repository.'); - - if (!$repository->isHosted()) { - $rw_message = array( - $rw_message, - phutil_tag('br'), - phutil_tag('br'), - pht( - '%s: This repository is hosted elsewhere, so Phabricator can not '. - 'perform writes. This mode will act like "Read Only" for '. - 'repositories hosted elsewhere.', - phutil_tag('strong', array(), pht('WARNING'))), - ); - } - - $ssh_control = - id(new AphrontFormRadioButtonControl()) - ->setName('ssh') - ->setLabel(pht('SSH')) - ->setValue($v_ssh_mode) - ->addButton( - PhabricatorRepository::SERVE_OFF, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_OFF), - pht('Phabricator will not serve this repository over SSH.')) - ->addButton( - PhabricatorRepository::SERVE_READONLY, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_READONLY), - pht( - 'Phabricator will serve a read-only copy of this repository '. - 'over SSH.')) - ->addButton( - PhabricatorRepository::SERVE_READWRITE, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_READWRITE), - $rw_message); - - $http_control = - id(new AphrontFormRadioButtonControl()) - ->setName('http') - ->setLabel(pht('HTTP')) - ->setValue($v_http_mode) - ->addButton( - PhabricatorRepository::SERVE_OFF, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_OFF), - pht('Phabricator will not serve this repository over HTTP.')) - ->addButton( - PhabricatorRepository::SERVE_READONLY, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_READONLY), - pht( - 'Phabricator will serve a read-only copy of this repository '. - 'over HTTP.')) - ->addButton( - PhabricatorRepository::SERVE_READWRITE, - PhabricatorRepository::getProtocolAvailabilityName( - PhabricatorRepository::SERVE_READWRITE), - $rw_message); - - if ($is_svn) { - $http_control = id(new AphrontFormMarkupControl()) - ->setLabel(pht('HTTP')) - ->setValue( - phutil_tag( - 'em', - array(), - pht( - 'Phabricator does not currently support HTTP access to '. - 'Subversion repositories.'))); - } - - $form = id(new AphrontFormView()) - ->setUser($user) - ->appendRemarkupInstructions( - pht( - 'Phabricator can serve repositories over various protocols. You can '. - 'configure server protocols here.')) - ->appendChild($ssh_control); - - if (!PhabricatorEnv::getEnvConfig('diffusion.allow-http-auth')) { - $form->appendRemarkupInstructions( - pht( - 'NOTE: The configuration setting [[ %s | %s ]] is currently '. - 'disabled. You must enable it to activate authenticated access '. - 'to repositories over HTTP.', - '/config/edit/diffusion.allow-http-auth/', - 'diffusion.allow-http-auth')); - } - - $form - ->appendChild($http_control) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Changes')) - ->addCancelButton($prev_uri, pht('Back'))); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Protocols')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php deleted file mode 100644 index 21c392cef5..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php +++ /dev/null @@ -1,1221 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $is_svn = false; - $is_git = false; - $is_hg = false; - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $is_git = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $is_svn = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $is_hg = true; - break; - } - - $has_branches = ($is_git || $is_hg); - $has_local = $repository->usesLocalWorkingCopy(); - $supports_staging = $repository->supportsStaging(); - $supports_automation = $repository->supportsAutomation(); - - $crumbs = $this->buildApplicationCrumbs($is_main = true); - - $title = pht('Edit %s', $repository->getName()); - - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - if ($repository->isTracked()) { - $header->setStatus('fa-check', 'bluegrey', pht('Active')); - } else { - $header->setStatus('fa-ban', 'dark', pht('Inactive')); - } - - $curtain = $this->buildCurtain($repository); - $basic_properties = $this->buildBasicProperties($repository); - - $policy_actions = $this->buildPolicyActions($repository); - $policy_properties = - $this->buildPolicyProperties($repository, $policy_actions); - - $remote_properties = null; - if (!$repository->isHosted()) { - $remote_properties = $this->buildRemoteProperties( - $repository, - $this->buildRemoteActions($repository)); - } - - $encoding_actions = $this->buildEncodingActions($repository); - $encoding_properties = - $this->buildEncodingProperties($repository, $encoding_actions); - - $symbols_actions = $this->buildSymbolsActions($repository); - $symbols_properties = - $this->buildSymbolsProperties($repository, $symbols_actions); - - $hosting_properties = $this->buildHostingProperties( - $repository, - $this->buildHostingActions($repository)); - - - $branches_properties = null; - if ($has_branches) { - $branches_properties = $this->buildBranchesProperties( - $repository, - $this->buildBranchesActions($repository)); - } - - $subversion_properties = null; - if ($is_svn) { - $subversion_properties = $this->buildSubversionProperties( - $repository, - $this->buildSubversionActions($repository)); - } - - $storage_properties = null; - if ($has_local) { - $storage_properties = $this->buildStorageProperties( - $repository, - $this->buildStorageActions($repository)); - } - - $staging_properties = null; - if ($supports_staging) { - $staging_properties = $this->buildStagingProperties( - $repository, - $this->buildStagingActions($repository)); - } - - $automation_properties = null; - if ($supports_automation) { - $automation_properties = $this->buildAutomationProperties( - $repository, - $this->buildAutomationActions($repository)); - } - - $actions_properties = $this->buildActionsProperties( - $repository, - $this->buildActionsActions($repository)); - - $timeline = $this->buildTransactionTimeline( - $repository, - new PhabricatorRepositoryTransactionQuery()); - $timeline->setShouldTerminate(true); - - $boxes = array(); - - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Policies')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($policy_properties); - - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Hosting')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($hosting_properties); - - if ($remote_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Remote')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($remote_properties); - } - - if ($storage_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Storage')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($storage_properties); - } - - if ($staging_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Staging')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($staging_properties); - } - - if ($automation_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Automation')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($automation_properties); - } - - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Text Encoding')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($encoding_properties); - - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Symbols')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($symbols_properties); - - if ($branches_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Branches')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($branches_properties); - } - - if ($subversion_properties) { - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Subversion')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($subversion_properties); - } - - $boxes[] = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Actions')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->addPropertyList($actions_properties); - - $crumbs->setBorder(true); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setCurtain($curtain) - ->addPropertySection(pht('Properties'), $basic_properties) - ->setMainColumn(array( - $boxes, - $timeline, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - - } - - private function buildCurtain(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $curtain = $this->newCurtainView($repository); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Basic Information')) - ->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/')); - $curtain->addAction($edit); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-refresh') - ->setName(pht('Update Now')) - ->setWorkflow(true) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/update/')); - $curtain->addAction($edit); - - $activate = id(new PhabricatorActionView()) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/activate/')) - ->setWorkflow(true); - - if ($repository->isTracked()) { - $activate - ->setIcon('fa-pause') - ->setName(pht('Deactivate Repository')); - } else { - $activate - ->setIcon('fa-play') - ->setName(pht('Activate Repository')); - } - - $curtain->addAction($activate); - - $curtain->addAction( - id(new PhabricatorActionView()) - ->setName(pht('Delete Repository')) - ->setIcon('fa-times') - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/delete/')) - ->setDisabled(true) - ->setWorkflow(true)); - - return $curtain; - } - - private function buildBasicProperties( - PhabricatorRepository $repository) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer); - - $type = PhabricatorRepositoryType::getNameForRepositoryType( - $repository->getVersionControlSystem()); - - $view->addProperty(pht('Type'), $type); - - $callsign = $repository->getCallsign(); - if (!strlen($callsign)) { - $callsign = phutil_tag('em', array(), pht('No Callsign')); - } - $view->addProperty(pht('Callsign'), $callsign); - - $short_name = $repository->getRepositorySlug(); - if ($short_name === null) { - $short_name = $repository->getCloneName(); - $short_name = phutil_tag('em', array(), $short_name); - } - $view->addProperty(pht('Short Name'), $short_name); - - $view->invokeWillRenderEvent(); - - $view->addProperty( - pht('Status'), - $this->buildRepositoryStatus($repository)); - - $view->addProperty( - pht('Update Frequency'), - $this->buildRepositoryUpdateInterval($repository)); - - $description = $repository->getDetail('description'); - $view->addSectionHeader( - pht('Description'), PHUIPropertyListView::ICON_SUMMARY); - if (!strlen($description)) { - $description = phutil_tag('em', array(), pht('No description provided.')); - } else { - $description = new PHUIRemarkupView($viewer, $description); - } - $view->addTextContent($description); - - return $view; - } - - private function buildEncodingActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Text Encoding')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/encoding/')); - $view->addAction($edit); - - return $view; - } - - private function buildEncodingProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $encoding = $repository->getDetail('encoding'); - if (!$encoding) { - $encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)')); - } - - $view->addProperty(pht('Encoding'), $encoding); - - return $view; - } - - private function buildPolicyActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Policies')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/policy/')); - $view->addAction($edit); - - return $view; - } - - private function buildPolicyProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions( - $viewer, - $repository); - - $view_parts = array(); - if (PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) { - $space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID( - $repository); - $view_parts[] = $viewer->renderHandle($space_phid); - } - $view_parts[] = $descriptions[PhabricatorPolicyCapability::CAN_VIEW]; - - $view->addProperty( - pht('Visible To'), - phutil_implode_html(" \xC2\xB7 ", $view_parts)); - - $view->addProperty( - pht('Editable By'), - $descriptions[PhabricatorPolicyCapability::CAN_EDIT]); - - $pushable = $repository->isHosted() - ? $descriptions[DiffusionPushCapability::CAPABILITY] - : phutil_tag('em', array(), pht('Not a Hosted Repository')); - $view->addProperty(pht('Pushable By'), $pushable); - - return $view; - } - - private function buildBranchesActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Branches')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/branches/')); - $view->addAction($edit); - - return $view; - } - - private function buildBranchesProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $default_branch = nonempty( - $repository->getHumanReadableDetail('default-branch'), - phutil_tag('em', array(), $repository->getDefaultBranch())); - $view->addProperty(pht('Default Branch'), $default_branch); - - $track_only = nonempty( - $repository->getHumanReadableDetail('branch-filter', array()), - phutil_tag('em', array(), pht('Track All Branches'))); - $view->addProperty(pht('Track Only'), $track_only); - - $autoclose_only = nonempty( - $repository->getHumanReadableDetail('close-commits-filter', array()), - phutil_tag('em', array(), pht('Autoclose On All Branches'))); - - if ($repository->getDetail('disable-autoclose')) { - $autoclose_only = phutil_tag('em', array(), pht('Disabled')); - } - - $view->addProperty(pht('Autoclose Only'), $autoclose_only); - - return $view; - } - - private function buildSubversionActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Subversion Info')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/subversion/')); - $view->addAction($edit); - - return $view; - } - - private function buildSubversionProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $svn_uuid = nonempty( - $repository->getUUID(), - phutil_tag('em', array(), pht('Not Configured'))); - $view->addProperty(pht('Subversion UUID'), $svn_uuid); - - $svn_subpath = nonempty( - $repository->getHumanReadableDetail('svn-subpath'), - phutil_tag('em', array(), pht('Import Entire Repository'))); - $view->addProperty(pht('Import Only'), $svn_subpath); - - return $view; - } - - private function buildActionsActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Actions')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/actions/')); - $view->addAction($edit); - - return $view; - } - - private function buildActionsProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $notify = $repository->getDetail('herald-disabled') - ? pht('Off') - : pht('On'); - $notify = phutil_tag('em', array(), $notify); - $view->addProperty(pht('Publish/Notify'), $notify); - - $autoclose = $repository->getDetail('disable-autoclose') - ? pht('Off') - : pht('On'); - $autoclose = phutil_tag('em', array(), $autoclose); - $view->addProperty(pht('Autoclose'), $autoclose); - - return $view; - } - - private function buildRemoteActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Remote')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/remote/')); - $view->addAction($edit); - - return $view; - } - - private function buildRemoteProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $view->addProperty( - pht('Remote URI'), - $repository->getHumanReadableDetail('remote-uri')); - - $credential_phid = $repository->getCredentialPHID(); - if ($credential_phid) { - $view->addProperty( - pht('Credential'), - $viewer->renderHandle($credential_phid)); - } - - return $view; - } - - private function buildStorageActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Storage')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/storage/')); - $view->addAction($edit); - - return $view; - } - - private function buildStorageProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $service_phid = $repository->getAlmanacServicePHID(); - if ($service_phid) { - $v_service = $viewer->renderHandle($service_phid); - } else { - $v_service = phutil_tag( - 'em', - array(), - pht('Local')); - } - - $view->addProperty( - pht('Storage Service'), - $v_service); - - $view->addProperty(pht('Storage Path'), $repository->getLocalPath()); - - return $view; - } - - private function buildStagingActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Staging')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/staging/')); - $view->addAction($edit); - - return $view; - } - - private function buildStagingProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $staging_uri = $repository->getStagingURI(); - if (!$staging_uri) { - $staging_uri = phutil_tag('em', array(), pht('No Staging Area')); - } - - $view->addProperty( - pht('Staging Area'), - $staging_uri); - - return $view; - } - - private function buildAutomationActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Automation')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/automation/')); - $view->addAction($edit); - - $can_test = $repository->canPerformAutomation(); - - $test = id(new PhabricatorActionView()) - ->setIcon('fa-gamepad') - ->setName(pht('Test Configuration')) - ->setWorkflow(true) - ->setDisabled(!$can_test) - ->setHref( - $this->getRepositoryControllerURI( - $repository, - 'edit/testautomation/')); - $view->addAction($test); - - return $view; - } - - private function buildAutomationProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $blueprint_phids = $repository->getAutomationBlueprintPHIDs(); - if (!$blueprint_phids) { - $blueprint_view = phutil_tag('em', array(), pht('Not Configured')); - } else { - $blueprint_view = id(new DrydockObjectAuthorizationView()) - ->setUser($viewer) - ->setObjectPHID($repository->getPHID()) - ->setBlueprintPHIDs($blueprint_phids); - } - - $view->addProperty(pht('Automation'), $blueprint_view); - - return $view; - } - - private function buildHostingActions(PhabricatorRepository $repository) { - $user = $this->getRequest()->getUser(); - - $view = id(new PhabricatorActionListView()) - ->setUser($user); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Hosting')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/hosting/')); - $view->addAction($edit); - - if ($repository->canAllowDangerousChanges()) { - if ($repository->shouldAllowDangerousChanges()) { - $changes = id(new PhabricatorActionView()) - ->setIcon('fa-shield') - ->setName(pht('Prevent Dangerous Changes')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) - ->setWorkflow(true); - } else { - $changes = id(new PhabricatorActionView()) - ->setIcon('fa-bullseye') - ->setName(pht('Allow Dangerous Changes')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/dangerous/')) - ->setWorkflow(true); - } - $view->addAction($changes); - } - - return $view; - } - - private function buildHostingProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $user = $this->getRequest()->getUser(); - - $view = id(new PHUIPropertyListView()) - ->setUser($user) - ->setActionList($actions); - - $hosting = $repository->isHosted() - ? pht('Hosted on Phabricator') - : pht('Hosted Elsewhere'); - $view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting)); - - $view->addProperty( - pht('Serve over HTTP'), - phutil_tag( - 'em', - array(), - PhabricatorRepository::getProtocolAvailabilityName( - $repository->getServeOverHTTP()))); - - $view->addProperty( - pht('Serve over SSH'), - phutil_tag( - 'em', - array(), - PhabricatorRepository::getProtocolAvailabilityName( - $repository->getServeOverSSH()))); - - if ($repository->canAllowDangerousChanges()) { - if ($repository->shouldAllowDangerousChanges()) { - $description = pht('Allowed'); - } else { - $description = pht('Not Allowed'); - } - - $view->addProperty( - pht('Dangerous Changes'), - $description); - } - - return $view; - } - - private function buildRepositoryStatus( - PhabricatorRepository $repository) { - - $viewer = $this->getViewer(); - $is_cluster = $repository->getAlmanacServicePHID(); - - $view = new PHUIStatusListView(); - - $messages = id(new PhabricatorRepositoryStatusMessage()) - ->loadAllWhere('repositoryID = %d', $repository->getID()); - $messages = mpull($messages, null, 'getStatusType'); - - if ($repository->isTracked()) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Repository Active'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey') - ->setTarget(pht('Repository Inactive')) - ->setNote( - pht('Activate this repository to begin or resume import.'))); - return $view; - } - - $binaries = array(); - $svnlook_check = false; - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svn'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - - if ($repository->isHosted()) { - if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git-http-backend'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svnserve'; - $binaries[] = 'svnadmin'; - $binaries[] = 'svnlook'; - $svnlook_check = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - } - if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - $binaries[] = 'git-receive-pack'; - $binaries[] = 'git-upload-pack'; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - $binaries[] = 'svnserve'; - $binaries[] = 'svnadmin'; - $binaries[] = 'svnlook'; - $svnlook_check = true; - break; - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - $binaries[] = 'hg'; - break; - } - } - } - - $binaries = array_unique($binaries); - if (!$is_cluster) { - // We're only checking for binaries if we aren't running with a cluster - // configuration. In theory, we could check for binaries on the - // repository host machine, but we'd need to make this more complicated - // to do that. - - foreach ($binaries as $binary) { - $where = Filesystem::resolveBinary($binary); - if (!$where) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget( - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(pht( - "Unable to find this binary in the webserver's PATH. You may ". - "need to configure %s.", - $this->getEnvConfigLink()))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget( - pht('Found Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(phutil_tag('tt', array(), $where))); - } - } - - // This gets checked generically above. However, for svn commit hooks, we - // need this to be in environment.append-paths because subversion strips - // PATH. - if ($svnlook_check) { - $where = Filesystem::resolveBinary('svnlook'); - if ($where) { - $path = substr($where, 0, strlen($where) - strlen('svnlook')); - $dirs = PhabricatorEnv::getEnvConfig('environment.append-paths'); - $in_path = false; - foreach ($dirs as $dir) { - if (Filesystem::isDescendant($path, $dir)) { - $in_path = true; - break; - } - } - if (!$in_path) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget( - pht('Missing Binary %s', phutil_tag('tt', array(), $binary))) - ->setNote(pht( - 'Unable to find this binary in `%s`. '. - 'You need to configure %s and include %s.', - 'environment.append-paths', - $this->getEnvConfigLink(), - $path))); - } - } - } - } - - $doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd'); - - $daemon_instructions = pht( - 'Use %s to start daemons. See %s.', - phutil_tag('tt', array(), 'bin/phd start'), - phutil_tag( - 'a', - array( - 'href' => $doc_href, - ), - pht('Managing Daemons with phd'))); - - - $pull_daemon = id(new PhabricatorDaemonLogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) - ->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon')) - ->setLimit(1) - ->execute(); - - if ($pull_daemon) { - - // TODO: In a cluster environment, we need a daemon on this repository's - // host, specifically, and we aren't checking for that right now. This - // is a reasonable proxy for things being more-or-less correctly set up, - // though. - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Pull Daemon Running'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Pull Daemon Not Running')) - ->setNote($daemon_instructions)); - } - - - $task_daemon = id(new PhabricatorDaemonLogQuery()) - ->setViewer(PhabricatorUser::getOmnipotentUser()) - ->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE) - ->withDaemonClasses(array('PhabricatorTaskmasterDaemon')) - ->setLimit(1) - ->execute(); - if ($task_daemon) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Task Daemon Running'))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Task Daemon Not Running')) - ->setNote($daemon_instructions)); - } - - - if ($is_cluster) { - // Just omit this status check for now in cluster environments. We - // could make a service call and pull it from the repository host - // eventually. - } else if ($repository->usesLocalWorkingCopy()) { - $local_parent = dirname($repository->getLocalPath()); - if (Filesystem::pathExists($local_parent)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Storage Directory OK')) - ->setNote(phutil_tag('tt', array(), $local_parent))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('No Storage Directory')) - ->setNote( - pht( - 'Storage directory %s does not exist, or is not readable by '. - 'the webserver. Create this directory or make it readable.', - phutil_tag('tt', array(), $local_parent)))); - return $view; - } - - $local_path = $repository->getLocalPath(); - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT); - if ($message) { - switch ($message->getStatusCode()) { - case PhabricatorRepositoryStatusMessage::CODE_ERROR: - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Initialization Error')) - ->setNote($message->getParameter('message'))); - return $view; - case PhabricatorRepositoryStatusMessage::CODE_OKAY: - if (Filesystem::pathExists($local_path)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Working Copy OK')) - ->setNote(phutil_tag('tt', array(), $local_path))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Working Copy Error')) - ->setNote( - pht( - 'Working copy %s has been deleted, or is not '. - 'readable by the webserver. Make this directory '. - 'readable. If it has been deleted, the daemons should '. - 'restore it automatically.', - phutil_tag('tt', array(), $local_path)))); - return $view; - } - break; - case PhabricatorRepositoryStatusMessage::CODE_WORKING: - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') - ->setTarget(pht('Initializing Working Copy')) - ->setNote(pht('Daemons are initializing the working copy.'))); - return $view; - default: - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Unknown Init Status')) - ->setNote($message->getStatusCode())); - return $view; - } - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') - ->setTarget(pht('No Working Copy Yet')) - ->setNote( - pht('Waiting for daemons to build a working copy.'))); - return $view; - } - } - - $message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH); - if ($message) { - switch ($message->getStatusCode()) { - case PhabricatorRepositoryStatusMessage::CODE_ERROR: - $message = $message->getParameter('message'); - - $suggestion = null; - if (preg_match('/Permission denied \(publickey\)./', $message)) { - $suggestion = pht( - 'Public Key Error: This error usually indicates that the '. - 'keypair you have configured does not have permission to '. - 'access the repository.'); - } - - $message = phutil_escape_html_newlines($message); - - if ($suggestion !== null) { - $message = array( - phutil_tag('strong', array(), $suggestion), - phutil_tag('br'), - phutil_tag('br'), - phutil_tag('em', array(), pht('Raw Error')), - phutil_tag('br'), - $message, - ); - } - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_WARNING, 'red') - ->setTarget(pht('Update Error')) - ->setNote($message)); - return $view; - case PhabricatorRepositoryStatusMessage::CODE_OKAY: - $ago = (PhabricatorTime::getNow() - $message->getEpoch()); - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Updates OK')) - ->setNote( - pht( - 'Last updated %s (%s ago).', - phabricator_datetime($message->getEpoch(), $viewer), - phutil_format_relative_time_detailed($ago)))); - break; - } - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange') - ->setTarget(pht('Waiting For Update')) - ->setNote( - pht('Waiting for daemons to read updates.'))); - } - - if ($repository->isImporting()) { - $ratio = $repository->loadImportProgress(); - $percentage = sprintf('%.2f%%', 100 * $ratio); - - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green') - ->setTarget(pht('Importing')) - ->setNote( - pht('%s Complete', $percentage))); - } else { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green') - ->setTarget(pht('Fully Imported'))); - } - - if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) { - $view->addItem( - id(new PHUIStatusItemView()) - ->setIcon(PHUIStatusItemView::ICON_UP, 'indigo') - ->setTarget(pht('Prioritized')) - ->setNote(pht('This repository will be updated soon!'))); - } - - return $view; - } - - private function buildRepositoryUpdateInterval( - PhabricatorRepository $repository) { - - $smart_wait = $repository->loadUpdateInterval(); - - $doc_href = PhabricatorEnv::getDoclink( - 'Diffusion User Guide: Repository Updates'); - - return array( - phutil_format_relative_time_detailed($smart_wait), - " \xC2\xB7 ", - phutil_tag( - 'a', - array( - 'href' => $doc_href, - 'target' => '_blank', - ), - pht('Learn More')), - ); - } - - private function buildSymbolsActions(PhabricatorRepository $repository) { - $viewer = $this->getViewer(); - - $view = id(new PhabricatorActionListView()) - ->setUser($viewer); - - $edit = id(new PhabricatorActionView()) - ->setIcon('fa-pencil') - ->setName(pht('Edit Symbols')) - ->setHref( - $this->getRepositoryControllerURI($repository, 'edit/symbol/')); - $view->addAction($edit); - - return $view; - } - - private function buildSymbolsProperties( - PhabricatorRepository $repository, - PhabricatorActionListView $actions) { - - $viewer = $this->getViewer(); - - $view = id(new PHUIPropertyListView()) - ->setUser($viewer) - ->setActionList($actions); - - $languages = $repository->getSymbolLanguages(); - - if ($languages) { - $languages = implode(', ', $languages); - } else { - $languages = phutil_tag('em', array(), pht('Any')); - } - $view->addProperty(pht('Languages'), $languages); - - $sources = $repository->getSymbolSources(); - if ($sources) { - $handles = $viewer->loadHandles($sources); - $sources = $handles->renderList(); - } else { - $sources = phutil_tag('em', array(), pht('This Repository Only')); - } - $view->addProperty(pht('Use Symbols From'), $sources); - return $view; - } - - private function getEnvConfigLink() { - $config_href = '/config/edit/environment.append-paths/'; - return phutil_tag( - 'a', - array( - 'href' => $config_href, - ), - 'environment.append-paths'); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditStagingController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditStagingController.php deleted file mode 100644 index 2d158e61ea..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditStagingController.php +++ /dev/null @@ -1,91 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - - if (!$repository->supportsStaging()) { - return new Aphront404Response(); - } - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_area = $repository->getHumanReadableDetail('staging-uri'); - if ($request->isFormPost()) { - $v_area = $request->getStr('area'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_encoding = PhabricatorRepositoryTransaction::TYPE_STAGING_URI; - - $xactions[] = id(clone $template) - ->setTransactionType($type_encoding) - ->setNewValue($v_area); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Staging')); - - $title = pht('Edit Staging (%s)', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendRemarkupInstructions( - pht( - "To make it easier to run integration tests and builds on code ". - "under review, you can configure a **Staging Area**. When `arc` ". - "creates a diff, it will push a copy of the changes to the ". - "configured staging area with a corresponding tag.". - "\n\n". - "IMPORTANT: This feature is new, experimental, and not supported. ". - "Use it at your own risk.")) - ->appendChild( - id(new AphrontFormTextControl()) - ->setLabel(pht('Staging Area URI')) - ->setName('area') - ->setValue($v_area)) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Staging')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditStorageController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditStorageController.php deleted file mode 100644 index 6aebd13500..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditStorageController.php +++ /dev/null @@ -1,76 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_local = $repository->getLocalPath(); - $errors = array(); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Storage')); - - $title = pht('Edit %s', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $service_phid = $repository->getAlmanacServicePHID(); - if ($service_phid) { - $handles = $this->loadViewerHandles(array($service_phid)); - $v_service = $handles[$service_phid]->renderLink(); - } else { - $v_service = phutil_tag( - 'em', - array(), - pht('Local')); - } - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendChild( - id(new AphrontFormMarkupControl()) - ->setLabel(pht('Storage Service')) - ->setValue($v_service)) - ->appendChild( - id(new AphrontFormMarkupControl()) - ->setName('local') - ->setLabel(pht('Storage Path')) - ->setValue($v_local)) - ->appendRemarkupInstructions( - pht( - "You can not adjust the local path for this repository from the ". - 'web interface.')) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->addCancelButton($edit_uri, pht('Done'))); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Storage')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php deleted file mode 100644 index 6fcc316135..0000000000 --- a/src/applications/diffusion/controller/DiffusionRepositoryEditSubversionController.php +++ /dev/null @@ -1,118 +0,0 @@ -loadDiffusionContextForEdit(); - if ($response) { - return $response; - } - - $viewer = $this->getViewer(); - $drequest = $this->getDiffusionRequest(); - $repository = $drequest->getRepository(); - - switch ($repository->getVersionControlSystem()) { - case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: - case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL: - throw new Exception( - pht('Git and Mercurial do not support editing SVN properties!')); - case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN: - break; - default: - throw new Exception( - pht('Repository has unknown version control system!')); - } - - $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/'); - - $v_subpath = $repository->getHumanReadableDetail('svn-subpath'); - $v_uuid = $repository->getUUID(); - - if ($request->isFormPost()) { - $v_subpath = $request->getStr('subpath'); - $v_uuid = $request->getStr('uuid'); - - $xactions = array(); - $template = id(new PhabricatorRepositoryTransaction()); - - $type_subpath = PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH; - $type_uuid = PhabricatorRepositoryTransaction::TYPE_UUID; - - $xactions[] = id(clone $template) - ->setTransactionType($type_subpath) - ->setNewValue($v_subpath); - - $xactions[] = id(clone $template) - ->setTransactionType($type_uuid) - ->setNewValue($v_uuid); - - id(new PhabricatorRepositoryEditor()) - ->setContinueOnNoEffect(true) - ->setContentSourceFromRequest($request) - ->setActor($viewer) - ->applyTransactions($repository, $xactions); - - return id(new AphrontRedirectResponse())->setURI($edit_uri); - } - - $content = array(); - - $crumbs = $this->buildApplicationCrumbs(); - $crumbs->addTextCrumb(pht('Edit Subversion Info')); - - $title = pht('Edit Subversion Info (%s)', $repository->getName()); - $header = id(new PHUIHeaderView()) - ->setHeader($title) - ->setHeaderIcon('fa-pencil'); - - $policies = id(new PhabricatorPolicyQuery()) - ->setViewer($viewer) - ->setObject($repository) - ->execute(); - - $form = id(new AphrontFormView()) - ->setUser($viewer) - ->appendRemarkupInstructions( - pht( - "You can set the **Repository UUID**, which will help Phabriactor ". - "provide better context in some cases. You can find the UUID of a ". - "repository by running `%s`.\n\n". - "If you want to import only part of a repository, like `trunk/`, ". - "you can set a path in **Import Only**. Phabricator will ignore ". - "commits which do not affect this path.", - 'svn info')) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('uuid') - ->setLabel(pht('Repository UUID')) - ->setValue($v_uuid)) - ->appendChild( - id(new AphrontFormTextControl()) - ->setName('subpath') - ->setLabel(pht('Import Only')) - ->setValue($v_subpath)) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Save Subversion Info')) - ->addCancelButton($edit_uri)); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Subversion')) - ->setBackground(PHUIObjectBoxView::BLUE_PROPERTY) - ->setForm($form); - - $view = id(new PHUITwoColumnView()) - ->setHeader($header) - ->setFooter(array( - $form_box, - )); - - return $this->newPage() - ->setTitle($title) - ->setCrumbs($crumbs) - ->appendChild($view); - } - -} diff --git a/src/applications/diffusion/controller/DiffusionRepositoryListController.php b/src/applications/diffusion/controller/DiffusionRepositoryListController.php index 5897d2f162..eebe0bf91f 100644 --- a/src/applications/diffusion/controller/DiffusionRepositoryListController.php +++ b/src/applications/diffusion/controller/DiffusionRepositoryListController.php @@ -15,16 +15,9 @@ final class DiffusionRepositoryListController extends DiffusionController { protected function buildApplicationCrumbs() { $crumbs = parent::buildApplicationCrumbs(); - $can_create = $this->hasApplicationCapability( - DiffusionCreateRepositoriesCapability::CAPABILITY); - - $crumbs->addAction( - id(new PHUIListItemView()) - ->setName(pht('New Repository')) - ->setHref($this->getApplicationURI('new/')) - ->setDisabled(!$can_create) - ->setWorkflow(!$can_create) - ->setIcon('fa-plus-square')); + id(new DiffusionRepositoryEditEngine()) + ->setViewer($this->getViewer()) + ->addActionToCrumbs($crumbs); return $crumbs; } diff --git a/src/applications/diffusion/controller/DiffusionServeController.php b/src/applications/diffusion/controller/DiffusionServeController.php index f1703655fa..06988ff4e3 100644 --- a/src/applications/diffusion/controller/DiffusionServeController.php +++ b/src/applications/diffusion/controller/DiffusionServeController.php @@ -219,6 +219,7 @@ final class DiffusionServeController extends DiffusionController { $repository = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withIdentifiers(array($identifier)) + ->needURIs(true) ->executeOne(); if (!$repository) { return new PhabricatorVCSResponse( @@ -266,22 +267,25 @@ final class DiffusionServeController extends DiffusionController { // token from SSH. If they're using HTTP username + password auth, they // have to obey the normal HTTP rules. } else { - switch ($repository->getServeOverHTTP()) { - case PhabricatorRepository::SERVE_READONLY: - if ($is_push) { - return new PhabricatorVCSResponse( - 403, - pht('This repository is read-only over HTTP.')); - } - break; - case PhabricatorRepository::SERVE_READWRITE: - // We'll check for push capability below. - break; - case PhabricatorRepository::SERVE_OFF: - default: + if ($request->isHTTPS()) { + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; + } else { + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; + } + + if (!$repository->canServeProtocol($protocol, false)) { + return new PhabricatorVCSResponse( + 403, + pht('This repository is not available over HTTP.')); + } + + if ($is_push) { + $can_write = $repository->canServeProtocol($protocol, true); + if (!$can_write) { return new PhabricatorVCSResponse( 403, - pht('This repository is not available over HTTP.')); + pht('This repository is read-only over HTTP.')); + } } } diff --git a/src/applications/diffusion/editor/DiffusionURIEditor.php b/src/applications/diffusion/editor/DiffusionURIEditor.php index 44ffd83e6e..9059430d0b 100644 --- a/src/applications/diffusion/editor/DiffusionURIEditor.php +++ b/src/applications/diffusion/editor/DiffusionURIEditor.php @@ -410,4 +410,44 @@ final class DiffusionURIEditor return $errors; } + protected function applyFinalEffects( + PhabricatorLiskDAO $object, + array $xactions) { + + // Synchronize the repository state based on the presence of an "Observe" + // URI. + $repository = $object->getRepository(); + + $uris = id(new PhabricatorRepositoryURIQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withRepositories(array($repository)) + ->execute(); + + $observe_uri = null; + foreach ($uris as $uri) { + if ($uri->getIoType() != PhabricatorRepositoryURI::IO_OBSERVE) { + continue; + } + + $observe_uri = $uri; + break; + } + + if ($observe_uri) { + $repository + ->setHosted(false) + ->setDetail('remote-uri', (string)$observe_uri->getEffectiveURI()) + ->setCredentialPHID($observe_uri->getCredentialPHID()); + } else { + $repository + ->setHosted(true) + ->setDetail('remote-uri', null) + ->setCredentialPHID(null); + } + + $repository->save(); + + return $xactions; + } + } diff --git a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php index efb165d801..156e1c436f 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryManagementPanel.php @@ -136,7 +136,7 @@ abstract class DiffusionRepositoryManagementPanel $repository = $this->getRepository(); $id = $repository->getID(); - return "/diffusion/editpro/{$id}/page/{$page}/"; + return "/diffusion/edit/{$id}/page/{$page}/"; } diff --git a/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php b/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php index eba7722f2f..a601bd1d64 100644 --- a/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php +++ b/src/applications/diffusion/management/DiffusionRepositoryStatusManagementPanel.php @@ -135,7 +135,12 @@ final class DiffusionRepositoryStatusManagementPanel } if ($repository->isHosted()) { - if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) { + $proto_https = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTPS; + $proto_http = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_HTTP; + $can_http = $repository->canServeProtocol($proto_http, false) || + $repository->canServeProtocol($proto_https, false); + + if ($can_http) { switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $binaries[] = 'git-http-backend'; @@ -151,7 +156,12 @@ final class DiffusionRepositoryStatusManagementPanel break; } } - if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) { + + + $proto_ssh = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; + $can_ssh = $repository->canServeProtocol($proto_ssh, false); + + if ($can_ssh) { switch ($repository->getVersionControlSystem()) { case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT: $binaries[] = 'git-receive-pack'; diff --git a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php index 60b929f7c4..78252fb8d9 100644 --- a/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php +++ b/src/applications/diffusion/ssh/DiffusionSSHWorkflow.php @@ -185,24 +185,19 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow { $repository = id(new PhabricatorRepositoryQuery()) ->setViewer($viewer) ->withIdentifiers(array($identifier)) + ->needURIs(true) ->executeOne(); if (!$repository) { throw new Exception( pht('No repository "%s" exists!', $identifier)); } - switch ($repository->getServeOverSSH()) { - case PhabricatorRepository::SERVE_READONLY: - case PhabricatorRepository::SERVE_READWRITE: - // If we have read or read/write access, proceed for now. We will - // check write access when the user actually issues a write command. - break; - case PhabricatorRepository::SERVE_OFF: - default: - throw new Exception( - pht( - 'This repository ("%s") is not available over SSH.', - $repository->getDisplayName())); + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; + if (!$repository->canServeProtocol($protocol, false)) { + throw new Exception( + pht( + 'This repository ("%s") is not available over SSH.', + $repository->getDisplayName())); } return $repository; @@ -224,35 +219,27 @@ abstract class DiffusionSSHWorkflow extends PhabricatorSSHWorkflow { 'user account.')); } - switch ($repository->getServeOverSSH()) { - case PhabricatorRepository::SERVE_READONLY: - if ($protocol_command !== null) { - throw new Exception( - pht( - 'This repository is read-only over SSH (tried to execute '. - 'protocol command "%s").', - $protocol_command)); - } else { - throw new Exception( - pht('This repository is read-only over SSH.')); - } - break; - case PhabricatorRepository::SERVE_READWRITE: - $can_push = PhabricatorPolicyFilter::hasCapability( - $viewer, - $repository, - DiffusionPushCapability::CAPABILITY); - if (!$can_push) { - throw new Exception( - pht('You do not have permission to push to this repository.')); - } - break; - case PhabricatorRepository::SERVE_OFF: - default: - // This shouldn't be reachable because we don't get this far if the - // repository isn't enabled, but kick them out anyway. + $protocol = PhabricatorRepositoryURI::BUILTIN_PROTOCOL_SSH; + if ($repository->canServeProtocol($protocol, true)) { + $can_push = PhabricatorPolicyFilter::hasCapability( + $viewer, + $repository, + DiffusionPushCapability::CAPABILITY); + if (!$can_push) { throw new Exception( - pht('This repository is not available over SSH.')); + pht('You do not have permission to push to this repository.')); + } + } else { + if ($protocol_command !== null) { + throw new Exception( + pht( + 'This repository is read-only over SSH (tried to execute '. + 'protocol command "%s").', + $protocol_command)); + } else { + throw new Exception( + pht('This repository is read-only over SSH.')); + } } $this->hasWriteAccess = true; diff --git a/src/applications/repository/editor/PhabricatorRepositoryEditor.php b/src/applications/repository/editor/PhabricatorRepositoryEditor.php index c528c91c99..fb97d7d908 100644 --- a/src/applications/repository/editor/PhabricatorRepositoryEditor.php +++ b/src/applications/repository/editor/PhabricatorRepositoryEditor.php @@ -26,18 +26,7 @@ final class PhabricatorRepositoryEditor $types[] = PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH; $types[] = PhabricatorRepositoryTransaction::TYPE_NOTIFY; $types[] = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE; - $types[] = PhabricatorRepositoryTransaction::TYPE_REMOTE_URI; - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN; - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_KEY; - $types[] = PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE; - $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN; - $types[] = PhabricatorRepositoryTransaction::TYPE_HTTP_PASS; - $types[] = PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH; - $types[] = PhabricatorRepositoryTransaction::TYPE_HOSTING; - $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP; - $types[] = PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH; $types[] = PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY; - $types[] = PhabricatorRepositoryTransaction::TYPE_CREDENTIAL; $types[] = PhabricatorRepositoryTransaction::TYPE_DANGEROUS; $types[] = PhabricatorRepositoryTransaction::TYPE_SLUG; $types[] = PhabricatorRepositoryTransaction::TYPE_SERVICE; @@ -83,20 +72,8 @@ final class PhabricatorRepositoryEditor return (int)!$object->getDetail('herald-disabled'); case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: return (int)!$object->getDetail('disable-autoclose'); - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: - return $object->getDetail('remote-uri'); - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: - return $object->getLocalPath(); - case PhabricatorRepositoryTransaction::TYPE_HOSTING: - return $object->isHosted(); - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: - return $object->getServeOverHTTP(); - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: - return $object->getServeOverSSH(); case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: return $object->getPushPolicy(); - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: - return $object->getCredentialPHID(); case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: return $object->shouldAllowDangerousChanges(); case PhabricatorRepositoryTransaction::TYPE_SLUG: @@ -130,19 +107,8 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: case PhabricatorRepositoryTransaction::TYPE_UUID: case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: - case PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN: - case PhabricatorRepositoryTransaction::TYPE_SSH_KEY: - case PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE: - case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN: - case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS: - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: case PhabricatorRepositoryTransaction::TYPE_VCS: - case PhabricatorRepositoryTransaction::TYPE_HOSTING: - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: case PhabricatorRepositoryTransaction::TYPE_SERVICE: case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE: @@ -205,22 +171,8 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: $object->setDetail('disable-autoclose', (int)!$xaction->getNewValue()); break; - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: - $object->setDetail('remote-uri', $xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: - $object->setLocalPath($xaction->getNewValue()); - break; - case PhabricatorRepositoryTransaction::TYPE_HOSTING: - return $object->setHosted($xaction->getNewValue()); - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: - return $object->setServeOverHTTP($xaction->getNewValue()); - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: - return $object->setServeOverSSH($xaction->getNewValue()); case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: return $object->setPushPolicy($xaction->getNewValue()); - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: - return $object->setCredentialPHID($xaction->getNewValue()); case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: $object->setDetail('allow-dangerous-changes', $xaction->getNewValue()); return; @@ -258,27 +210,6 @@ final class PhabricatorRepositoryEditor PhabricatorApplicationTransaction $xaction) { switch ($xaction->getTransactionType()) { - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: - // Adjust the object <-> credential edge for this repository. - - $old_phid = $xaction->getOldValue(); - $new_phid = $xaction->getNewValue(); - - $editor = new PhabricatorEdgeEditor(); - - $edge_type = PhabricatorObjectUsesCredentialsEdgeType::EDGECONST; - $src_phid = $object->getPHID(); - - if ($old_phid) { - $editor->removeEdge($src_phid, $edge_type, $old_phid); - } - - if ($new_phid) { - $editor->addEdge($src_phid, $edge_type, $new_phid); - } - - $editor->save(); - break; case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: DrydockAuthorization::applyAuthorizationChanges( $this->getActor(), @@ -304,21 +235,10 @@ final class PhabricatorRepositoryEditor case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY: case PhabricatorRepositoryTransaction::TYPE_UUID: case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH: - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: - case PhabricatorRepositoryTransaction::TYPE_SSH_LOGIN: - case PhabricatorRepositoryTransaction::TYPE_SSH_KEY: - case PhabricatorRepositoryTransaction::TYPE_SSH_KEYFILE: - case PhabricatorRepositoryTransaction::TYPE_HTTP_LOGIN: - case PhabricatorRepositoryTransaction::TYPE_HTTP_PASS: - case PhabricatorRepositoryTransaction::TYPE_LOCAL_PATH: case PhabricatorRepositoryTransaction::TYPE_VCS: case PhabricatorRepositoryTransaction::TYPE_NOTIFY: case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE: - case PhabricatorRepositoryTransaction::TYPE_HOSTING: - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_HTTP: - case PhabricatorRepositoryTransaction::TYPE_PROTOCOL_SSH: case PhabricatorRepositoryTransaction::TYPE_PUSH_POLICY: - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: case PhabricatorRepositoryTransaction::TYPE_DANGEROUS: case PhabricatorRepositoryTransaction::TYPE_SLUG: case PhabricatorRepositoryTransaction::TYPE_SERVICE: @@ -388,38 +308,6 @@ final class PhabricatorRepositoryEditor } break; - case PhabricatorRepositoryTransaction::TYPE_REMOTE_URI: - foreach ($xactions as $xaction) { - $new_uri = $xaction->getNewValue(); - try { - PhabricatorRepository::assertValidRemoteURI($new_uri); - } catch (Exception $ex) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - $ex->getMessage(), - $xaction); - } - } - break; - - case PhabricatorRepositoryTransaction::TYPE_CREDENTIAL: - $ok = PassphraseCredentialControl::validateTransactions( - $this->getActor(), - $xactions); - if (!$ok) { - foreach ($xactions as $xaction) { - $errors[] = new PhabricatorApplicationTransactionValidationError( - $type, - pht('Invalid'), - pht( - 'The selected credential does not exist, or you do not have '. - 'permission to use it.'), - $xaction); - } - } - break; - case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS: foreach ($xactions as $xaction) { $old = nonempty($xaction->getOldValue(), array()); @@ -721,6 +609,17 @@ final class PhabricatorRepositoryEditor } if ($this->getIsNewObject()) { + // The default state of repositories is to be hosted, if they are + // enabled without configuring any "Observe" URIs. + $object->setHosted(true); + $object->save(); + + // Create this repository's builtin URIs. + $builtin_uris = $object->newBuiltinURIs(); + foreach ($builtin_uris as $uri) { + $uri->save(); + } + id(new DiffusionRepositoryClusterEngine()) ->setViewer($this->getActor()) ->setRepository($object) diff --git a/src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php b/src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php index 300f8ec50f..56a75764c8 100644 --- a/src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php +++ b/src/applications/repository/management/PhabricatorRepositoryManagementWorkflow.php @@ -12,6 +12,7 @@ abstract class PhabricatorRepositoryManagementWorkflow $query = id(new PhabricatorRepositoryQuery()) ->setViewer($this->getViewer()) + ->needURIs(true) ->withIdentifiers($identifiers); $query->execute(); diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php index 5762386119..1ca585851f 100644 --- a/src/applications/repository/storage/PhabricatorRepository.php +++ b/src/applications/repository/storage/PhabricatorRepository.php @@ -35,10 +35,6 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO const TABLE_PARENTS = 'repository_parents'; const TABLE_COVERAGE = 'repository_coverage'; - const SERVE_OFF = 'off'; - const SERVE_READONLY = 'readonly'; - const SERVE_READWRITE = 'readwrite'; - const BECAUSE_REPOSITORY_IMPORTING = 'auto/importing'; const BECAUSE_AUTOCLOSE_DISABLED = 'auto/disabled'; const BECAUSE_NOT_ON_AUTOCLOSE_BRANCH = 'auto/nobranch'; @@ -1201,26 +1197,7 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO * @task uri */ public function getPublicCloneURI() { - $uri = $this->getCloneURIObject(); - - // Make sure we don't leak anything if this repo is using HTTP Basic Auth - // with the credentials in the URI or something zany like that. - - // If repository is not accessed over SSH we remove both username and - // password. - if (!$this->isHosted()) { - if (!$this->shouldUseSSH()) { - $uri->setUser(null); - - // This might be a Git URI or a normal URI. If it's Git, there's no - // password support. - if ($uri instanceof PhutilURI) { - $uri->setPass(null); - } - } - } - - return (string)$uri; + return (string)$this->getCloneURIObject(); } @@ -1303,91 +1280,19 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO } } - // Choose the best URI: pick a read/write URI over a URI which is not - // read/write, and SSH over HTTP. + // TODO: This should be cleaned up to deal with all the new URI handling. + $another_copy = id(new PhabricatorRepositoryQuery()) + ->setViewer(PhabricatorUser::getOmnipotentUser()) + ->withPHIDs(array($this->getPHID())) + ->needURIs(true) + ->executeOne(); - $serve_ssh = $this->getServeOverSSH(); - $serve_http = $this->getServeOverHTTP(); - - if ($serve_ssh === self::SERVE_READWRITE) { - return $this->getSSHCloneURIObject(); - } else if ($serve_http === self::SERVE_READWRITE) { - return $this->getHTTPCloneURIObject(); - } else if ($serve_ssh !== self::SERVE_OFF) { - return $this->getSSHCloneURIObject(); - } else if ($serve_http !== self::SERVE_OFF) { - return $this->getHTTPCloneURIObject(); - } else { - return null; - } - } - - - /** - * Get the repository's SSH clone/checkout URI, if one exists. - */ - public function getSSHCloneURIObject() { - if (!$this->isHosted()) { - if ($this->shouldUseSSH()) { - return $this->getRemoteURIObject(); - } else { - return null; - } - } - - $serve_ssh = $this->getServeOverSSH(); - if ($serve_ssh === self::SERVE_OFF) { + $clone_uris = $another_copy->getCloneURIs(); + if (!$clone_uris) { return null; } - $uri = new PhutilURI(PhabricatorEnv::getProductionURI($this->getURI())); - - if ($this->isSVN()) { - $uri->setProtocol('svn+ssh'); - } else { - $uri->setProtocol('ssh'); - } - - if ($this->isGit()) { - $uri->setPath($uri->getPath().$this->getCloneName().'.git'); - } else if ($this->isHg()) { - $uri->setPath($uri->getPath().$this->getCloneName().'/'); - } - - $ssh_user = AlmanacKeys::getClusterSSHUser(); - if (strlen($ssh_user)) { - $uri->setUser($ssh_user); - } - - $ssh_host = PhabricatorEnv::getEnvConfig('diffusion.ssh-host'); - if (strlen($ssh_host)) { - $uri->setDomain($ssh_host); - } - - $uri->setPort(PhabricatorEnv::getEnvConfig('diffusion.ssh-port')); - - return $uri; - } - - - /** - * Get the repository's HTTP clone/checkout URI, if one exists. - */ - public function getHTTPCloneURIObject() { - if (!$this->isHosted()) { - if ($this->shouldUseHTTP()) { - return $this->getRemoteURIObject(); - } else { - return null; - } - } - - $serve_http = $this->getServeOverHTTP(); - if ($serve_http === self::SERVE_OFF) { - return null; - } - - return $this->getRawHTTPCloneURIObject(); + return head($clone_uris); } private function getRawHTTPCloneURIObject() { @@ -1554,56 +1459,31 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO return $this->setDetail('hosting-enabled', $enabled); } - public function getServeOverHTTP() { - if ($this->isSVN()) { - return self::SERVE_OFF; + public function canServeProtocol($protocol, $write) { + if (!$this->isTracked()) { + return false; } - $serve = $this->getDetail('serve-over-http', self::SERVE_OFF); - return $this->normalizeServeConfigSetting($serve); - } - public function setServeOverHTTP($mode) { - return $this->setDetail('serve-over-http', $mode); - } + $clone_uris = $this->getCloneURIs(); + foreach ($clone_uris as $uri) { + if ($uri->getBuiltinProtocol() !== $protocol) { + continue; + } - public function getServeOverSSH() { - $serve = $this->getDetail('serve-over-ssh', self::SERVE_OFF); - return $this->normalizeServeConfigSetting($serve); - } + $io_type = $uri->getEffectiveIoType(); + if ($io_type == PhabricatorRepositoryURI::IO_READWRITE) { + return true; + } - public function setServeOverSSH($mode) { - return $this->setDetail('serve-over-ssh', $mode); - } - - public static function getProtocolAvailabilityName($constant) { - switch ($constant) { - case self::SERVE_OFF: - return pht('Off'); - case self::SERVE_READONLY: - return pht('Read Only'); - case self::SERVE_READWRITE: - return pht('Read/Write'); - default: - return pht('Unknown'); - } - } - - private function normalizeServeConfigSetting($value) { - switch ($value) { - case self::SERVE_OFF: - case self::SERVE_READONLY: - return $value; - case self::SERVE_READWRITE: - if ($this->isHosted()) { - return self::SERVE_READWRITE; - } else { - return self::SERVE_READONLY; + if (!$write) { + if ($io_type == PhabricatorRepositoryURI::IO_READ) { + return true; } - default: - return self::SERVE_OFF; + } } - } + return false; + } /** * Raise more useful errors when there are basic filesystem problems. @@ -2133,10 +2013,9 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO continue; } - // If we don't have a persisted version of the URI, add the builtin - // version. - if (empty($custom_map[$builtin_key])) { - $uris[] = $builtin_uri; + // If the URI exists, make sure it's marked as not being disabled. + if (isset($custom_map[$builtin_key])) { + $uris[$custom_map[$builtin_key]]->setIsDisabled(false); } } @@ -2156,10 +2035,42 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO return $this->assertAttached($this->uris); } - protected function newBuiltinURIs() { + public function getCloneURIs() { + $uris = $this->getURIs(); + + $clone = array(); + foreach ($uris as $uri) { + if (!$uri->isBuiltin()) { + continue; + } + + if ($uri->getIsDisabled()) { + continue; + } + + $io_type = $uri->getEffectiveIoType(); + $is_clone = + ($io_type == PhabricatorRepositoryURI::IO_READ) || + ($io_type == PhabricatorRepositoryURI::IO_READWRITE); + + if (!$is_clone) { + continue; + } + + $clone[] = $uri; + } + + return msort($clone, 'getURIScore'); + } + + + public function newBuiltinURIs() { $has_callsign = ($this->getCallsign() !== null); $has_shortname = ($this->getRepositorySlug() !== null); + // TODO: For now, never enable these because they don't work yet. + $has_shortname = false; + $identifier_map = array( PhabricatorRepositoryURI::BUILTIN_IDENTIFIER_CALLSIGN => $has_callsign, PhabricatorRepositoryURI::BUILTIN_IDENTIFIER_SHORTNAME => $has_shortname, @@ -2176,6 +2087,11 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO $has_http = !PhabricatorEnv::getEnvConfig('security.require-https'); $has_http = ($has_http && $allow_http); + // HTTP is not supported for Subversion. + if ($this->isSVN()) { + $has_http = false; + } + // TODO: Maybe allow users to disable this by default somehow? $has_ssh = true; @@ -2188,12 +2104,16 @@ final class PhabricatorRepository extends PhabricatorRepositoryDAO $uris = array(); foreach ($protocol_map as $protocol => $proto_supported) { foreach ($identifier_map as $identifier => $id_supported) { + // This is just a dummy value because it can't be empty; we'll force + // it to a proper value when using it in the UI. + $builtin_uri = "{$protocol}://{$identifier}"; $uris[] = PhabricatorRepositoryURI::initializeNewURI() ->setRepositoryPHID($this->getPHID()) ->attachRepository($this) ->setBuiltinProtocol($protocol) ->setBuiltinIdentifier($identifier) - ->setIsDisabled(!$proto_supported || !$id_supported); + ->setURI($builtin_uri) + ->setIsDisabled((int)(!$proto_supported || !$id_supported)); } } diff --git a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php index 76e75a70b0..e02b670f75 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php +++ b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php @@ -351,15 +351,15 @@ final class PhabricatorRepositoryTransaction '%s changed the availability of this repository over HTTP from '. '"%s" to "%s".', $this->renderHandleLink($author_phid), - PhabricatorRepository::getProtocolAvailabilityName($old), - PhabricatorRepository::getProtocolAvailabilityName($new)); + $old, + $new); case self::TYPE_PROTOCOL_SSH: return pht( '%s changed the availability of this repository over SSH from '. '"%s" to "%s".', $this->renderHandleLink($author_phid), - PhabricatorRepository::getProtocolAvailabilityName($old), - PhabricatorRepository::getProtocolAvailabilityName($new)); + $old, + $new); case self::TYPE_PUSH_POLICY: return pht( '%s changed the push policy of this repository from "%s" to "%s".', diff --git a/src/applications/repository/storage/PhabricatorRepositoryURI.php b/src/applications/repository/storage/PhabricatorRepositoryURI.php index f432971d29..227b13012f 100644 --- a/src/applications/repository/storage/PhabricatorRepositoryURI.php +++ b/src/applications/repository/storage/PhabricatorRepositoryURI.php @@ -246,6 +246,11 @@ final class PhabricatorRepositoryURI ); $uri = new PhutilURI($raw_uri); + + // Make sure to remove any password from the URI before we do anything + // with it; this should always be provided by the associated credential. + $uri->setPass(null); + if (!$uri->getProtocol()) { $git_uri = new PhutilGitURI($raw_uri); @@ -409,7 +414,7 @@ final class PhabricatorRepositoryURI if ($this->isBuiltin()) { $options[] = self::IO_READ; - $options[] = self::IO_WRITE; + $options[] = self::IO_READWRITE; } else { $options[] = self::IO_OBSERVE; $options[] = self::IO_MIRROR; @@ -536,6 +541,25 @@ final class PhabricatorRepositoryURI ->setProtocol($protocol); } + public function getURIScore() { + $score = 0; + + $io_points = array( + self::IO_READWRITE => 20, + self::IO_READ => 10, + ); + $score += idx($io_points, $this->getEffectiveIoType(), 0); + + $protocol_points = array( + self::BUILTIN_PROTOCOL_SSH => 3, + self::BUILTIN_PROTOCOL_HTTPS => 2, + self::BUILTIN_PROTOCOL_HTTP => 1, + ); + $score += idx($protocol_points, $this->getBuiltinProtocol(), 0); + + return $score; + } + /* -( PhabricatorApplicationTransactionInterface )------------------------- */ diff --git a/src/applications/transactions/editengine/PhabricatorEditEngine.php b/src/applications/transactions/editengine/PhabricatorEditEngine.php index f67860f938..2c283a27f3 100644 --- a/src/applications/transactions/editengine/PhabricatorEditEngine.php +++ b/src/applications/transactions/editengine/PhabricatorEditEngine.php @@ -2035,6 +2035,10 @@ abstract class PhabricatorEditEngine return $fields; } + if (!$this->getSelectedPage()) { + return $fields; + } + $page_picks = array(); $default_key = head($pages)->getKey(); foreach ($pages as $page_key => $page) {