Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F14704390
D7632.id17227.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
26 KB
Referenced Files
None
Subscribers
None
D7632.id17227.diff
View Options
Index: resources/sql/patches/20131122.repomirror.sql
===================================================================
--- /dev/null
+++ resources/sql/patches/20131122.repomirror.sql
@@ -0,0 +1,13 @@
+CREATE TABLE {$NAMESPACE}_repository.repository_mirror (
+ id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ phid VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ repositoryPHID VARCHAR(64) NOT NULL COLLATE utf8_bin,
+ remoteURI VARCHAR(255) NOT NULL COLLATE utf8_bin,
+ credentialPHID VARCHAR(64) COLLATE utf8_bin,
+ dateCreated INT UNSIGNED NOT NULL,
+ dateModified INT UNSIGNED NOT NULL,
+
+ UNIQUE KEY `key_phid` (phid),
+ KEY `key_repository` (repositoryPHID)
+
+) ENGINE=InnoDB, COLLATE utf8_general_ci;
Index: src/__phutil_library_map__.php
===================================================================
--- src/__phutil_library_map__.php
+++ src/__phutil_library_map__.php
@@ -510,6 +510,8 @@
'DiffusionMercurialRequest' => 'applications/diffusion/request/DiffusionMercurialRequest.php',
'DiffusionMercurialResponse' => 'applications/diffusion/response/DiffusionMercurialResponse.php',
'DiffusionMercurialWireProtocol' => 'applications/diffusion/protocol/DiffusionMercurialWireProtocol.php',
+ 'DiffusionMirrorDeleteController' => 'applications/diffusion/controller/DiffusionMirrorDeleteController.php',
+ 'DiffusionMirrorEditController' => 'applications/diffusion/controller/DiffusionMirrorEditController.php',
'DiffusionPathChange' => 'applications/diffusion/data/DiffusionPathChange.php',
'DiffusionPathChangeQuery' => 'applications/diffusion/query/pathchange/DiffusionPathChangeQuery.php',
'DiffusionPathCompleteController' => 'applications/diffusion/controller/DiffusionPathCompleteController.php',
@@ -1768,8 +1770,11 @@
'PhabricatorRepositoryManagementWorkflow' => 'applications/repository/management/PhabricatorRepositoryManagementWorkflow.php',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/PhabricatorRepositoryMercurialCommitChangeParserWorker.php',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/PhabricatorRepositoryMercurialCommitMessageParserWorker.php',
+ 'PhabricatorRepositoryMirror' => 'applications/repository/storage/PhabricatorRepositoryMirror.php',
+ 'PhabricatorRepositoryMirrorQuery' => 'applications/repository/query/PhabricatorRepositoryMirrorQuery.php',
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeArcanistProject.php',
'PhabricatorRepositoryPHIDTypeCommit' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeCommit.php',
+ 'PhabricatorRepositoryPHIDTypeMirror' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeMirror.php',
'PhabricatorRepositoryPHIDTypeRepository' => 'applications/repository/phid/PhabricatorRepositoryPHIDTypeRepository.php',
'PhabricatorRepositoryPullEngine' => 'applications/repository/engine/PhabricatorRepositoryPullEngine.php',
'PhabricatorRepositoryPullLocalDaemon' => 'applications/repository/daemon/PhabricatorRepositoryPullLocalDaemon.php',
@@ -2821,6 +2826,8 @@
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMercurialResponse' => 'AphrontResponse',
+ 'DiffusionMirrorDeleteController' => 'DiffusionController',
+ 'DiffusionMirrorEditController' => 'DiffusionController',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController',
@@ -4249,8 +4256,15 @@
'PhabricatorRepositoryManagementWorkflow' => 'PhutilArgumentWorkflow',
'PhabricatorRepositoryMercurialCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryMercurialCommitMessageParserWorker' => 'PhabricatorRepositoryCommitMessageParserWorker',
+ 'PhabricatorRepositoryMirror' =>
+ array(
+ 0 => 'PhabricatorRepositoryDAO',
+ 1 => 'PhabricatorPolicyInterface',
+ ),
+ 'PhabricatorRepositoryMirrorQuery' => 'PhabricatorCursorPagedPolicyAwareQuery',
'PhabricatorRepositoryPHIDTypeArcanistProject' => 'PhabricatorPHIDType',
'PhabricatorRepositoryPHIDTypeCommit' => 'PhabricatorPHIDType',
+ 'PhabricatorRepositoryPHIDTypeMirror' => 'PhabricatorPHIDType',
'PhabricatorRepositoryPHIDTypeRepository' => 'PhabricatorPHIDType',
'PhabricatorRepositoryPullEngine' => 'PhabricatorRepositoryEngine',
'PhabricatorRepositoryPullLocalDaemon' => 'PhabricatorDaemon',
Index: src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
===================================================================
--- src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
+++ src/applications/diffusion/application/PhabricatorApplicationDiffusion.php
@@ -80,6 +80,10 @@
'hosting/' => 'DiffusionRepositoryEditHostingController',
'(?P<serve>serve)/' => 'DiffusionRepositoryEditHostingController',
),
+ 'mirror/' => array(
+ 'edit/(?:(?P<id>\d+)/)?' => 'DiffusionMirrorEditController',
+ 'delete/(?P<id>\d+)/' => 'DiffusionMirrorDeleteController',
+ ),
),
// NOTE: This must come after the rule above; it just gives us a
Index: src/applications/diffusion/controller/DiffusionMirrorDeleteController.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/controller/DiffusionMirrorDeleteController.php
@@ -0,0 +1,47 @@
+<?php
+
+final class DiffusionMirrorDeleteController
+ extends DiffusionController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = $data['id'];
+ parent::willProcessRequest($data);
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+ $drequest = $this->diffusionRequest;
+ $repository = $drequest->getRepository();
+
+ $mirror = id(new PhabricatorRepositoryMirrorQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$mirror) {
+ return new Aphront404Response();
+ }
+
+ $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/#mirrors');
+
+ if ($request->isFormPost()) {
+ $mirror->delete();
+ return id(new AphrontReloadResponse())->setURI($edit_uri);
+ }
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($viewer)
+ ->setTitle(pht('Really delete mirror?'))
+ ->appendChild(
+ pht('Phabricator will stop pushing updates to this mirror.'))
+ ->addSubmitButton(pht('Delete Mirror'))
+ ->addCancelButton($edit_uri);
+
+ return id(new AphrontDialogResponse())
+ ->setDialog($dialog);
+ }
+
+
+}
Index: src/applications/diffusion/controller/DiffusionMirrorEditController.php
===================================================================
--- /dev/null
+++ src/applications/diffusion/controller/DiffusionMirrorEditController.php
@@ -0,0 +1,121 @@
+<?php
+
+final class DiffusionMirrorEditController
+ extends DiffusionController {
+
+ private $id;
+
+ public function willProcessRequest(array $data) {
+ $this->id = idx($data, 'id');
+ parent::willProcessRequest($data);
+ }
+
+ public function processRequest() {
+ $request = $this->getRequest();
+ $viewer = $request->getUser();
+ $drequest = $this->diffusionRequest;
+ $repository = $drequest->getRepository();
+
+ if ($this->id) {
+ $mirror = id(new PhabricatorRepositoryMirrorQuery())
+ ->setViewer($viewer)
+ ->withIDs(array($this->id))
+ ->executeOne();
+ if (!$mirror) {
+ return new Aphront404Response();
+ }
+ $is_new = false;
+ } else {
+ $mirror = PhabricatorRepositoryMirror::initializeNewMirror($viewer)
+ ->setRepositoryPHID($repository->getPHID())
+ ->attachRepository($repository);
+ $is_new = true;
+ }
+
+ $edit_uri = $this->getRepositoryControllerURI($repository, 'edit/#mirrors');
+
+ $v_remote = $mirror->getRemoteURI();
+ $e_remote = true;
+
+ $v_credentials = $mirror->getCredentialPHID();
+ $e_credentials = null;
+
+ $credentials = id(new PassphraseCredentialQuery())
+ ->setViewer($viewer)
+ ->withIsDestroyed(false)
+ ->execute();
+
+ $errors = array();
+ if ($request->isFormPost()) {
+ $v_remote = $request->getStr('remoteURI');
+ if (strlen($v_remote)) {
+ $e_remote = null;
+ } else {
+ $e_remote = pht('Required');
+ $errors[] = pht('You must provide a remote URI.');
+ }
+
+ $v_credentials = $request->getStr('credential');
+ if ($v_credentials) {
+ $phids = mpull($credentials, null, 'getPHID');
+ if (empty($phids[$v_credentials])) {
+ $e_credentials = pht('Invalid');
+ $errors[] = pht(
+ 'You do not have permission to use those credentials.');
+ }
+ }
+
+ if (!$errors) {
+ $mirror
+ ->setRemoteURI($v_remote)
+ ->setCredentialPHID($v_credentials)
+ ->save();
+ return id(new AphrontReloadResponse())->setURI($edit_uri);
+ }
+ }
+
+ $form_errors = null;
+ if ($errors) {
+ $form_errors = id(new AphrontErrorView())
+ ->setErrors($errors);
+ }
+
+ if ($is_new) {
+ $title = pht('Create Mirror');
+ $submit = pht('Create Mirror');
+ } else {
+ $title = pht('Edit Mirror');
+ $submit = pht('Save Changes');
+ }
+
+ $form = id(new PHUIFormLayoutView())
+ ->appendChild(
+ id(new AphrontFormTextControl())
+ ->setLabel(pht('Remote URI'))
+ ->setName('remoteURI')
+ ->setValue($v_remote)
+ ->setError($e_remote))
+ ->appendChild(
+ id(new PassphraseCredentialControl())
+ ->setLabel(pht('Credentials'))
+ ->setName('credential')
+ ->setAllowNull(true)
+ ->setValue($v_credentials)
+ ->setError($e_credentials)
+ ->setOptions($credentials));
+
+ $dialog = id(new AphrontDialogView())
+ ->setUser($viewer)
+ ->setTitle($title)
+ ->setWidth(AphrontDialogView::WIDTH_FORM)
+ ->appendChild($form_errors)
+ ->appendChild($form)
+ ->addSubmitButton($submit)
+ ->addCancelButton($edit_uri);
+
+ return id(new AphrontDialogResponse())
+ ->setDialog($dialog);
+ }
+
+
+}
Index: src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
===================================================================
--- src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
+++ src/applications/diffusion/controller/DiffusionRepositoryEditMainController.php
@@ -67,6 +67,7 @@
$repository,
$this->buildHostingActions($repository));
+
$branches_properties = null;
if ($has_branches) {
$branches_properties = $this->buildBranchesProperties(
@@ -114,36 +115,78 @@
->setTransactions($xactions)
->setMarkupEngine($engine);
- $obj_box = id(new PHUIObjectBoxView())
+ $boxes = array();
+
+ $boxes[] = id(new PHUIObjectBoxView())
->setHeader($header)
- ->addPropertyList($basic_properties)
- ->addPropertyList($policy_properties)
+ ->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');
+
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Mirrors'))
+ ->addPropertyList($mirror_properties);
+
+ $boxes[] = $mirror_list;
+ }
+
if ($remote_properties) {
- $obj_box->addPropertyList($remote_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Remote'))
+ ->addPropertyList($remote_properties);
}
if ($local_properties) {
- $obj_box->addPropertyList($local_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Local'))
+ ->addPropertyList($local_properties);
}
- $obj_box->addPropertyList($encoding_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Text Encoding'))
+ ->addPropertyList($encoding_properties);
if ($branches_properties) {
- $obj_box->addPropertyList($branches_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Branches'))
+ ->addPropertyList($branches_properties);
}
if ($subversion_properties) {
- $obj_box->addPropertyList($subversion_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Subversion'))
+ ->addPropertyList($subversion_properties);
}
- $obj_box->addPropertyList($actions_properties);
+ $boxes[] = id(new PHUIObjectBoxView())
+ ->setHeaderText(pht('Actions'))
+ ->addPropertyList($actions_properties);
return $this->buildApplicationPage(
array(
$crumbs,
- $obj_box,
+ $boxes,
$xaction_view,
),
array(
@@ -253,8 +296,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Text Encoding'));
+ ->setActionList($actions);
$encoding = $repository->getDetail('encoding');
if (!$encoding) {
@@ -291,8 +333,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Policies'));
+ ->setActionList($actions);
$descriptions = PhabricatorPolicyQuery::renderPolicyDescriptions(
$viewer,
@@ -339,8 +380,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Branches'));
+ ->setActionList($actions);
$default_branch = nonempty(
$repository->getHumanReadableDetail('default-branch'),
@@ -390,8 +430,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Subversion'));
+ ->setActionList($actions);
$svn_uuid = nonempty(
$repository->getUUID(),
@@ -431,8 +470,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Actions'));
+ ->setActionList($actions);
$notify = $repository->getDetail('herald-disabled')
? pht('Off')
@@ -474,8 +512,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Remote'));
+ ->setActionList($actions);
$view->addProperty(
pht('Remote URI'),
@@ -517,8 +554,7 @@
$view = id(new PHUIPropertyListView())
->setUser($viewer)
- ->setActionList($actions)
- ->addSectionHeader(pht('Local'));
+ ->setActionList($actions);
$view->addProperty(
pht('Local Path'),
@@ -552,8 +588,7 @@
$view = id(new PHUIPropertyListView())
->setUser($user)
- ->setActionList($actions)
- ->addSectionHeader(pht('Hosting'));
+ ->setActionList($actions);
$hosting = $repository->isHosted()
? pht('Hosted on Phabricator')
@@ -903,4 +938,86 @@
return $view;
}
+ private function buildMirrorActions(
+ PhabricatorRepository $repository) {
+
+ $viewer = $this->getRequest()->getUser();
+
+ $mirror_actions = id(new PhabricatorActionListView())
+ ->setObjectURI($this->getRequest()->getRequestURI())
+ ->setUser($viewer);
+
+ $new_mirror_uri = $this->getRepositoryControllerURI(
+ $repository,
+ 'mirror/edit/');
+
+ $mirror_actions->addAction(
+ id(new PhabricatorActionView())
+ ->setName(pht('Add Mirror'))
+ ->setIcon('new')
+ ->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('edit')
+ ->setHref($edit_uri)
+ ->setWorkflow(true));
+
+ $item->addAction(
+ id(new PHUIListItemView())
+ ->setIcon('delete')
+ ->setHref($delete_uri)
+ ->setWorkflow(true));
+
+ $mirror_list->addItem($item);
+ }
+
+ return $mirror_list;
+ }
+
+
}
Index: src/applications/passphrase/view/PassphraseCredentialControl.php
===================================================================
--- src/applications/passphrase/view/PassphraseCredentialControl.php
+++ src/applications/passphrase/view/PassphraseCredentialControl.php
@@ -68,15 +68,19 @@
'sigil' => 'passphrase-credential-select',
));
- $button = javelin_tag(
- 'a',
- array(
- 'href' => '#',
- 'class' => 'button grey',
- 'sigil' => 'passphrase-credential-add',
- 'mustcapture' => true,
- ),
- pht('Add Credential'));
+ if ($this->credentialType) {
+ $button = javelin_tag(
+ 'a',
+ array(
+ 'href' => '#',
+ 'class' => 'button grey',
+ 'sigil' => 'passphrase-credential-add',
+ 'mustcapture' => true,
+ ),
+ pht('Add Credential'));
+ } else {
+ $button = null;
+ }
return javelin_tag(
'div',
Index: src/applications/repository/phid/PhabricatorRepositoryPHIDTypeMirror.php
===================================================================
--- /dev/null
+++ src/applications/repository/phid/PhabricatorRepositoryPHIDTypeMirror.php
@@ -0,0 +1,47 @@
+<?php
+
+final class PhabricatorRepositoryPHIDTypeMirror
+ extends PhabricatorPHIDType {
+
+ const TYPECONST = 'RMIR';
+
+ public function getTypeConstant() {
+ return self::TYPECONST;
+ }
+
+ public function getTypeName() {
+ return pht('Repository Mirror');
+ }
+
+ public function newObject() {
+ return new PhabricatorRepositoryMirror();
+ }
+
+ protected function buildQueryForObjects(
+ PhabricatorObjectQuery $query,
+ array $phids) {
+
+ return id(new PhabricatorRepositoryMirrorQuery())
+ ->withPHIDs($phids);
+ }
+
+ public function loadHandles(
+ PhabricatorHandleQuery $query,
+ array $handles,
+ array $objects) {
+
+ foreach ($handles as $phid => $handle) {
+ $mirror = $objects[$phid];
+
+ $handle->setName(
+ pht('Mirror %d %s', $mirror->getID(), $mirror->getRemoteURI()));
+ $handle->setURI("/diffusion/mirror/".$mirror->getID()."/");
+ }
+ }
+
+ public function canLoadNamedObject($name) {
+ return false;
+ }
+
+
+}
Index: src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
===================================================================
--- /dev/null
+++ src/applications/repository/query/PhabricatorRepositoryMirrorQuery.php
@@ -0,0 +1,101 @@
+<?php
+
+final class PhabricatorRepositoryMirrorQuery
+ extends PhabricatorCursorPagedPolicyAwareQuery {
+
+ private $ids;
+ private $phids;
+ private $repositoryPHIDs;
+
+ public function withIDs(array $ids) {
+ $this->ids = $ids;
+ return $this;
+ }
+
+ public function withPHIDs(array $phids) {
+ $this->phids = $phids;
+ return $this;
+ }
+
+ public function withRepositoryPHIDs(array $repository_phids) {
+ $this->repositoryPHIDs = $repository_phids;
+ return $this;
+ }
+
+ protected function loadPage() {
+ $table = new PhabricatorRepositoryMirror();
+ $conn_r = $table->establishConnection('r');
+
+ $data = queryfx_all(
+ $conn_r,
+ 'SELECT * FROM %T %Q %Q %Q',
+ $table->getTableName(),
+ $this->buildWhereClause($conn_r),
+ $this->buildOrderClause($conn_r),
+ $this->buildLimitClause($conn_r));
+
+ return $table->loadAllFromArray($data);
+ }
+
+ public function willFilterPage(array $mirrors) {
+ assert_instances_of($mirrors, 'PhabricatorRepositoryMirror');
+
+ $repository_phids = mpull($mirrors, 'getRepositoryPHID');
+ if ($repository_phids) {
+ $repositories = id(new PhabricatorRepositoryQuery())
+ ->setViewer($this->getViewer())
+ ->withPHIDs($repository_phids)
+ ->execute();
+ $repositories = mpull($repositories, null, 'getPHID');
+ } else {
+ $repositories = array();
+ }
+
+ foreach ($mirrors as $key => $mirror) {
+ $phid = $mirror->getRepositoryPHID();
+ if (empty($repositories[$phid])) {
+ unset($mirrors[$key]);
+ continue;
+ }
+ $mirror->attachRepository($repositories[$phid]);
+ }
+
+ return $mirrors;
+ }
+
+
+ private function buildWhereClause(AphrontDatabaseConnection $conn_r) {
+ $where = array();
+
+ if ($this->ids) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'id IN (%Ld)',
+ $this->ids);
+ }
+
+ if ($this->phids) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'phid IN (%Ls)',
+ $this->phids);
+ }
+
+ if ($this->repositoryPHIDs) {
+ $where[] = qsprintf(
+ $conn_r,
+ 'repositoryPHID IN (%Ls)',
+ $this->repositoryPHIDs);
+ }
+
+ $where[] = $this->buildPagingClause($conn_r);
+
+ return $this->formatWhereClause($where);
+ }
+
+
+ public function getQueryApplicationClass() {
+ return 'PhabricatorApplicationDiffusion';
+ }
+
+}
Index: src/applications/repository/storage/PhabricatorRepository.php
===================================================================
--- src/applications/repository/storage/PhabricatorRepository.php
+++ src/applications/repository/storage/PhabricatorRepository.php
@@ -744,6 +744,12 @@
$commit->delete();
}
+ $mirrors = id(new PhabricatorRepositoryMirror())
+ ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
+ foreach ($mirrors as $mirror) {
+ $mirror->delete();
+ }
+
$conn_w = $this->establishConnection('w');
queryfx(
@@ -898,6 +904,17 @@
return Filesystem::isDescendant($this->getLocalPath(), $default_path);
}
+ public function canMirror() {
+ if (!$this->isHosted()) {
+ return false;
+ }
+
+ if ($this->isGit()) {
+ return true;
+ }
+
+ return false;
+ }
public function writeStatusMessage(
$status_type,
Index: src/applications/repository/storage/PhabricatorRepositoryMirror.php
===================================================================
--- /dev/null
+++ src/applications/repository/storage/PhabricatorRepositoryMirror.php
@@ -0,0 +1,60 @@
+<?php
+
+final class PhabricatorRepositoryMirror extends PhabricatorRepositoryDAO
+ implements PhabricatorPolicyInterface {
+
+ protected $repositoryPHID;
+ protected $remoteURI;
+ protected $credentialPHID;
+
+ private $repository = self::ATTACHABLE;
+
+ public static function initializeNewMirror(PhabricatorUser $actor) {
+ return id(new PhabricatorRepositoryMirror())
+ ->setRemoteURI('');
+ }
+
+ public function getConfiguration() {
+ return array(
+ self::CONFIG_AUX_PHID => true,
+ ) + parent::getConfiguration();
+ }
+
+ public function generatePHID() {
+ return PhabricatorPHID::generateNewPHID(
+ PhabricatorRepositoryPHIDTypeMirror::TYPECONST);
+ }
+
+ public function attachRepository(PhabricatorRepository $repository) {
+ $this->repository = $repository;
+ return $this;
+ }
+
+ public function getRepository() {
+ return $this->assertAttached($this->repository);
+ }
+
+
+/* -( PhabricatorPolicyInterface )----------------------------------------- */
+
+
+ public function getCapabilities() {
+ return array(
+ PhabricatorPolicyCapability::CAN_VIEW,
+ PhabricatorPolicyCapability::CAN_EDIT,
+ );
+ }
+
+ public function getPolicy($capability) {
+ return $this->getRepository()->getPolicy($capability);
+ }
+
+ public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
+ return $this->getRepository()->hasAutomaticCapability($capability, $viewer);
+ }
+
+ public function describeAutomaticCapability($capability) {
+ return null;
+ }
+
+}
Index: src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
===================================================================
--- src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
+++ src/infrastructure/storage/patch/PhabricatorBuiltinPatchList.php
@@ -1784,6 +1784,10 @@
'type' => 'php',
'name' => $this->getPatchPath('20131121.repocredentials.2.mig.php'),
),
+ '20131122.repomirror.sql' => array(
+ 'type' => 'sql',
+ 'name' => $this->getPatchPath('20131122.repomirror.sql'),
+ ),
);
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 17, 2:57 AM (18 h, 4 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6997966
Default Alt Text
D7632.id17227.diff (26 KB)
Attached To
Mode
D7632: Add UI for defining repository mirrors
Attached
Detach File
Event Timeline
Log In to Comment