Page MenuHomestyx hydra

No OneTemporary

diff --git a/resources/sql/autopatches/20160111.repo.01.slugx.sql b/resources/sql/autopatches/20160111.repo.01.slugx.sql
new file mode 100644
index 0000000000..41be6517d0
--- /dev/null
+++ b/resources/sql/autopatches/20160111.repo.01.slugx.sql
@@ -0,0 +1,2 @@
+UPDATE {$NAMESPACE}_repository.repository_transaction
+ SET transactionType = 'repo:slug' WHERE transactionType = 'repo:clone-name';
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
index 1e4de51cff..65f7dd0974 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
@@ -1,176 +1,163 @@
<?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_clone_name = $repository->getRepositorySlug();
+ $v_slug = $repository->getRepositorySlug();
$v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
$repository->getPHID(),
PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
$e_name = true;
$e_slug = null;
$errors = array();
$validation_exception = null;
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_desc = $request->getStr('description');
$v_projects = $request->getArr('projectPHIDs');
-
- if ($repository->isHosted()) {
- $v_clone_name = $request->getStr('cloneName');
- }
+ $v_slug = $request->getStr('slug');
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_clone_name = PhabricatorRepositoryTransaction::TYPE_CLONE_NAME;
+ $type_slug = PhabricatorRepositoryTransaction::TYPE_SLUG;
$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_clone_name)
- ->setNewValue($v_clone_name);
+ ->setTransactionType($type_slug)
+ ->setNewValue($v_slug);
$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);
return id(new AphrontRedirectResponse())->setURI($edit_uri);
} catch (PhabricatorApplicationTransactionValidationException $ex) {
$validation_exception = $ex;
- $e_slug = $ex->getShortMessage($type_clone_name);
+ $e_slug = $ex->getShortMessage($type_slug);
}
}
}
$crumbs = $this->buildApplicationCrumbs();
$crumbs->addTextCrumb(pht('Edit Basics'));
$title = pht('Edit %s', $repository->getName());
$form = id(new AphrontFormView())
->setUser($viewer)
->appendChild(
id(new AphrontFormTextControl())
->setName('name')
->setLabel(pht('Name'))
->setValue($v_name)
- ->setError($e_name));
-
- if ($repository->isHosted()) {
- $form
- ->appendChild(
- id(new AphrontFormTextControl())
- ->setName('cloneName')
- ->setLabel(pht('Clone/Checkout As'))
- ->setValue($v_clone_name)
- ->setError($e_slug)
- ->setCaption(
- pht(
- 'Optional directory name to use when cloning or checking out '.
- 'this repository.')));
- }
-
- $form
+ ->setError($e_name))
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setName('slug')
+ ->setLabel(pht('Short Name'))
+ ->setValue($v_slug)
+ ->setError($e_slug))
->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());
$object_box = id(new PHUIObjectBoxView())
->setHeaderText($title)
->setValidationException($validation_exception)
->setForm($form)
->setFormErrors($errors);
return $this->newPage()
->setTitle($title)
->setCrumbs($crumbs)
->appendChild($object_box);
}
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');
}
}
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
index 4a48f02bf9..886809dedd 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
@@ -1,1325 +1,1322 @@
<?php
final class DiffusionRepositoryEditMainController
extends DiffusionRepositoryEditController {
public function handleRequest(AphrontRequest $request) {
$response = $this->loadDiffusionContextForEdit();
if ($response) {
return $response;
}
$viewer = $this->getViewer();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
$is_svn = false;
$is_git = false;
$is_hg = false;
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$is_git = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$is_svn = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$is_hg = true;
break;
}
$has_branches = ($is_git || $is_hg);
$has_local = $repository->usesLocalWorkingCopy();
$supports_staging = $repository->supportsStaging();
$supports_automation = $repository->supportsAutomation();
$crumbs = $this->buildApplicationCrumbs($is_main = true);
$title = pht('Edit %s', $repository->getName());
$header = id(new PHUIHeaderView())
->setHeader($title);
if ($repository->isTracked()) {
$header->setStatus('fa-check', 'bluegrey', pht('Active'));
} else {
$header->setStatus('fa-ban', 'dark', pht('Inactive'));
}
$basic_actions = $this->buildBasicActions($repository);
$basic_properties =
$this->buildBasicProperties($repository, $basic_actions);
$policy_actions = $this->buildPolicyActions($repository);
$policy_properties =
$this->buildPolicyProperties($repository, $policy_actions);
$remote_properties = null;
if (!$repository->isHosted()) {
$remote_properties = $this->buildRemoteProperties(
$repository,
$this->buildRemoteActions($repository));
}
$encoding_actions = $this->buildEncodingActions($repository);
$encoding_properties =
$this->buildEncodingProperties($repository, $encoding_actions);
$symbols_actions = $this->buildSymbolsActions($repository);
$symbols_properties =
$this->buildSymbolsProperties($repository, $symbols_actions);
$hosting_properties = $this->buildHostingProperties(
$repository,
$this->buildHostingActions($repository));
$branches_properties = null;
if ($has_branches) {
$branches_properties = $this->buildBranchesProperties(
$repository,
$this->buildBranchesActions($repository));
}
$subversion_properties = null;
if ($is_svn) {
$subversion_properties = $this->buildSubversionProperties(
$repository,
$this->buildSubversionActions($repository));
}
$storage_properties = null;
if ($has_local) {
$storage_properties = $this->buildStorageProperties(
$repository,
$this->buildStorageActions($repository));
}
$staging_properties = null;
if ($supports_staging) {
$staging_properties = $this->buildStagingProperties(
$repository,
$this->buildStagingActions($repository));
}
$automation_properties = null;
if ($supports_automation) {
$automation_properties = $this->buildAutomationProperties(
$repository,
$this->buildAutomationActions($repository));
}
$actions_properties = $this->buildActionsProperties(
$repository,
$this->buildActionsActions($repository));
$timeline = $this->buildTransactionTimeline(
$repository,
new PhabricatorRepositoryTransactionQuery());
$timeline->setShouldTerminate(true);
$boxes = array();
$boxes[] = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($basic_properties);
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Policies'))
->addPropertyList($policy_properties);
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Hosting'))
->addPropertyList($hosting_properties);
if ($repository->canMirror()) {
$mirror_actions = $this->buildMirrorActions($repository);
$mirror_properties = $this->buildMirrorProperties(
$repository,
$mirror_actions);
$mirrors = id(new PhabricatorRepositoryMirrorQuery())
->setViewer($viewer)
->withRepositoryPHIDs(array($repository->getPHID()))
->execute();
$mirror_list = $this->buildMirrorList($repository, $mirrors);
$boxes[] = id(new PhabricatorAnchorView())->setAnchorName('mirrors');
$mirror_info = array();
if (PhabricatorEnv::getEnvConfig('phabricator.silent')) {
$mirror_info[] = pht(
'Phabricator is running in silent mode, so changes will not '.
'be pushed to mirrors.');
}
$boxes[] = id(new PHUIObjectBoxView())
->setFormErrors($mirror_info)
->setHeaderText(pht('Mirrors'))
->addPropertyList($mirror_properties);
$boxes[] = $mirror_list;
}
if ($remote_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Remote'))
->addPropertyList($remote_properties);
}
if ($storage_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Storage'))
->addPropertyList($storage_properties);
}
if ($staging_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Staging'))
->addPropertyList($staging_properties);
}
if ($automation_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Automation'))
->addPropertyList($automation_properties);
}
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Text Encoding'))
->addPropertyList($encoding_properties);
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Symbols'))
->addPropertyList($symbols_properties);
if ($branches_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Branches'))
->addPropertyList($branches_properties);
}
if ($subversion_properties) {
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Subversion'))
->addPropertyList($subversion_properties);
}
$boxes[] = id(new PHUIObjectBoxView())
->setHeaderText(pht('Actions'))
->addPropertyList($actions_properties);
return $this->buildApplicationPage(
array(
$crumbs,
$boxes,
$timeline,
),
array(
'title' => $title,
));
}
private function buildBasicActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Basic Information'))
->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/'));
$view->addAction($edit);
$edit = id(new PhabricatorActionView())
->setIcon('fa-refresh')
->setName(pht('Update Now'))
->setWorkflow(true)
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/update/'));
$view->addAction($edit);
$activate = id(new PhabricatorActionView())
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/activate/'))
->setWorkflow(true);
if ($repository->isTracked()) {
$activate
->setIcon('fa-pause')
->setName(pht('Deactivate Repository'));
} else {
$activate
->setIcon('fa-play')
->setName(pht('Activate Repository'));
}
$view->addAction($activate);
$view->addAction(
id(new PhabricatorActionView())
->setName(pht('Delete Repository'))
->setIcon('fa-times')
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/delete/'))
->setDisabled(true)
->setWorkflow(true));
return $view;
}
private function buildBasicProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setObject($repository)
->setActionList($actions);
$type = PhabricatorRepositoryType::getNameForRepositoryType(
$repository->getVersionControlSystem());
$view->addProperty(pht('Type'), $type);
$view->addProperty(pht('Callsign'), $repository->getCallsign());
- $clone_name = $repository->getRepositorySlug();
-
- if ($repository->isHosted()) {
- $view->addProperty(
- pht('Clone/Checkout As'),
- $clone_name
- ? $clone_name.'/'
- : phutil_tag('em', array(), $repository->getCloneName().'/'));
+ $short_name = $repository->getRepositorySlug();
+ if ($short_name === null) {
+ $short_name = $repository->getCloneName();
+ $short_name = phutil_tag('em', array(), $short_name);
}
+ $view->addProperty(pht('Short Name'), $short_name);
$view->invokeWillRenderEvent();
$view->addProperty(
pht('Status'),
$this->buildRepositoryStatus($repository));
$view->addProperty(
pht('Update Frequency'),
$this->buildRepositoryUpdateInterval($repository));
$description = $repository->getDetail('description');
$view->addSectionHeader(
pht('Description'), PHUIPropertyListView::ICON_SUMMARY);
if (!strlen($description)) {
$description = phutil_tag('em', array(), pht('No description provided.'));
} else {
$description = PhabricatorMarkupEngine::renderOneObject(
$repository,
'description',
$viewer);
}
$view->addTextContent($description);
return $view;
}
private function buildEncodingActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Text Encoding'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/encoding/'));
$view->addAction($edit);
return $view;
}
private function buildEncodingProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$encoding = $repository->getDetail('encoding');
if (!$encoding) {
$encoding = phutil_tag('em', array(), pht('Use Default (UTF-8)'));
}
$view->addProperty(pht('Encoding'), $encoding);
return $view;
}
private function buildPolicyActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Policies'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/policy/'));
$view->addAction($edit);
return $view;
}
private function buildPolicyProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
$repository);
$view_parts = array();
if (PhabricatorSpacesNamespaceQuery::getViewerSpacesExist($viewer)) {
$space_phid = PhabricatorSpacesNamespaceQuery::getObjectSpacePHID(
$repository);
$view_parts[] = $viewer->renderHandle($space_phid);
}
$view_parts[] = $descriptions[PhabricatorPolicyCapability::CAN_VIEW];
$view->addProperty(
pht('Visible To'),
phutil_implode_html(" \xC2\xB7 ", $view_parts));
$view->addProperty(
pht('Editable By'),
$descriptions[PhabricatorPolicyCapability::CAN_EDIT]);
$pushable = $repository->isHosted()
? $descriptions[DiffusionPushCapability::CAPABILITY]
: phutil_tag('em', array(), pht('Not a Hosted Repository'));
$view->addProperty(pht('Pushable By'), $pushable);
return $view;
}
private function buildBranchesActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Branches'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/branches/'));
$view->addAction($edit);
return $view;
}
private function buildBranchesProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$default_branch = nonempty(
$repository->getHumanReadableDetail('default-branch'),
phutil_tag('em', array(), $repository->getDefaultBranch()));
$view->addProperty(pht('Default Branch'), $default_branch);
$track_only = nonempty(
$repository->getHumanReadableDetail('branch-filter', array()),
phutil_tag('em', array(), pht('Track All Branches')));
$view->addProperty(pht('Track Only'), $track_only);
$autoclose_only = nonempty(
$repository->getHumanReadableDetail('close-commits-filter', array()),
phutil_tag('em', array(), pht('Autoclose On All Branches')));
if ($repository->getDetail('disable-autoclose')) {
$autoclose_only = phutil_tag('em', array(), pht('Disabled'));
}
$view->addProperty(pht('Autoclose Only'), $autoclose_only);
return $view;
}
private function buildSubversionActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Subversion Info'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/subversion/'));
$view->addAction($edit);
return $view;
}
private function buildSubversionProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$svn_uuid = nonempty(
$repository->getUUID(),
phutil_tag('em', array(), pht('Not Configured')));
$view->addProperty(pht('Subversion UUID'), $svn_uuid);
$svn_subpath = nonempty(
$repository->getHumanReadableDetail('svn-subpath'),
phutil_tag('em', array(), pht('Import Entire Repository')));
$view->addProperty(pht('Import Only'), $svn_subpath);
return $view;
}
private function buildActionsActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Actions'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/actions/'));
$view->addAction($edit);
return $view;
}
private function buildActionsProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$notify = $repository->getDetail('herald-disabled')
? pht('Off')
: pht('On');
$notify = phutil_tag('em', array(), $notify);
$view->addProperty(pht('Publish/Notify'), $notify);
$autoclose = $repository->getDetail('disable-autoclose')
? pht('Off')
: pht('On');
$autoclose = phutil_tag('em', array(), $autoclose);
$view->addProperty(pht('Autoclose'), $autoclose);
return $view;
}
private function buildRemoteActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Remote'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/remote/'));
$view->addAction($edit);
return $view;
}
private function buildRemoteProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$view->addProperty(
pht('Remote URI'),
$repository->getHumanReadableDetail('remote-uri'));
$credential_phid = $repository->getCredentialPHID();
if ($credential_phid) {
$view->addProperty(
pht('Credential'),
$viewer->renderHandle($credential_phid));
}
return $view;
}
private function buildStorageActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Storage'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/storage/'));
$view->addAction($edit);
return $view;
}
private function buildStorageProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$service_phid = $repository->getAlmanacServicePHID();
if ($service_phid) {
$v_service = $viewer->renderHandle($service_phid);
} else {
$v_service = phutil_tag(
'em',
array(),
pht('Local'));
}
$view->addProperty(
pht('Storage Service'),
$v_service);
$view->addProperty(
pht('Storage Path'),
$repository->getHumanReadableDetail('local-path'));
return $view;
}
private function buildStagingActions(PhabricatorRepository $repository) {
$viewer = $this->getViewer();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Staging'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/staging/'));
$view->addAction($edit);
return $view;
}
private function buildStagingProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$staging_uri = $repository->getStagingURI();
if (!$staging_uri) {
$staging_uri = phutil_tag('em', array(), pht('No Staging Area'));
}
$view->addProperty(
pht('Staging Area'),
$staging_uri);
return $view;
}
private function buildAutomationActions(PhabricatorRepository $repository) {
$viewer = $this->getViewer();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Automation'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/automation/'));
$view->addAction($edit);
$can_test = $repository->canPerformAutomation();
$test = id(new PhabricatorActionView())
->setIcon('fa-gamepad')
->setName(pht('Test Configuration'))
->setWorkflow(true)
->setDisabled(!$can_test)
->setHref(
$this->getRepositoryControllerURI(
$repository,
'edit/testautomation/'));
$view->addAction($test);
return $view;
}
private function buildAutomationProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getViewer();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$blueprint_phids = $repository->getAutomationBlueprintPHIDs();
if (!$blueprint_phids) {
$blueprint_view = phutil_tag('em', array(), pht('Not Configured'));
} else {
$blueprint_view = id(new DrydockObjectAuthorizationView())
->setUser($viewer)
->setObjectPHID($repository->getPHID())
->setBlueprintPHIDs($blueprint_phids);
}
$view->addProperty(pht('Automation'), $blueprint_view);
return $view;
}
private function buildHostingActions(PhabricatorRepository $repository) {
$user = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($user);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Hosting'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/hosting/'));
$view->addAction($edit);
if ($repository->canAllowDangerousChanges()) {
if ($repository->shouldAllowDangerousChanges()) {
$changes = id(new PhabricatorActionView())
->setIcon('fa-shield')
->setName(pht('Prevent Dangerous Changes'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/dangerous/'))
->setWorkflow(true);
} else {
$changes = id(new PhabricatorActionView())
->setIcon('fa-bullseye')
->setName(pht('Allow Dangerous Changes'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/dangerous/'))
->setWorkflow(true);
}
$view->addAction($changes);
}
return $view;
}
private function buildHostingProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$user = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($user)
->setActionList($actions);
$hosting = $repository->isHosted()
? pht('Hosted on Phabricator')
: pht('Hosted Elsewhere');
$view->addProperty(pht('Hosting'), phutil_tag('em', array(), $hosting));
$view->addProperty(
pht('Serve over HTTP'),
phutil_tag(
'em',
array(),
PhabricatorRepository::getProtocolAvailabilityName(
$repository->getServeOverHTTP())));
$view->addProperty(
pht('Serve over SSH'),
phutil_tag(
'em',
array(),
PhabricatorRepository::getProtocolAvailabilityName(
$repository->getServeOverSSH())));
if ($repository->canAllowDangerousChanges()) {
if ($repository->shouldAllowDangerousChanges()) {
$description = pht('Allowed');
} else {
$description = pht('Not Allowed');
}
$view->addProperty(
pht('Dangerous Changes'),
$description);
}
return $view;
}
private function buildRepositoryStatus(
PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$is_cluster = $repository->getAlmanacServicePHID();
$view = new PHUIStatusListView();
$messages = id(new PhabricatorRepositoryStatusMessage())
->loadAllWhere('repositoryID = %d', $repository->getID());
$messages = mpull($messages, null, 'getStatusType');
if ($repository->isTracked()) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Repository Active')));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'bluegrey')
->setTarget(pht('Repository Inactive'))
->setNote(
pht('Activate this repository to begin or resume import.')));
return $view;
}
$binaries = array();
$svnlook_check = false;
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$binaries[] = 'git';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$binaries[] = 'svn';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$binaries[] = 'hg';
break;
}
if ($repository->isHosted()) {
if ($repository->getServeOverHTTP() != PhabricatorRepository::SERVE_OFF) {
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$binaries[] = 'git-http-backend';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$binaries[] = 'svnserve';
$binaries[] = 'svnadmin';
$binaries[] = 'svnlook';
$svnlook_check = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$binaries[] = 'hg';
break;
}
}
if ($repository->getServeOverSSH() != PhabricatorRepository::SERVE_OFF) {
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$binaries[] = 'git-receive-pack';
$binaries[] = 'git-upload-pack';
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$binaries[] = 'svnserve';
$binaries[] = 'svnadmin';
$binaries[] = 'svnlook';
$svnlook_check = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$binaries[] = 'hg';
break;
}
}
}
$binaries = array_unique($binaries);
if (!$is_cluster) {
// We're only checking for binaries if we aren't running with a cluster
// configuration. In theory, we could check for binaries on the
// repository host machine, but we'd need to make this more complicated
// to do that.
foreach ($binaries as $binary) {
$where = Filesystem::resolveBinary($binary);
if (!$where) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
->setNote(pht(
"Unable to find this binary in the webserver's PATH. You may ".
"need to configure %s.",
$this->getEnvConfigLink())));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(
pht('Found Binary %s', phutil_tag('tt', array(), $binary)))
->setNote(phutil_tag('tt', array(), $where)));
}
}
// This gets checked generically above. However, for svn commit hooks, we
// need this to be in environment.append-paths because subversion strips
// PATH.
if ($svnlook_check) {
$where = Filesystem::resolveBinary('svnlook');
if ($where) {
$path = substr($where, 0, strlen($where) - strlen('svnlook'));
$dirs = PhabricatorEnv::getEnvConfig('environment.append-paths');
$in_path = false;
foreach ($dirs as $dir) {
if (Filesystem::isDescendant($path, $dir)) {
$in_path = true;
break;
}
}
if (!$in_path) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(
pht('Missing Binary %s', phutil_tag('tt', array(), $binary)))
->setNote(pht(
'Unable to find this binary in `%s`. '.
'You need to configure %s and include %s.',
'environment.append-paths',
$this->getEnvConfigLink(),
$path)));
}
}
}
}
$doc_href = PhabricatorEnv::getDocLink('Managing Daemons with phd');
$daemon_instructions = pht(
'Use %s to start daemons. See %s.',
phutil_tag('tt', array(), 'bin/phd start'),
phutil_tag(
'a',
array(
'href' => $doc_href,
),
pht('Managing Daemons with phd')));
$pull_daemon = id(new PhabricatorDaemonLogQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
->withDaemonClasses(array('PhabricatorRepositoryPullLocalDaemon'))
->setLimit(1)
->execute();
if ($pull_daemon) {
// TODO: In a cluster environment, we need a daemon on this repository's
// host, specifically, and we aren't checking for that right now. This
// is a reasonable proxy for things being more-or-less correctly set up,
// though.
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Pull Daemon Running')));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Pull Daemon Not Running'))
->setNote($daemon_instructions));
}
$task_daemon = id(new PhabricatorDaemonLogQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withStatus(PhabricatorDaemonLogQuery::STATUS_ALIVE)
->withDaemonClasses(array('PhabricatorTaskmasterDaemon'))
->setLimit(1)
->execute();
if ($task_daemon) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Task Daemon Running')));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Task Daemon Not Running'))
->setNote($daemon_instructions));
}
if ($is_cluster) {
// Just omit this status check for now in cluster environments. We
// could make a service call and pull it from the repository host
// eventually.
} else if ($repository->usesLocalWorkingCopy()) {
$local_parent = dirname($repository->getLocalPath());
if (Filesystem::pathExists($local_parent)) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Storage Directory OK'))
->setNote(phutil_tag('tt', array(), $local_parent)));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('No Storage Directory'))
->setNote(
pht(
'Storage directory %s does not exist, or is not readable by '.
'the webserver. Create this directory or make it readable.',
phutil_tag('tt', array(), $local_parent))));
return $view;
}
$local_path = $repository->getLocalPath();
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_INIT);
if ($message) {
switch ($message->getStatusCode()) {
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Initialization Error'))
->setNote($message->getParameter('message')));
return $view;
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
if (Filesystem::pathExists($local_path)) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Working Copy OK'))
->setNote(phutil_tag('tt', array(), $local_path)));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Working Copy Error'))
->setNote(
pht(
'Working copy %s has been deleted, or is not '.
'readable by the webserver. Make this directory '.
'readable. If it has been deleted, the daemons should '.
'restore it automatically.',
phutil_tag('tt', array(), $local_path))));
return $view;
}
break;
case PhabricatorRepositoryStatusMessage::CODE_WORKING:
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
->setTarget(pht('Initializing Working Copy'))
->setNote(pht('Daemons are initializing the working copy.')));
return $view;
default:
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Unknown Init Status'))
->setNote($message->getStatusCode()));
return $view;
}
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
->setTarget(pht('No Working Copy Yet'))
->setNote(
pht('Waiting for daemons to build a working copy.')));
return $view;
}
}
$message = idx($messages, PhabricatorRepositoryStatusMessage::TYPE_FETCH);
if ($message) {
switch ($message->getStatusCode()) {
case PhabricatorRepositoryStatusMessage::CODE_ERROR:
$message = $message->getParameter('message');
$suggestion = null;
if (preg_match('/Permission denied \(publickey\)./', $message)) {
$suggestion = pht(
'Public Key Error: This error usually indicates that the '.
'keypair you have configured does not have permission to '.
'access the repository.');
}
$message = phutil_escape_html_newlines($message);
if ($suggestion !== null) {
$message = array(
phutil_tag('strong', array(), $suggestion),
phutil_tag('br'),
phutil_tag('br'),
phutil_tag('em', array(), pht('Raw Error')),
phutil_tag('br'),
$message,
);
}
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_WARNING, 'red')
->setTarget(pht('Update Error'))
->setNote($message));
return $view;
case PhabricatorRepositoryStatusMessage::CODE_OKAY:
$ago = (PhabricatorTime::getNow() - $message->getEpoch());
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Updates OK'))
->setNote(
pht(
'Last updated %s (%s ago).',
phabricator_datetime($message->getEpoch(), $viewer),
phutil_format_relative_time_detailed($ago))));
break;
}
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'orange')
->setTarget(pht('Waiting For Update'))
->setNote(
pht('Waiting for daemons to read updates.')));
}
if ($repository->isImporting()) {
$ratio = $repository->loadImportProgress();
$percentage = sprintf('%.2f%%', 100 * $ratio);
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_CLOCK, 'green')
->setTarget(pht('Importing'))
->setNote(
pht('%s Complete', $percentage)));
} else {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_ACCEPT, 'green')
->setTarget(pht('Fully Imported')));
}
if (idx($messages, PhabricatorRepositoryStatusMessage::TYPE_NEEDS_UPDATE)) {
$view->addItem(
id(new PHUIStatusItemView())
->setIcon(PHUIStatusItemView::ICON_UP, 'indigo')
->setTarget(pht('Prioritized'))
->setNote(pht('This repository will be updated soon!')));
}
return $view;
}
private function buildRepositoryUpdateInterval(
PhabricatorRepository $repository) {
$smart_wait = $repository->loadUpdateInterval();
$doc_href = PhabricatorEnv::getDoclink(
'Diffusion User Guide: Repository Updates');
return array(
phutil_format_relative_time_detailed($smart_wait),
" \xC2\xB7 ",
phutil_tag(
'a',
array(
'href' => $doc_href,
'target' => '_blank',
),
pht('Learn More')),
);
}
private function buildMirrorActions(
PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$mirror_actions = id(new PhabricatorActionListView())
->setUser($viewer);
$new_mirror_uri = $this->getRepositoryControllerURI(
$repository,
'mirror/edit/');
$mirror_actions->addAction(
id(new PhabricatorActionView())
->setName(pht('Add Mirror'))
->setIcon('fa-plus')
->setHref($new_mirror_uri)
->setWorkflow(true));
return $mirror_actions;
}
private function buildMirrorProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$mirror_properties = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$mirror_properties->addProperty(
'',
phutil_tag(
'em',
array(),
pht('Automatically push changes into other remotes.')));
return $mirror_properties;
}
private function buildMirrorList(
PhabricatorRepository $repository,
array $mirrors) {
assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
$mirror_list = id(new PHUIObjectItemListView())
->setNoDataString(pht('This repository has no configured mirrors.'));
foreach ($mirrors as $mirror) {
$item = id(new PHUIObjectItemView())
->setHeader($mirror->getRemoteURI());
$edit_uri = $this->getRepositoryControllerURI(
$repository,
'mirror/edit/'.$mirror->getID().'/');
$delete_uri = $this->getRepositoryControllerURI(
$repository,
'mirror/delete/'.$mirror->getID().'/');
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-pencil')
->setHref($edit_uri)
->setWorkflow(true));
$item->addAction(
id(new PHUIListItemView())
->setIcon('fa-times')
->setHref($delete_uri)
->setWorkflow(true));
$mirror_list->addItem($item);
}
return $mirror_list;
}
private function buildSymbolsActions(PhabricatorRepository $repository) {
$viewer = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($viewer);
$edit = id(new PhabricatorActionView())
->setIcon('fa-pencil')
->setName(pht('Edit Symbols'))
->setHref(
$this->getRepositoryControllerURI($repository, 'edit/symbol/'));
$view->addAction($edit);
return $view;
}
private function buildSymbolsProperties(
PhabricatorRepository $repository,
PhabricatorActionListView $actions) {
$viewer = $this->getRequest()->getUser();
$view = id(new PHUIPropertyListView())
->setUser($viewer)
->setActionList($actions);
$languages = $repository->getSymbolLanguages();
if ($languages) {
$languages = implode(', ', $languages);
} else {
$languages = phutil_tag('em', array(), pht('Any'));
}
$view->addProperty(pht('Languages'), $languages);
$sources = $repository->getSymbolSources();
if ($sources) {
$handles = $viewer->loadHandles($sources);
$sources = $handles->renderList();
} else {
$sources = phutil_tag('em', array(), pht('This Repository Only'));
}
$view->addProperty(pht('Use Symbols From'), $sources);
return $view;
}
private function getEnvConfigLink() {
$config_href = '/config/edit/environment.append-paths/';
return phutil_tag(
'a',
array(
'href' => $config_href,
),
'environment.append-paths');
}
}
diff --git a/src/applications/repository/editor/PhabricatorRepositoryEditor.php b/src/applications/repository/editor/PhabricatorRepositoryEditor.php
index 9e04a5552f..fc397daa1e 100644
--- a/src/applications/repository/editor/PhabricatorRepositoryEditor.php
+++ b/src/applications/repository/editor/PhabricatorRepositoryEditor.php
@@ -1,521 +1,521 @@
<?php
final class PhabricatorRepositoryEditor
extends PhabricatorApplicationTransactionEditor {
public function getEditorApplicationClass() {
return 'PhabricatorDiffusionApplication';
}
public function getEditorObjectsDescription() {
return pht('Repositories');
}
public function getTransactionTypes() {
$types = parent::getTransactionTypes();
$types[] = PhabricatorRepositoryTransaction::TYPE_VCS;
$types[] = PhabricatorRepositoryTransaction::TYPE_ACTIVATE;
$types[] = PhabricatorRepositoryTransaction::TYPE_NAME;
$types[] = PhabricatorRepositoryTransaction::TYPE_DESCRIPTION;
$types[] = PhabricatorRepositoryTransaction::TYPE_ENCODING;
$types[] = PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH;
$types[] = PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY;
$types[] = PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY;
$types[] = PhabricatorRepositoryTransaction::TYPE_UUID;
$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_CLONE_NAME;
+ $types[] = PhabricatorRepositoryTransaction::TYPE_SLUG;
$types[] = PhabricatorRepositoryTransaction::TYPE_SERVICE;
$types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE;
$types[] = PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES;
$types[] = PhabricatorRepositoryTransaction::TYPE_STAGING_URI;
$types[] = PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS;
$types[] = PhabricatorTransactions::TYPE_EDGE;
$types[] = PhabricatorTransactions::TYPE_VIEW_POLICY;
$types[] = PhabricatorTransactions::TYPE_EDIT_POLICY;
return $types;
}
protected function getCustomTransactionOldValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryTransaction::TYPE_VCS:
return $object->getVersionControlSystem();
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
return $object->isTracked();
case PhabricatorRepositoryTransaction::TYPE_NAME:
return $object->getName();
case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
return $object->getDetail('description');
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
return $object->getDetail('encoding');
case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
return $object->getDetail('default-branch');
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
return array_keys($object->getDetail('branch-filter', array()));
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY:
return array_keys($object->getDetail('close-commits-filter', array()));
case PhabricatorRepositoryTransaction::TYPE_UUID:
return $object->getUUID();
case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH:
return $object->getDetail('svn-subpath');
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
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->getDetail('local-path');
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_CLONE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_SLUG:
return $object->getRepositorySlug();
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
return $object->getAlmanacServicePHID();
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
return $object->getSymbolLanguages();
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
return $object->getSymbolSources();
case PhabricatorRepositoryTransaction::TYPE_STAGING_URI:
return $object->getDetail('staging-uri');
case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS:
return $object->getDetail('automation.blueprintPHIDs', array());
}
}
protected function getCustomTransactionNewValue(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
case PhabricatorRepositoryTransaction::TYPE_NAME:
case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
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:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
case PhabricatorRepositoryTransaction::TYPE_STAGING_URI:
case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS:
return $xaction->getNewValue();
- case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_SLUG:
$name = $xaction->getNewValue();
if (strlen($name)) {
return $name;
}
return null;
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
return (int)$xaction->getNewValue();
}
}
protected function applyCustomInternalTransaction(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryTransaction::TYPE_VCS:
$object->setVersionControlSystem($xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
$object->setDetail('tracking-enabled', $xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_NAME:
$object->setName($xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
$object->setDetail('description', $xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
$object->setDetail('default-branch', $xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
$object->setDetail(
'branch-filter',
array_fill_keys($xaction->getNewValue(), true));
break;
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE_ONLY:
$object->setDetail(
'close-commits-filter',
array_fill_keys($xaction->getNewValue(), true));
break;
case PhabricatorRepositoryTransaction::TYPE_UUID:
$object->setUUID($xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_SVN_SUBPATH:
$object->setDetail('svn-subpath', $xaction->getNewValue());
break;
case PhabricatorRepositoryTransaction::TYPE_NOTIFY:
$object->setDetail('herald-disabled', (int)!$xaction->getNewValue());
break;
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->setDetail('local-path', $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;
- case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_SLUG:
$object->setRepositorySlug($xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
$object->setAlmanacServicePHID($xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
$object->setDetail('symbol-languages', $xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
$object->setDetail('symbol-sources', $xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_STAGING_URI:
$object->setDetail('staging-uri', $xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS:
$object->setDetail(
'automation.blueprintPHIDs',
$xaction->getNewValue());
return;
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
// Make sure the encoding is valid by converting to UTF-8. This tests
// that the user has mbstring installed, and also that they didn't type
// a garbage encoding name. Note that we're converting from UTF-8 to
// the target encoding, because mbstring is fine with converting from
// a nonsense encoding.
$encoding = $xaction->getNewValue();
if (strlen($encoding)) {
try {
phutil_utf8_convert('.', $encoding, 'UTF-8');
} catch (Exception $ex) {
throw new PhutilProxyException(
pht(
"Error setting repository encoding '%s': %s'",
$encoding,
$ex->getMessage()),
$ex);
}
}
$object->setDetail('encoding', $encoding);
break;
}
}
protected function applyCustomExternalTransaction(
PhabricatorLiskDAO $object,
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(),
$object->getPHID(),
$xaction->getOldValue(),
$xaction->getNewValue());
break;
}
}
protected function requireCapabilities(
PhabricatorLiskDAO $object,
PhabricatorApplicationTransaction $xaction) {
switch ($xaction->getTransactionType()) {
case PhabricatorRepositoryTransaction::TYPE_ACTIVATE:
case PhabricatorRepositoryTransaction::TYPE_NAME:
case PhabricatorRepositoryTransaction::TYPE_DESCRIPTION:
case PhabricatorRepositoryTransaction::TYPE_ENCODING:
case PhabricatorRepositoryTransaction::TYPE_DEFAULT_BRANCH:
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
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_CLONE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_SLUG:
case PhabricatorRepositoryTransaction::TYPE_SERVICE:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_SOURCES:
case PhabricatorRepositoryTransaction::TYPE_SYMBOLS_LANGUAGE:
case PhabricatorRepositoryTransaction::TYPE_STAGING_URI:
case PhabricatorRepositoryTransaction::TYPE_AUTOMATION_BLUEPRINTS:
PhabricatorPolicyFilter::requireCapability(
$this->requireActor(),
$object,
PhabricatorPolicyCapability::CAN_EDIT);
break;
}
}
protected function validateTransaction(
PhabricatorLiskDAO $object,
$type,
array $xactions) {
$errors = parent::validateTransaction($object, $type, $xactions);
switch ($type) {
case PhabricatorRepositoryTransaction::TYPE_AUTOCLOSE:
case PhabricatorRepositoryTransaction::TYPE_TRACK_ONLY:
foreach ($xactions as $xaction) {
foreach ($xaction->getNewValue() as $pattern) {
// Check for invalid regular expressions.
$regexp = PhabricatorRepository::extractBranchRegexp($pattern);
if ($regexp !== null) {
$ok = @preg_match($regexp, '');
if ($ok === false) {
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Expression "%s" is not a valid regular expression. Note '.
'that you must include delimiters.',
$regexp),
$xaction);
$errors[] = $error;
continue;
}
}
// Check for formatting mistakes like `regex(...)` instead of
// `regexp(...)`.
$matches = null;
if (preg_match('/^([^(]+)\\(.*\\)\z/', $pattern, $matches)) {
switch ($matches[1]) {
case 'regexp':
break;
default:
$error = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Matching function "%s(...)" is not recognized. Valid '.
'functions are: regexp(...).',
$matches[1]),
$xaction);
$errors[] = $error;
break;
}
}
}
}
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());
$new = nonempty($xaction->getNewValue(), array());
$add = array_diff($new, $old);
$invalid = PhabricatorObjectQuery::loadInvalidPHIDsForViewer(
$this->getActor(),
$add);
if ($invalid) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
pht(
'Some of the selected automation blueprints are invalid '.
'or restricted: %s.',
implode(', ', $invalid)),
$xaction);
}
}
break;
- case PhabricatorRepositoryTransaction::TYPE_CLONE_NAME:
+ case PhabricatorRepositoryTransaction::TYPE_SLUG:
foreach ($xactions as $xaction) {
$old = $xaction->getOldValue();
$new = $xaction->getNewValue();
if (!strlen($new)) {
continue;
}
if ($new === $old) {
continue;
}
try {
PhabricatorRepository::asssertValidRepositorySlug($new);
} catch (Exception $ex) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Invalid'),
$ex->getMessage(),
$xaction);
continue;
}
$other = id(new PhabricatorRepositoryQuery())
->setViewer(PhabricatorUser::getOmnipotentUser())
->withSlugs(array($new))
->executeOne();
if ($other && ($other->getID() !== $object->getID())) {
$errors[] = new PhabricatorApplicationTransactionValidationError(
$type,
pht('Duplicate'),
pht(
'The selected repository short name is already in use by '.
'another repository. Choose a unique short name.'),
$xaction);
continue;
}
}
break;
}
return $errors;
}
protected function didCatchDuplicateKeyException(
PhabricatorLiskDAO $object,
array $xactions,
Exception $ex) {
$errors = array();
$errors[] = new PhabricatorApplicationTransactionValidationError(
null,
pht('Invalid'),
pht(
'The chosen callsign or repository short name is already in '.
'use by another repository.'),
null);
throw new PhabricatorApplicationTransactionValidationException($errors);
}
}
diff --git a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
index c9077e0236..a10ac0a60b 100644
--- a/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
+++ b/src/applications/repository/storage/PhabricatorRepositoryTransaction.php
@@ -1,489 +1,489 @@
<?php
final class PhabricatorRepositoryTransaction
extends PhabricatorApplicationTransaction {
const TYPE_VCS = 'repo:vcs';
const TYPE_ACTIVATE = 'repo:activate';
const TYPE_NAME = 'repo:name';
const TYPE_DESCRIPTION = 'repo:description';
const TYPE_ENCODING = 'repo:encoding';
const TYPE_DEFAULT_BRANCH = 'repo:default-branch';
const TYPE_TRACK_ONLY = 'repo:track-only';
const TYPE_AUTOCLOSE_ONLY = 'repo:autoclose-only';
const TYPE_SVN_SUBPATH = 'repo:svn-subpath';
const TYPE_UUID = 'repo:uuid';
const TYPE_NOTIFY = 'repo:notify';
const TYPE_AUTOCLOSE = 'repo:autoclose';
const TYPE_REMOTE_URI = 'repo:remote-uri';
const TYPE_LOCAL_PATH = 'repo:local-path';
const TYPE_HOSTING = 'repo:hosting';
const TYPE_PROTOCOL_HTTP = 'repo:serve-http';
const TYPE_PROTOCOL_SSH = 'repo:serve-ssh';
const TYPE_PUSH_POLICY = 'repo:push-policy';
const TYPE_CREDENTIAL = 'repo:credential';
const TYPE_DANGEROUS = 'repo:dangerous';
- const TYPE_CLONE_NAME = 'repo:clone-name';
+ const TYPE_SLUG = 'repo:slug';
const TYPE_SERVICE = 'repo:service';
const TYPE_SYMBOLS_SOURCES = 'repo:symbol-source';
const TYPE_SYMBOLS_LANGUAGE = 'repo:symbol-language';
const TYPE_STAGING_URI = 'repo:staging-uri';
const TYPE_AUTOMATION_BLUEPRINTS = 'repo:automation-blueprints';
// TODO: Clean up these legacy transaction types.
const TYPE_SSH_LOGIN = 'repo:ssh-login';
const TYPE_SSH_KEY = 'repo:ssh-key';
const TYPE_SSH_KEYFILE = 'repo:ssh-keyfile';
const TYPE_HTTP_LOGIN = 'repo:http-login';
const TYPE_HTTP_PASS = 'repo:http-pass';
public function getApplicationName() {
return 'repository';
}
public function getApplicationTransactionType() {
return PhabricatorRepositoryRepositoryPHIDType::TYPECONST;
}
public function getApplicationTransactionCommentObject() {
return null;
}
public function getRequiredHandlePHIDs() {
$phids = parent::getRequiredHandlePHIDs();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_PUSH_POLICY:
case self::TYPE_SERVICE:
if ($old) {
$phids[] = $old;
}
if ($new) {
$phids[] = $new;
}
break;
case self::TYPE_SYMBOLS_SOURCES:
case self::TYPE_AUTOMATION_BLUEPRINTS:
if ($old) {
$phids = array_merge($phids, $old);
}
if ($new) {
$phids = array_merge($phids, $new);
}
break;
}
return $phids;
}
public function shouldHide() {
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_REMOTE_URI:
case self::TYPE_SSH_LOGIN:
case self::TYPE_SSH_KEY:
case self::TYPE_SSH_KEYFILE:
case self::TYPE_HTTP_LOGIN:
case self::TYPE_HTTP_PASS:
// Hide null vs empty string changes.
return (!strlen($old) && !strlen($new));
case self::TYPE_LOCAL_PATH:
case self::TYPE_NAME:
// Hide these on create, they aren't interesting and we have an
// explicit "create" transaction.
if (!strlen($old)) {
return true;
}
break;
}
return parent::shouldHide();
}
public function getIcon() {
switch ($this->getTransactionType()) {
case self::TYPE_VCS:
return 'fa-plus';
}
return parent::getIcon();
}
public function getColor() {
switch ($this->getTransactionType()) {
case self::TYPE_VCS:
return 'green';
}
return parent::getIcon();
}
public function getTitle() {
$author_phid = $this->getAuthorPHID();
$old = $this->getOldValue();
$new = $this->getNewValue();
switch ($this->getTransactionType()) {
case self::TYPE_VCS:
return pht(
'%s created this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_ACTIVATE:
if ($new) {
return pht(
'%s activated this repository.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s deactivated this repository.',
$this->renderHandleLink($author_phid));
}
case self::TYPE_NAME:
return pht(
'%s renamed this repository from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_DESCRIPTION:
return pht(
'%s updated the description of this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_ENCODING:
if (strlen($old) && !strlen($new)) {
return pht(
'%s removed the "%s" encoding configured for this repository.',
$this->renderHandleLink($author_phid),
$old);
} else if (strlen($new) && !strlen($old)) {
return pht(
'%s set the encoding for this repository to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
'%s changed the repository encoding from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_DEFAULT_BRANCH:
if (!strlen($new)) {
return pht(
'%s removed "%s" as the default branch.',
$this->renderHandleLink($author_phid),
$old);
} else if (!strlen($old)) {
return pht(
'%s set the default branch to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
'%s changed the default branch from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_TRACK_ONLY:
if (!$new) {
return pht(
'%s set this repository to track all branches.',
$this->renderHandleLink($author_phid));
} else if (!$old) {
return pht(
'%s set this repository to track branches: %s.',
$this->renderHandleLink($author_phid),
implode(', ', $new));
} else {
return pht(
'%s changed track branches from "%s" to "%s".',
$this->renderHandleLink($author_phid),
implode(', ', $old),
implode(', ', $new));
}
break;
case self::TYPE_AUTOCLOSE_ONLY:
if (!$new) {
return pht(
'%s set this repository to autoclose on all branches.',
$this->renderHandleLink($author_phid));
} else if (!$old) {
return pht(
'%s set this repository to autoclose on branches: %s.',
$this->renderHandleLink($author_phid),
implode(', ', $new));
} else {
return pht(
'%s changed autoclose branches from "%s" to "%s".',
$this->renderHandleLink($author_phid),
implode(', ', $old),
implode(', ', $new));
}
break;
case self::TYPE_UUID:
if (!strlen($new)) {
return pht(
'%s removed "%s" as the repository UUID.',
$this->renderHandleLink($author_phid),
$old);
} else if (!strlen($old)) {
return pht(
'%s set the repository UUID to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
'%s changed the repository UUID from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_SVN_SUBPATH:
if (!strlen($new)) {
return pht(
'%s removed "%s" as the Import Only path.',
$this->renderHandleLink($author_phid),
$old);
} else if (!strlen($old)) {
return pht(
'%s set the repository to import only "%s".',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
'%s changed the import path from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_NOTIFY:
if ($new) {
return pht(
'%s enabled notifications and publishing for this repository.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s disabled notifications and publishing for this repository.',
$this->renderHandleLink($author_phid));
}
break;
case self::TYPE_AUTOCLOSE:
if ($new) {
return pht(
'%s enabled autoclose for this repository.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s disabled autoclose for this repository.',
$this->renderHandleLink($author_phid));
}
break;
case self::TYPE_REMOTE_URI:
if (!strlen($old)) {
return pht(
'%s set the remote URI for this repository to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else if (!strlen($new)) {
return pht(
'%s removed the remote URI for this repository.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed the remote URI for this repository from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
break;
case self::TYPE_SSH_LOGIN:
return pht(
'%s updated the SSH login for this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_SSH_KEY:
return pht(
'%s updated the SSH key for this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_SSH_KEYFILE:
return pht(
'%s updated the SSH keyfile for this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_HTTP_LOGIN:
return pht(
'%s updated the HTTP login for this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_HTTP_PASS:
return pht(
'%s updated the HTTP password for this repository.',
$this->renderHandleLink($author_phid));
case self::TYPE_LOCAL_PATH:
return pht(
'%s changed the local path from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
case self::TYPE_HOSTING:
if ($new) {
return pht(
'%s changed this repository to be hosted on Phabricator.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s changed this repository to track a remote elsewhere.',
$this->renderHandleLink($author_phid));
}
case self::TYPE_PROTOCOL_HTTP:
return pht(
'%s changed the availability of this repository over HTTP from '.
'"%s" to "%s".',
$this->renderHandleLink($author_phid),
PhabricatorRepository::getProtocolAvailabilityName($old),
PhabricatorRepository::getProtocolAvailabilityName($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));
case self::TYPE_PUSH_POLICY:
return pht(
'%s changed the push policy of this repository from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$this->renderPolicyName($old, 'old'),
$this->renderPolicyName($new, 'new'));
case self::TYPE_DANGEROUS:
if ($new) {
return pht(
'%s disabled protection against dangerous changes.',
$this->renderHandleLink($author_phid));
} else {
return pht(
'%s enabled protection against dangerous changes.',
$this->renderHandleLink($author_phid));
}
- case self::TYPE_CLONE_NAME:
+ case self::TYPE_SLUG:
if (strlen($old) && !strlen($new)) {
return pht(
- '%s removed the clone name of this repository.',
+ '%s removed the short name of this repository.',
$this->renderHandleLink($author_phid));
} else if (strlen($new) && !strlen($old)) {
return pht(
- '%s set the clone name of this repository to "%s".',
+ '%s set the short name of this repository to "%s".',
$this->renderHandleLink($author_phid),
$new);
} else {
return pht(
- '%s changed the clone name of this repository from "%s" to "%s".',
+ '%s changed the short name of this repository from "%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_SERVICE:
if (strlen($old) && !strlen($new)) {
return pht(
'%s moved storage for this repository from %s to local.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old));
} else if (!strlen($old) && strlen($new)) {
// TODO: Possibly, we should distinguish between automatic assignment
// on creation vs explicit adjustment.
return pht(
'%s set storage for this repository to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($new));
} else {
return pht(
'%s moved storage for this repository from %s to %s.',
$this->renderHandleLink($author_phid),
$this->renderHandleLink($old),
$this->renderHandleLink($new));
}
case self::TYPE_SYMBOLS_SOURCES:
return pht(
'%s changed symbol sources from %s to %s.',
$this->renderHandleLink($author_phid),
empty($old) ? pht('None') : $this->renderHandleList($old),
empty($new) ? pht('None') : $this->renderHandleList($new));
case self::TYPE_SYMBOLS_LANGUAGE:
return pht('%s changed indexed languages from %s to %s.',
$this->renderHandleLink($author_phid),
$old ? implode(', ', $old) : pht('Any'),
$new ? implode(', ', $new) : pht('Any'));
case self::TYPE_STAGING_URI:
if (!$old) {
return pht(
'%s set "%s" as the staging area for this repository.',
$this->renderHandleLink($author_phid),
$new);
} else if (!$new) {
return pht(
'%s removed "%s" as the staging area for this repository.',
$this->renderHandleLink($author_phid),
$old);
} else {
return pht(
'%s changed the staging area for this repository from '.
'"%s" to "%s".',
$this->renderHandleLink($author_phid),
$old,
$new);
}
case self::TYPE_AUTOMATION_BLUEPRINTS:
$add = array_diff($new, $old);
$rem = array_diff($old, $new);
if ($add && $rem) {
return pht(
'%s changed %s automation blueprint(s), '.
'added %s: %s; removed %s: %s.',
$this->renderHandleLink($author_phid),
new PhutilNumber(count($add) + count($rem)),
new PhutilNumber(count($add)),
$this->renderHandleList($add),
new PhutilNumber(count($rem)),
$this->renderHandleList($rem));
} else if ($add) {
return pht(
'%s added %s automation blueprint(s): %s.',
$this->renderHandleLink($author_phid),
new PhutilNumber(count($add)),
$this->renderHandleList($add));
} else {
return pht(
'%s removed %s automation blueprint(s): %s.',
$this->renderHandleLink($author_phid),
new PhutilNumber(count($rem)),
$this->renderHandleList($rem));
}
}
return parent::getTitle();
}
public function hasChangeDetails() {
switch ($this->getTransactionType()) {
case self::TYPE_DESCRIPTION:
return true;
}
return parent::hasChangeDetails();
}
public function renderChangeDetails(PhabricatorUser $viewer) {
return $this->renderTextCorpusChangeDetails(
$viewer,
$this->getOldValue(),
$this->getNewValue());
}
}

File Metadata

Mime Type
text/x-diff
Expires
Tue, Jun 10, 4:22 PM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
140516
Default Alt Text
(88 KB)

Event Timeline