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:
parent
55ff197f2a
commit
7f43cde82d
6 changed files with 196 additions and 4 deletions
|
@ -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',
|
||||
|
|
|
@ -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',
|
||||
|
|
|
@ -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,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue