mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-18 19:40:55 +01:00
Swap Repository Edit UI to new code
Summary: Ref T10748. This needs more extensive testing and is sure to have some rough edges, but seems to basically work so far. Throwing this up so I can work through it more deliberately and make notes. Test Plan: - Ran migration. - Used `bin/repository list` to list existing repositories. - Used `bin/repository update <repository>` to update various repositories. - Updated a migrated, hosted Git repository. - Updated a migrated, observed Git repository. - Converted an observed repository into a hosted repository by toggling the I/O mode of the URI. - Conveted a hosted repository into an observed repository by toggling it back. - Created and activated a new empty hosted Git repository. - Created and activated an observed Git repository. - Updated a mirrored repository. - Cloned and pushed over HTTP. - Tried to HTTP push a read-only repository. - Cloned and pushed over SSH. - Tried to SSH push a read-only repository. - Updated several Mercurial repositories. - Updated several Subversion repositories. - Created and edited repositories via the API. Reviewers: chad Reviewed By: chad Maniphest Tasks: T10748 Differential Revision: https://secure.phabricator.com/D15842
This commit is contained in:
parent
42eaa88f80
commit
29d1115037
27 changed files with 328 additions and 3897 deletions
82
resources/sql/autopatches/20160503.repo.05.urimigrate.php
Normal file
82
resources/sql/autopatches/20160503.repo.05.urimigrate.php
Normal file
|
@ -0,0 +1,82 @@
|
|||
<?php
|
||||
|
||||
$table = new PhabricatorRepository();
|
||||
$conn_w = $table->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()));
|
||||
}
|
||||
}
|
|
@ -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',
|
||||
|
|
|
@ -57,7 +57,7 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
|
|||
'/diffusion/' => array(
|
||||
$this->getQueryRoutePattern()
|
||||
=> 'DiffusionRepositoryListController',
|
||||
$this->getEditRoutePattern('editpro/') =>
|
||||
$this->getEditRoutePattern('edit/') =>
|
||||
'DiffusionRepositoryEditproController',
|
||||
'new/' => 'DiffusionRepositoryNewController',
|
||||
'(?P<edit>create)/' => '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',
|
||||
'(?P<edit>remote)/' => 'DiffusionRepositoryCreateController',
|
||||
'(?P<edit>policy)/' => 'DiffusionRepositoryCreateController',
|
||||
'storage/' => 'DiffusionRepositoryEditStorageController',
|
||||
'delete/' => 'DiffusionRepositoryEditDeleteController',
|
||||
'hosting/' => 'DiffusionRepositoryEditHostingController',
|
||||
'(?P<serve>serve)/' => 'DiffusionRepositoryEditHostingController',
|
||||
'update/' => 'DiffusionRepositoryEditUpdateController',
|
||||
'symbol/' => 'DiffusionRepositorySymbolsController',
|
||||
'staging/' => 'DiffusionRepositoryEditStagingController',
|
||||
'automation/' => 'DiffusionRepositoryEditAutomationController',
|
||||
'testautomation/' => 'DiffusionRepositoryTestAutomationController',
|
||||
),
|
||||
'pathtree/(?P<dblob>.*)' => 'DiffusionPathTreeController',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,849 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryCreateController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
private $edit;
|
||||
private $repository;
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$viewer = $request->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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditActionsController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditAutomationController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,193 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditBasicController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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(<<<EOTEXT
|
||||
You can also create a `%s` file at the repository root (or in any
|
||||
subdirectory) to provide information about the repository. These formats are
|
||||
supported:
|
||||
|
||||
| File Name | Rendered As... |
|
||||
|-----------|-----------------|
|
||||
| `%s` | Plain Text |
|
||||
| `%s` | Plain Text |
|
||||
| `%s` | Remarkup |
|
||||
| `%s` | Remarkup |
|
||||
| `%s` | \xC2\xA1Fiesta! |
|
||||
EOTEXT
|
||||
,
|
||||
'README',
|
||||
'README',
|
||||
'README.txt',
|
||||
'README.remarkup',
|
||||
'README.md',
|
||||
'README.rainbow');
|
||||
}
|
||||
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditBranchesController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditEncodingController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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(<<<EOT
|
||||
If source code in this repository uses a character encoding other than UTF-8
|
||||
(for example, `ISO-8859-1`), specify it here.
|
||||
|
||||
**Normally, you can leave this field blank.** If your source code is written in
|
||||
ASCII or UTF-8, everything will work correctly.
|
||||
|
||||
Source files will be translated from the specified encoding to UTF-8 when they
|
||||
are read from the repository, before they are displayed in Diffusion.
|
||||
|
||||
See [[%s | UTF-8 and Character Encoding]] for more information on how
|
||||
Phabricator handles text encodings.
|
||||
EOT
|
||||
,
|
||||
PhabricatorEnv::getDoclink('User Guide: UTF-8 and Character Encoding'));
|
||||
}
|
||||
|
||||
}
|
|
@ -1,288 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditHostingController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
private $serve;
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,91 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditStagingController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditStorageController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class DiffusionRepositoryEditSubversionController
|
||||
extends DiffusionRepositoryEditController {
|
||||
|
||||
public function handleRequest(AphrontRequest $request) {
|
||||
$response = $this->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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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}/";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -12,6 +12,7 @@ abstract class PhabricatorRepositoryManagementWorkflow
|
|||
|
||||
$query = id(new PhabricatorRepositoryQuery())
|
||||
->setViewer($this->getViewer())
|
||||
->needURIs(true)
|
||||
->withIdentifiers($identifiers);
|
||||
|
||||
$query->execute();
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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".',
|
||||
|
|
|
@ -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 )------------------------- */
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue