Page MenuHomePhabricator

D7632.diff
No OneTemporary

D7632.diff

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',
@@ -1770,8 +1772,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',
@@ -2823,6 +2828,8 @@
'DiffusionMercurialRawDiffQuery' => 'DiffusionRawDiffQuery',
'DiffusionMercurialRequest' => 'DiffusionRequest',
'DiffusionMercurialResponse' => 'AphrontResponse',
+ 'DiffusionMirrorDeleteController' => 'DiffusionController',
+ 'DiffusionMirrorEditController' => 'DiffusionController',
'DiffusionPathCompleteController' => 'DiffusionController',
'DiffusionPathQueryTestCase' => 'PhabricatorTestCase',
'DiffusionPathValidateController' => 'DiffusionController',
@@ -4253,8 +4260,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
@@ -740,6 +740,12 @@
$commit->delete();
}
+ $mirrors = id(new PhabricatorRepositoryMirror())
+ ->loadAllWhere('repositoryPHID = %s', $this->getPHID());
+ foreach ($mirrors as $mirror) {
+ $mirror->delete();
+ }
+
$conn_w = $this->establishConnection('w');
queryfx(
@@ -894,6 +900,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

Mime Type
text/plain
Expires
Sat, May 18, 4:43 AM (2 w, 11 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6293518
Default Alt Text
D7632.diff (26 KB)

Event Timeline