1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-10 08:52:39 +01:00

Add a "refs" table to Diffusion

Summary:
Ref T7100. When a user navigates to a branch like "default" which is ambiguous:

  - don't fatal;
  - choose one alternative to resolve it to (currently more or less at random);
  - sometimes show what we did in the UI.

Also, add a new table to show the alternatives.

This will get refined in followup changes.

Test Plan:
{F384335}

{F384336}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T7100

Differential Revision: https://secure.phabricator.com/D12547
This commit is contained in:
epriestley 2015-04-27 03:49:57 -07:00
parent 55ff197f2a
commit 7f43cde82d
6 changed files with 196 additions and 4 deletions

View file

@ -577,6 +577,7 @@ phutil_register_library_map(array(
'DiffusionRawDiffQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRawDiffQueryConduitAPIMethod.php',
'DiffusionReadmeView' => 'applications/diffusion/view/DiffusionReadmeView.php',
'DiffusionRefNotFoundException' => 'applications/diffusion/exception/DiffusionRefNotFoundException.php',
'DiffusionRefTableController' => 'applications/diffusion/controller/DiffusionRefTableController.php',
'DiffusionRefsQueryConduitAPIMethod' => 'applications/diffusion/conduit/DiffusionRefsQueryConduitAPIMethod.php',
'DiffusionRenameHistoryQuery' => 'applications/diffusion/query/DiffusionRenameHistoryQuery.php',
'DiffusionRepositoryByIDRemarkupRule' => 'applications/diffusion/remarkup/DiffusionRepositoryByIDRemarkupRule.php',
@ -3789,6 +3790,7 @@ phutil_register_library_map(array(
'DiffusionRawDiffQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionReadmeView' => 'DiffusionView',
'DiffusionRefNotFoundException' => 'Exception',
'DiffusionRefTableController' => 'DiffusionController',
'DiffusionRefsQueryConduitAPIMethod' => 'DiffusionQueryConduitAPIMethod',
'DiffusionRepositoryByIDRemarkupRule' => 'PhabricatorObjectRemarkupRule',
'DiffusionRepositoryController' => 'DiffusionController',

View file

@ -76,6 +76,7 @@ final class PhabricatorDiffusionApplication extends PhabricatorApplication {
'diff/' => 'DiffusionDiffController',
'tags/(?P<dblob>.*)' => 'DiffusionTagListController',
'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController',
'refs/(?P<dblob>.*)' => 'DiffusionRefTableController',
'lint/(?P<dblob>.*)' => 'DiffusionLintController',
'commit/(?P<commit>[a-z0-9]+)/branches/'
=> 'DiffusionCommitBranchesController',

View file

@ -0,0 +1,131 @@
<?php
final class DiffusionRefTableController extends DiffusionController {
public function shouldAllowPublic() {
return true;
}
protected function processDiffusionRequest(AphrontRequest $request) {
$viewer = $this->getViewer();
$drequest = $this->getDiffusionRequest();
$repository = $drequest->getRepository();
if (!$drequest->supportsBranches()) {
return $this->newDialog()
->setTitle(pht('No Ref Support'))
->appendParagraph(
pht(
'The version control system this repository uses does not '.
'support named references, so you can not resolve or list '.
'repository refs in this repository.'))
->addCancelButton($repository->getURI());
}
$ref_name = $drequest->getBranch();
$cache_query = id(new DiffusionCachedResolveRefsQuery())
->setRepository($repository);
if ($ref_name !== null) {
$cache_query->withRefs(array($ref_name));
}
$cache_refs = $cache_query->execute();
$vcs_refs = DiffusionQuery::callConduitWithDiffusionRequest(
$viewer,
$drequest,
'diffusion.resolverefs',
array(
'refs' => array($ref_name),
));
$all = array();
foreach ($cache_refs as $ref => $results) {
foreach ($results as $result) {
$id = $result['type'].'/'.$result['identifier'];
$all[$ref][$id]['cache'] = $result;
}
}
foreach ($vcs_refs as $ref => $results) {
foreach ($results as $result) {
$id = $result['type'].'/'.$result['identifier'];
$all[$ref][$id]['vcs'] = $result;
}
}
$rows = array();
foreach ($all as $ref => $results) {
foreach ($results as $info) {
$cache = idx($info, 'cache', array());
$vcs = idx($info, 'vcs', array());
$type = idx($vcs, 'type');
if (!$type) {
$type = idx($cache, 'type');
}
$identifier = idx($vcs, 'identifier');
if ($identifier !== null) {
$identifier = DiffusionView::linkCommit(
$repository,
$identifier);
}
$cache_identifier = idx($cache, 'identifier');
if ($cache_identifier !== null) {
$cache_identifier = DiffusionView::linkCommit(
$repository,
$cache_identifier);
}
$alternate = idx($vcs, 'alternate');
if ($alternate !== null) {
$alternate = DiffusionView::linkCommit(
$repository,
$alternate);
}
$rows[] = array(
$ref,
$type,
$identifier,
$cache_identifier,
$alternate,
);
}
}
$table = id(new AphrontTableView($rows))
->setHeaders(
array(
pht('Ref'),
pht('Type'),
pht('Identifier'),
pht('Cached'),
pht('Alternate'),
));
$content = id(new PHUIObjectBoxView())
->setHeaderText(pht('Ref "%s"', $ref_name))
->appendChild($table);
$crumbs = $this->buildCrumbs(array());
$crumbs->addTextCrumb(pht('Refs'));
return $this->buildApplicationPage(
array(
$crumbs,
$content,
),
array(
'title' => array(
pht('Refs'),
$repository->getMonogram(),
$ref_name,
),
));
}
}

View file

@ -303,10 +303,40 @@ final class DiffusionRepositoryController extends DiffusionController {
$view->setActionList($actions);
return id(new PHUIObjectBoxView())
$box = id(new PHUIObjectBoxView())
->setHeader($header)
->addPropertyList($view);
$info = null;
$drequest = $this->getDiffusionRequest();
if ($drequest->getRefAlternatives()) {
$message = array(
pht(
'The ref "%s" is ambiguous in this repository.',
$drequest->getBranch()),
' ',
phutil_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'refs',
)),
),
pht('View Alternatives')),
);
$messages = array($message);
$info = id(new PHUIInfoView())
->setSeverity(PHUIInfoView::SEVERITY_WARNING)
->setErrors(array($message));
$box->setInfoView($info);
}
return $box;
}
private function buildBranchListTable(DiffusionRequest $drequest) {

View file

@ -45,6 +45,8 @@ final class DiffusionLowLevelResolveRefsQuery
private function resolveGitRefs() {
$repository = $this->getRepository();
// TODO: When refs are ambiguous (for example, tags and branches with
// the same name) this will only resolve one of them.
$future = $repository->getLocalCommandFuture('cat-file --batch-check');
$future->write(implode("\n", $this->refs));
list($stdout) = $future->resolvex();

View file

@ -28,6 +28,7 @@ abstract class DiffusionRequest {
private $initFromConduit = true;
private $user;
private $branchObject = false;
private $refAlternatives;
abstract public function supportsBranches();
abstract protected function isStableCommit($symbol);
@ -528,6 +529,7 @@ abstract class DiffusionRequest {
case 'tags':
case 'branches':
case 'lint':
case 'refs':
$req_callsign = true;
break;
case 'branch':
@ -559,6 +561,7 @@ abstract class DiffusionRequest {
case 'branches':
case 'lint':
case 'pathtree':
case 'refs':
$uri = "/diffusion/{$callsign}{$action}/{$path}{$commit}{$line}";
break;
case 'branch':
@ -728,18 +731,41 @@ abstract class DiffusionRequest {
$results = $this->resolveRefs(array($ref));
$matches = idx($results, $ref, array());
if (count($matches) !== 1) {
$message = pht('Ref "%s" is ambiguous or does not exist.', $ref);
if (!$matches) {
$message = pht(
'Ref "%s" does not exist in this repository.',
$ref);
throw id(new DiffusionRefNotFoundException($message))
->setRef($ref);
}
$match = head($matches);
if (count($matches) > 1) {
$match = $this->chooseBestRefMatch($ref, $matches);
} else {
$match = head($matches);
}
$this->stableCommit = $match['identifier'];
$this->symbolicType = $match['type'];
}
public function getRefAlternatives() {
// Make sure we've resolved the reference into a stable commit first.
$this->getStableCommit();
return $this->refAlternatives;
}
private function chooseBestRefMatch($ref, array $results) {
// TODO: Do a better job of selecting the best match.
$match = head($results);
// After choosing the best alternative, save all the alternatives so the
// UI can show them to the user.
$this->refAlternatives = $results;
return $match;
}
protected function getResolvableBranchName($branch) {
return $branch;
}