Page MenuHomePhorge

No OneTemporary

diff --git a/src/applications/diffusion/controller/DiffusionRepositoryController.php b/src/applications/diffusion/controller/DiffusionRepositoryController.php
index 089ecb6415..9b9bf41c2c 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryController.php
@@ -1,286 +1,292 @@
<?php
final class DiffusionRepositoryController extends DiffusionController {
public function processRequest() {
$drequest = $this->diffusionRequest;
$content = array();
$crumbs = $this->buildCrumbs();
$content[] = $crumbs;
$content[] = $this->buildPropertiesTable($drequest->getRepository());
$history_results = $this->callConduitWithDiffusionRequest(
'diffusion.historyquery',
array(
'commit' => $drequest->getCommit(),
'path' => $drequest->getPath(),
'offset' => 0,
'limit' => 15));
$history = DiffusionPathChange::newFromConduit(
$history_results['pathChanges']);
$browse_results = DiffusionBrowseResultSet::newFromConduit(
$this->callConduitWithDiffusionRequest(
'diffusion.browsequery',
array(
'path' => $drequest->getPath(),
'commit' => $drequest->getCommit(),
)));
$browse_paths = $browse_results->getPaths();
$phids = array();
foreach ($history as $item) {
$data = $item->getCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
if ($data->getCommitDetail('committerPHID')) {
$phids[$data->getCommitDetail('committerPHID')] = true;
}
}
}
foreach ($browse_paths as $item) {
$data = $item->getLastCommitData();
if ($data) {
if ($data->getCommitDetail('authorPHID')) {
$phids[$data->getCommitDetail('authorPHID')] = true;
}
if ($data->getCommitDetail('committerPHID')) {
$phids[$data->getCommitDetail('committerPHID')] = true;
}
}
}
$phids = array_keys($phids);
$handles = $this->loadViewerHandles($phids);
$readme = $this->callConduitWithDiffusionRequest(
'diffusion.readmequery',
array(
'paths' => $browse_results->getPathDicts()
));
$history_table = new DiffusionHistoryTableView();
$history_table->setUser($this->getRequest()->getUser());
$history_table->setDiffusionRequest($drequest);
$history_table->setHandles($handles);
$history_table->setHistory($history);
$history_table->loadRevisions();
$history_table->setParents($history_results['parents']);
$history_table->setIsHead(true);
$callsign = $drequest->getRepository()->getCallsign();
$all = phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'history',
)),
),
pht('View Full Commit History'));
$panel = new AphrontPanelView();
$panel->setHeader(pht("Recent Commits &middot; %s", $all));
$panel->appendChild($history_table);
$panel->setNoBackground();
$content[] = $panel;
$browse_table = new DiffusionBrowseTableView();
$browse_table->setDiffusionRequest($drequest);
$browse_table->setHandles($handles);
$browse_table->setPaths($browse_paths);
$browse_table->setUser($this->getRequest()->getUser());
$browse_panel = new AphrontPanelView();
$browse_panel->setHeader(phutil_tag(
'a',
array('href' => $drequest->generateURI(array('action' => 'browse'))),
pht('Browse Repository')));
$browse_panel->appendChild($browse_table);
$browse_panel->setNoBackground();
$content[] = $browse_panel;
$content[] = $this->buildTagListTable($drequest);
$content[] = $this->buildBranchListTable($drequest);
if ($readme) {
$box = new PHUIBoxView();
$box->setShadow(true);
$box->appendChild($readme);
$box->addPadding(PHUI::PADDING_LARGE);
$panel = new AphrontPanelView();
$panel->setHeader(pht('README'));
$panel->setNoBackground();
$panel->appendChild($box);
$content[] = $panel;
}
return $this->buildApplicationPage(
$content,
array(
'title' => $drequest->getRepository()->getName(),
'dust' => true,
'device' => true,
));
}
private function buildPropertiesTable(PhabricatorRepository $repository) {
+ $user = $this->getRequest()->getUser();
$header = id(new PhabricatorHeaderView())
->setHeader($repository->getName());
- $view = new PhabricatorPropertyListView();
+ $view = id(new PhabricatorPropertyListView())
+ ->setUser($user);
$view->addProperty(pht('Callsign'), $repository->getCallsign());
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$view->addProperty(
pht('Clone URI'),
$repository->getPublicRemoteURI());
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$view->addProperty(
pht('Repository Root'),
$repository->getPublicRemoteURI());
break;
}
$description = $repository->getDetail('description');
if (strlen($description)) {
+ $description = PhabricatorMarkupEngine::renderOneObject(
+ $repository,
+ 'description',
+ $user);
$view->addTextContent($description);
}
return array($header, $view);
}
private function buildBranchListTable(DiffusionRequest $drequest) {
if ($drequest->getBranch() !== null) {
$limit = 15;
$branches = DiffusionBranchInformation::newFromConduit(
$this->callConduitWithDiffusionRequest(
'diffusion.branchquery',
array(
'limit' => $limit
)));
if (!$branches) {
return null;
}
$more_branches = (count($branches) > $limit);
$branches = array_slice($branches, 0, $limit);
$commits = id(new PhabricatorAuditCommitQuery())
->withIdentifiers(
$drequest->getRepository()->getID(),
mpull($branches, 'getHeadCommitIdentifier'))
->needCommitData(true)
->execute();
$table = new DiffusionBranchTableView();
$table->setDiffusionRequest($drequest);
$table->setBranches($branches);
$table->setCommits($commits);
$table->setUser($this->getRequest()->getUser());
$panel = new AphrontPanelView();
$panel->setHeader(pht('Branches'));
$panel->setNoBackground();
if ($more_branches) {
$panel->setCaption(pht('Showing %d branches.', $limit));
}
$panel->addButton(
phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'branches',
)),
'class' => 'grey button',
),
pht("Show All Branches \xC2\xBB")));
$panel->appendChild($table);
return $panel;
}
return null;
}
private function buildTagListTable(DiffusionRequest $drequest) {
$tag_limit = 15;
$tags = array();
try {
$tags = DiffusionRepositoryTag::newFromConduit(
$this->callConduitWithDiffusionRequest(
'diffusion.tagsquery',
array('limit' => $tag_limit + 1)));
} catch (ConduitException $e) {
if ($e->getMessage() != 'ERR-UNSUPPORTED-VCS') {
throw $e;
}
}
if (!$tags) {
return null;
}
$more_tags = (count($tags) > $tag_limit);
$tags = array_slice($tags, 0, $tag_limit);
$commits = id(new PhabricatorAuditCommitQuery())
->withIdentifiers(
$drequest->getRepository()->getID(),
mpull($tags, 'getCommitIdentifier'))
->needCommitData(true)
->execute();
$view = new DiffusionTagListView();
$view->setDiffusionRequest($drequest);
$view->setTags($tags);
$view->setUser($this->getRequest()->getUser());
$view->setCommits($commits);
$phids = $view->getRequiredHandlePHIDs();
$handles = $this->loadViewerHandles($phids);
$view->setHandles($handles);
$panel = new AphrontPanelView();
$panel->setHeader(pht('Tags'));
if ($more_tags) {
$panel->setCaption(pht('Showing the %d most recent tags.', $tag_limit));
}
$panel->addButton(
phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'tags',
)),
'class' => 'grey button',
),
pht("Show All Tags \xC2\xBB")));
$panel->appendChild($view);
return $panel;
}
}
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
index 9ff999911e..c5ac2e8449 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditBasicController.php
@@ -1,133 +1,133 @@
<?php
final class DiffusionRepositoryEditBasicController extends DiffusionController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$drequest = $this->diffusionRequest;
$repository = $drequest->getRepository();
$repository = id(new PhabricatorRepositoryQuery())
->setViewer($user)
->requireCapabilities(
array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
))
->withIDs(array($repository->getID()))
->executeOne();
if (!$repository) {
return new Aphront404Response();
}
$edit_uri = $this->getRepositoryControllerURI($repository, 'edit/');
$v_name = $repository->getName();
$v_desc = $repository->getDetail('description');
$e_name = true;
$errors = array();
if ($request->isFormPost()) {
$v_name = $request->getStr('name');
$v_desc = $request->getStr('description');
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;
$xactions[] = id(clone $template)
->setTransactionType($type_name)
->setNewValue($v_name);
$xactions[] = id(clone $template)
->setTransactionType($type_desc)
->setNewValue($v_desc);
id(new PhabricatorRepositoryEditor())
->setContinueOnNoEffect(true)
->setContentSourceFromRequest($request)
->setActor($user)
->applyTransactions($repository, $xactions);
return id(new AphrontRedirectResponse())->setURI($edit_uri);
}
}
$content = array();
$crumbs = $this->buildCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('Edit Basics')));
$content[] = $crumbs;
$title = pht('Edit %s', $repository->getName());
if ($errors) {
$content[] = id(new AphrontErrorView())
->setTitle(pht('Form Errors'))
->setErrors($errors);
}
$form = id(new AphrontFormView())
->setUser($user)
->setFlexible(true)
->appendChild(
id(new AphrontFormTextControl())
->setName('name')
->setLabel(pht('Name'))
->setValue($v_name)
->setError($e_name))
->appendChild(
- id(new AphrontFormTextAreaControl())
+ id(new PhabricatorRemarkupControl())
->setName('description')
->setLabel(pht('Description'))
->setValue($v_desc))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue(pht('Save'))
->addCancelButton($edit_uri))
->appendChild(id(new PHUIFormDividerControl()))
->appendRemarkupInstructions($this->getReadmeInstructions());
$content[] = $form;
return $this->buildApplicationPage(
$content,
array(
'title' => $title,
'dust' => true,
'device' => true,
));
}
private function getReadmeInstructions() {
return pht(<<<EOTEXT
You can also create a `README` file at the repository root (or in any
subdirectory) to provide information about the repository. These formats are
supported:
| File Name | Rendered As... |
|-----------------|----------------|
| `README` | Plain Text |
| `README.txt` | Plain Text |
| `README.remarkup` | Remarkup |
| `README.md` | Remarkup |
| `README.rainbow` | \xC2\xA1Fiesta! |
EOTEXT
);
}
}
diff --git a/src/applications/diffusion/controller/DiffusionRepositoryEditController.php b/src/applications/diffusion/controller/DiffusionRepositoryEditController.php
index 81d3344030..eead89d4d2 100644
--- a/src/applications/diffusion/controller/DiffusionRepositoryEditController.php
+++ b/src/applications/diffusion/controller/DiffusionRepositoryEditController.php
@@ -1,112 +1,119 @@
<?php
final class DiffusionRepositoryEditController extends DiffusionController {
public function processRequest() {
$request = $this->getRequest();
$user = $request->getUser();
$drequest = $this->diffusionRequest;
$repository = $drequest->getRepository();
$content = array();
$crumbs = $this->buildCrumbs();
$crumbs->addCrumb(
id(new PhabricatorCrumbView())
->setName(pht('Edit')));
$content[] = $crumbs;
$title = pht('Edit %s', $repository->getName());
$content[] = id(new PhabricatorHeaderView())
->setHeader($title);
$content[] = $this->buildBasicActions($repository);
$content[] = $this->buildBasicProperties($repository);
$content[] = id(new PhabricatorHeaderView())
->setHeader(pht('Edit History'));
$xactions = id(new PhabricatorRepositoryTransactionQuery())
->setViewer($user)
->withObjectPHIDs(array($repository->getPHID()))
->execute();
$engine = id(new PhabricatorMarkupEngine())
->setViewer($user);
foreach ($xactions as $xaction) {
if ($xaction->getComment()) {
$engine->addObject(
$xaction->getComment(),
PhabricatorApplicationTransactionComment::MARKUP_FIELD_COMMENT);
}
}
$engine->process();
$xaction_view = id(new PhabricatorApplicationTransactionView())
->setUser($user)
->setTransactions($xactions)
->setMarkupEngine($engine);
$content[] = $xaction_view;
return $this->buildApplicationPage(
$content,
array(
'title' => $title,
'device' => true,
'dust' => true,
));
}
private function buildBasicActions(PhabricatorRepository $repository) {
$user = $this->getRequest()->getUser();
$view = id(new PhabricatorActionListView())
->setUser($user);
$can_edit = PhabricatorPolicyFilter::hasCapability(
$user,
$repository,
PhabricatorPolicyCapability::CAN_EDIT);
$edit = id(new PhabricatorActionView())
->setIcon('edit')
->setName(pht('Edit Basic Information'))
->setHref($this->getRepositoryControllerURI($repository, 'edit/basic/'))
->setDisabled(!$can_edit);
$view->addAction($edit);
return $view;
}
private function buildBasicProperties(PhabricatorRepository $repository) {
+ $user = $this->getRequest()->getUser();
+
$view = id(new PhabricatorPropertyListView())
- ->setUser($this->getRequest()->getUser())
+ ->setUser($user)
->setObject($repository);
$view->addProperty(pht('Name'), $repository->getName());
$view->addProperty(pht('ID'), $repository->getID());
$view->addProperty(pht('PHID'), $repository->getPHID());
$type = PhabricatorRepositoryType::getNameForRepositoryType(
$repository->getVersionControlSystem());
$view->addProperty(pht('Type'), $type);
$view->addProperty(pht('Callsign'), $repository->getCallsign());
$description = $repository->getDetail('description');
+ $view->addSectionHeader(pht('Description'));
if (!strlen($description)) {
- $description = phutil_tag('em', array(), pht('None'));
+ $description = phutil_tag('em', array(), pht('No description provided.'));
+ } else {
+ $description = PhabricatorMarkupEngine::renderOneObject(
+ $repository,
+ 'description',
+ $user);
}
- $view->addProperty(pht('Description'), $description);
-
+ $view->addTextContent($description);
return $view;
}
}
diff --git a/src/applications/repository/storage/PhabricatorRepository.php b/src/applications/repository/storage/PhabricatorRepository.php
index 51195b9518..eeb6f18a8e 100644
--- a/src/applications/repository/storage/PhabricatorRepository.php
+++ b/src/applications/repository/storage/PhabricatorRepository.php
@@ -1,745 +1,781 @@
<?php
/**
* @task uri Repository URI Management
*/
final class PhabricatorRepository extends PhabricatorRepositoryDAO
- implements PhabricatorPolicyInterface {
+ implements
+ PhabricatorPolicyInterface,
+ PhabricatorMarkupInterface {
/**
* Shortest hash we'll recognize in raw "a829f32" form.
*/
const MINIMUM_UNQUALIFIED_HASH = 7;
/**
* Shortest hash we'll recognize in qualified "rXab7ef2f8" form.
*/
const MINIMUM_QUALIFIED_HASH = 5;
const TABLE_PATH = 'repository_path';
const TABLE_PATHCHANGE = 'repository_pathchange';
const TABLE_FILESYSTEM = 'repository_filesystem';
const TABLE_SUMMARY = 'repository_summary';
const TABLE_BADCOMMIT = 'repository_badcommit';
const TABLE_LINTMESSAGE = 'repository_lintmessage';
protected $phid;
protected $name;
protected $callsign;
protected $uuid;
protected $versionControlSystem;
protected $details = array();
private $sshKeyfile;
public function getConfiguration() {
return array(
self::CONFIG_AUX_PHID => true,
self::CONFIG_SERIALIZATION => array(
'details' => self::SERIALIZATION_JSON,
),
) + parent::getConfiguration();
}
public function generatePHID() {
return PhabricatorPHID::generateNewPHID(
PhabricatorPHIDConstants::PHID_TYPE_REPO);
}
public function toDictionary() {
return array(
'name' => $this->getName(),
'phid' => $this->getPHID(),
'callsign' => $this->getCallsign(),
'vcs' => $this->getVersionControlSystem(),
'uri' => PhabricatorEnv::getProductionURI($this->getURI()),
'remoteURI' => (string)$this->getPublicRemoteURI(),
'tracking' => $this->getDetail('tracking-enabled'),
'description' => $this->getDetail('description'),
);
}
public function getDetail($key, $default = null) {
return idx($this->details, $key, $default);
}
public function setDetail($key, $value) {
$this->details[$key] = $value;
return $this;
}
public function getDiffusionBrowseURIForPath(
PhabricatorUser $user,
$path,
$line = null,
$branch = null) {
$drequest = DiffusionRequest::newFromDictionary(
array(
'user' => $user,
'repository' => $this,
'path' => $path,
'branch' => $branch,
));
return $drequest->generateURI(
array(
'action' => 'browse',
'line' => $line,
));
}
public function getLocalPath() {
return $this->getDetail('local-path');
}
public function getSubversionBaseURI() {
$vcs = $this->getVersionControlSystem();
if ($vcs != PhabricatorRepositoryType::REPOSITORY_TYPE_SVN) {
throw new Exception("Not a subversion repository!");
}
$uri = $this->getDetail('remote-uri');
$subpath = $this->getDetail('svn-subpath');
return $uri.$subpath;
}
public function execRemoteCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatRemoteCommand($args);
return call_user_func_array('exec_manual', $args);
}
public function execxRemoteCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatRemoteCommand($args);
return call_user_func_array('execx', $args);
}
public function getRemoteCommandFuture($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatRemoteCommand($args);
return newv('ExecFuture', $args);
}
public function passthruRemoteCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatRemoteCommand($args);
return call_user_func_array('phutil_passthru', $args);
}
public function execLocalCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatLocalCommand($args);
return call_user_func_array('exec_manual', $args);
}
public function execxLocalCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatLocalCommand($args);
return call_user_func_array('execx', $args);
}
public function getLocalCommandFuture($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatLocalCommand($args);
return newv('ExecFuture', $args);
}
public function passthruLocalCommand($pattern /* , $arg, ... */) {
$args = func_get_args();
$args = $this->formatLocalCommand($args);
return call_user_func_array('phutil_passthru', $args);
}
private function formatRemoteCommand(array $args) {
$pattern = $args[0];
$args = array_slice($args, 1);
$empty = $this->getEmptyReadableDirectoryPath();
if ($this->shouldUseSSH()) {
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$pattern = "SVN_SSH=%s svn --non-interactive {$pattern}";
array_unshift(
$args,
csprintf(
'ssh -l %s -i %s',
$this->getSSHLogin(),
$this->getSSHKeyfile()));
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$command = call_user_func_array(
'csprintf',
array_merge(
array(
"(ssh-add %s && HOME=%s git {$pattern})",
$this->getSSHKeyfile(),
$empty,
),
$args));
$pattern = "ssh-agent sh -c %s";
$args = array($command);
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$pattern = "hg --config ui.ssh=%s {$pattern}";
array_unshift(
$args,
csprintf(
'ssh -l %s -i %s',
$this->getSSHLogin(),
$this->getSSHKeyfile()));
break;
default:
throw new Exception("Unrecognized version control system.");
}
} else if ($this->shouldUseHTTP()) {
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$pattern =
"svn ".
"--non-interactive ".
"--no-auth-cache ".
"--trust-server-cert ".
"--username %s ".
"--password %s ".
$pattern;
array_unshift(
$args,
$this->getDetail('http-login'),
$this->getDetail('http-pass'));
break;
default:
throw new Exception(
"No support for HTTP Basic Auth in this version control system.");
}
} else if ($this->shouldUseSVNProtocol()) {
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$pattern =
"svn ".
"--non-interactive ".
"--no-auth-cache ".
"--username %s ".
"--password %s ".
$pattern;
array_unshift(
$args,
$this->getDetail('http-login'),
$this->getDetail('http-pass'));
break;
default:
throw new Exception(
"SVN protocol is SVN only.");
}
} else {
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$pattern = "svn --non-interactive {$pattern}";
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$pattern = "HOME=%s git {$pattern}";
array_unshift($args, $empty);
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$pattern = "hg {$pattern}";
break;
default:
throw new Exception("Unrecognized version control system.");
}
}
array_unshift($args, $pattern);
return $args;
}
private function formatLocalCommand(array $args) {
$pattern = $args[0];
$args = array_slice($args, 1);
$empty = $this->getEmptyReadableDirectoryPath();
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$pattern = "(cd %s && svn --non-interactive {$pattern})";
array_unshift($args, $this->getLocalPath());
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$pattern = "(cd %s && HOME=%s git {$pattern})";
array_unshift($args, $this->getLocalPath(), $empty);
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
$hgplain = (phutil_is_windows() ? "set HGPLAIN=1 &&" : "HGPLAIN=1");
$pattern = "(cd %s && {$hgplain} hg {$pattern})";
array_unshift($args, $this->getLocalPath());
break;
default:
throw new Exception("Unrecognized version control system.");
}
array_unshift($args, $pattern);
return $args;
}
private function getEmptyReadableDirectoryPath() {
// See T2965. Some time after Git 1.7.5.4, Git started fataling if it can
// not read $HOME. For many users, $HOME points at /root (this seems to be
// a default result of Apache setup). Instead, explicitly point $HOME at a
// readable, empty directory so that Git looks for the config file it's
// after, fails to locate it, and moves on. This is really silly, but seems
// like the least damaging approach to mitigating the issue.
$root = dirname(phutil_get_library_root('phabricator'));
return $root.'/support/empty/';
}
private function getSSHLogin() {
return $this->getDetail('ssh-login');
}
private function getSSHKeyfile() {
if ($this->sshKeyfile === null) {
$key = $this->getDetail('ssh-key');
$keyfile = $this->getDetail('ssh-keyfile');
if ($keyfile) {
// Make sure we can read the file, that it exists, etc.
Filesystem::readFile($keyfile);
$this->sshKeyfile = $keyfile;
} else if ($key) {
$keyfile = new TempFile('phabricator-repository-ssh-key');
chmod($keyfile, 0600);
Filesystem::writeFile($keyfile, $key);
$this->sshKeyfile = $keyfile;
} else {
$this->sshKeyfile = '';
}
}
return (string)$this->sshKeyfile;
}
public function getURI() {
return '/diffusion/'.$this->getCallsign().'/';
}
public function isTracked() {
return $this->getDetail('tracking-enabled', false);
}
public function getDefaultBranch() {
$default = $this->getDetail('default-branch');
if (strlen($default)) {
return $default;
}
$default_branches = array(
PhabricatorRepositoryType::REPOSITORY_TYPE_GIT => 'master',
PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL => 'default',
);
return idx($default_branches, $this->getVersionControlSystem());
}
public function getDefaultArcanistBranch() {
return coalesce($this->getDefaultBranch(), 'svn');
}
private function isBranchInFilter($branch, $filter_key) {
$vcs = $this->getVersionControlSystem();
$is_git = ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
$use_filter = ($is_git);
if ($use_filter) {
$filter = $this->getDetail($filter_key, array());
if ($filter && empty($filter[$branch])) {
return false;
}
}
// By default, all branches pass.
return true;
}
public function shouldTrackBranch($branch) {
return $this->isBranchInFilter($branch, 'branch-filter');
}
public function shouldAutocloseBranch($branch) {
if ($this->getDetail('disable-autoclose', false)) {
return false;
}
return $this->isBranchInFilter($branch, 'close-commits-filter');
}
public function shouldAutocloseCommit(
PhabricatorRepositoryCommit $commit,
PhabricatorRepositoryCommitData $data) {
if ($this->getDetail('disable-autoclose', false)) {
return false;
}
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
return true;
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL:
return true;
default:
throw new Exception("Unrecognized version control system.");
}
$branches = $data->getCommitDetail('seenOnBranches', array());
foreach ($branches as $branch) {
if ($this->shouldAutocloseBranch($branch)) {
return true;
}
}
return false;
}
public function formatCommitName($commit_identifier) {
$vcs = $this->getVersionControlSystem();
$type_git = PhabricatorRepositoryType::REPOSITORY_TYPE_GIT;
$type_hg = PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL;
$is_git = ($vcs == $type_git);
$is_hg = ($vcs == $type_hg);
if ($is_git || $is_hg) {
$short_identifier = substr($commit_identifier, 0, 12);
} else {
$short_identifier = $commit_identifier;
}
return 'r'.$this->getCallsign().$short_identifier;
}
public static function loadAllByPHIDOrCallsign(array $names) {
$repositories = array();
foreach ($names as $name) {
$repo = id(new PhabricatorRepository())->loadOneWhere(
'phid = %s OR callsign = %s',
$name,
$name);
if (!$repo) {
throw new Exception(
"No repository with PHID or callsign '{$name}' exists!");
}
$repositories[$repo->getID()] = $repo;
}
return $repositories;
}
/* -( Repository URI Management )------------------------------------------ */
/**
* Get the remote URI for this repository.
*
* @return string
* @task uri
*/
public function getRemoteURI() {
return (string)$this->getRemoteURIObject();
}
/**
* Get the remote URI for this repository, without authentication information.
*
* @return string Repository URI.
* @task uri
*/
public function getPublicRemoteURI() {
$uri = $this->getRemoteURIObject();
// Make sure we don't leak anything if this repo is using HTTP Basic Auth
// with the credentials in the URI or something zany like that.
if ($uri instanceof PhutilGitURI) {
if (!$this->getDetail('show-user', false)) {
$uri->setUser(null);
}
} else {
if (!$this->getDetail('show-user', false)) {
$uri->setUser(null);
}
$uri->setPass(null);
}
return (string)$uri;
}
/**
* Get the protocol for the repository's remote.
*
* @return string Protocol, like "ssh" or "git".
* @task uri
*/
public function getRemoteProtocol() {
$uri = $this->getRemoteURIObject();
if ($uri instanceof PhutilGitURI) {
return 'ssh';
} else {
return $uri->getProtocol();
}
}
/**
* Get a parsed object representation of the repository's remote URI. This
* may be a normal URI (returned as a @{class@libphutil:PhutilURI}) or a git
* URI (returned as a @{class@libphutil:PhutilGitURI}).
*
* @return wild A @{class@libphutil:PhutilURI} or
* @{class@libphutil:PhutilGitURI}.
* @task uri
*/
private function getRemoteURIObject() {
$raw_uri = $this->getDetail('remote-uri');
if (!$raw_uri) {
return new PhutilURI('');
}
if (!strncmp($raw_uri, '/', 1)) {
return new PhutilURI('file://'.$raw_uri);
}
$uri = new PhutilURI($raw_uri);
if ($uri->getProtocol()) {
if ($this->isSSHProtocol($uri->getProtocol())) {
if ($this->getSSHLogin()) {
$uri->setUser($this->getSSHLogin());
}
}
return $uri;
}
$uri = new PhutilGitURI($raw_uri);
if ($uri->getDomain()) {
if ($this->getSSHLogin()) {
$uri->setUser($this->getSSHLogin());
}
return $uri;
}
throw new Exception("Remote URI '{$raw_uri}' could not be parsed!");
}
/**
* Determine if we should connect to the remote using SSH flags and
* credentials.
*
* @return bool True to use the SSH protocol.
* @task uri
*/
private function shouldUseSSH() {
$protocol = $this->getRemoteProtocol();
if ($this->isSSHProtocol($protocol)) {
return (bool)$this->getSSHKeyfile();
} else {
return false;
}
}
/**
* Determine if we should connect to the remote using HTTP flags and
* credentials.
*
* @return bool True to use the HTTP protocol.
* @task uri
*/
private function shouldUseHTTP() {
$protocol = $this->getRemoteProtocol();
if ($protocol == 'http' || $protocol == 'https') {
return (bool)$this->getDetail('http-login');
} else {
return false;
}
}
/**
* Determine if we should connect to the remote using SVN flags and
* credentials.
*
* @return bool True to use the SVN protocol.
* @task uri
*/
private function shouldUseSVNProtocol() {
$protocol = $this->getRemoteProtocol();
if ($protocol == 'svn') {
return (bool)$this->getDetail('http-login');
} else {
return false;
}
}
/**
* Determine if a protocol is SSH or SSH-like.
*
* @param string A protocol string, like "http" or "ssh".
* @return bool True if the protocol is SSH-like.
* @task uri
*/
private function isSSHProtocol($protocol) {
return ($protocol == 'ssh' || $protocol == 'svn+ssh');
}
public function delete() {
$this->openTransaction();
$paths = id(new PhabricatorOwnersPath())
->loadAllWhere('repositoryPHID = %s', $this->getPHID());
foreach ($paths as $path) {
$path->delete();
}
$projects = id(new PhabricatorRepositoryArcanistProject())
->loadAllWhere('repositoryID = %d', $this->getID());
foreach ($projects as $project) {
// note each project deletes its PhabricatorRepositorySymbols
$project->delete();
}
$commits = id(new PhabricatorRepositoryCommit())
->loadAllWhere('repositoryID = %d', $this->getID());
foreach ($commits as $commit) {
// note PhabricatorRepositoryAuditRequests and
// PhabricatorRepositoryCommitData are deleted here too.
$commit->delete();
}
$conn_w = $this->establishConnection('w');
queryfx(
$conn_w,
'DELETE FROM %T WHERE repositoryID = %d',
self::TABLE_FILESYSTEM,
$this->getID());
queryfx(
$conn_w,
'DELETE FROM %T WHERE repositoryID = %d',
self::TABLE_PATHCHANGE,
$this->getID());
queryfx(
$conn_w,
'DELETE FROM %T WHERE repositoryID = %d',
self::TABLE_SUMMARY,
$this->getID());
$result = parent::delete();
$this->saveTransaction();
return $result;
}
public function isGit() {
$vcs = $this->getVersionControlSystem();
return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_GIT);
}
public function isSVN() {
$vcs = $this->getVersionControlSystem();
return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_SVN);
}
public function isHg() {
$vcs = $this->getVersionControlSystem();
return ($vcs == PhabricatorRepositoryType::REPOSITORY_TYPE_MERCURIAL);
}
/**
* Link external bug tracking system if defined.
*
* @param string Plain text.
* @param string Commit identifier.
* @return string Remarkup
*/
public function linkBugtraq($message, $revision = null) {
$bugtraq_url = PhabricatorEnv::getEnvConfig('bugtraq.url');
list($bugtraq_re, $id_re) =
PhabricatorEnv::getEnvConfig('bugtraq.logregex') +
array('', '');
switch ($this->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
// TODO: Get bugtraq:logregex and bugtraq:url from SVN properties.
break;
}
if (!$bugtraq_url || $bugtraq_re == '') {
return $message;
}
$matches = null;
$flags = PREG_SET_ORDER | PREG_OFFSET_CAPTURE;
preg_match_all('('.$bugtraq_re.')', $message, $matches, $flags);
foreach ($matches as $match) {
list($all, $all_offset) = array_shift($match);
if ($id_re != '') {
// Match substrings with bug IDs
preg_match_all('('.$id_re.')', $all, $match, PREG_OFFSET_CAPTURE);
list(, $match) = $match;
} else {
$all_offset = 0;
}
foreach ($match as $val) {
list($s, $offset) = $val;
$message = substr_replace(
$message,
'[[ '.str_replace('%BUGID%', $s, $bugtraq_url).' | '.$s.' ]]',
$offset + $all_offset,
strlen($s));
}
}
return $message;
}
/* -( PhabricatorPolicyInterface )----------------------------------------- */
public function getCapabilities() {
return array(
PhabricatorPolicyCapability::CAN_VIEW,
PhabricatorPolicyCapability::CAN_EDIT,
);
}
public function getPolicy($capability) {
switch ($capability) {
case PhabricatorPolicyCapability::CAN_VIEW:
return PhabricatorPolicies::POLICY_USER;
case PhabricatorPolicyCapability::CAN_EDIT:
return PhabricatorPolicies::POLICY_ADMIN;
}
}
public function hasAutomaticCapability($capability, PhabricatorUser $user) {
return false;
}
+
+/* -( PhabricatorMarkupInterface )----------------------------------------- */
+
+
+ public function getMarkupFieldKey($field) {
+ $hash = PhabricatorHash::digestForIndex($this->getMarkupText($field));
+ return "repo:{$hash}";
+ }
+
+ public function newMarkupEngine($field) {
+ return PhabricatorMarkupEngine::newMarkupEngine(array());
+ }
+
+ public function getMarkupText($field) {
+ return $this->getDetail('description');
+ }
+
+ public function didMarkupText(
+ $field,
+ $output,
+ PhutilMarkupEngine $engine) {
+ require_celerity_resource('phabricator-remarkup-css');
+ return phutil_tag(
+ 'div',
+ array(
+ 'class' => 'phabricator-remarkup',
+ ),
+ $output);
+ }
+
+ public function shouldUseMarkupCache($field) {
+ return true;
+ }
+
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 13:42 (3 w, 3 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1125174
Default Alt Text
(39 KB)

Event Timeline