1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-24 14:30:56 +01:00

Branch view improvements.

Summary:
Sorting by last commit date
Branch view limit to 25 branches
All branches table page with pagination on Git

Test Plan:
* Check repository view for expected behavior on branch table view
* Check all branches page & test pagination

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Koolvin

Maniphest Tasks: T1200

Differential Revision: https://secure.phabricator.com/D2442
This commit is contained in:
Aurelijus 2012-05-10 09:28:19 +02:00 committed by epriestley
parent 4921f3f13b
commit ba98089426
11 changed files with 240 additions and 49 deletions

View file

@ -302,6 +302,7 @@ phutil_register_library_map(array(
'DifferentialUnitTestResult' => 'applications/differential/constants/unittestresult', 'DifferentialUnitTestResult' => 'applications/differential/constants/unittestresult',
'DiffusionBranchInformation' => 'applications/diffusion/data/branch', 'DiffusionBranchInformation' => 'applications/diffusion/data/branch',
'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base', 'DiffusionBranchQuery' => 'applications/diffusion/query/branch/base',
'DiffusionBranchTableController' => 'applications/diffusion/controller/branchtable',
'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable', 'DiffusionBranchTableView' => 'applications/diffusion/view/branchtable',
'DiffusionBrowseController' => 'applications/diffusion/controller/browse', 'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file', 'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
@ -1297,6 +1298,7 @@ phutil_register_library_map(array(
'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialTestPlanFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialTitleFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialTitleFieldSpecification' => 'DifferentialFieldSpecification',
'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification', 'DifferentialUnitFieldSpecification' => 'DifferentialFieldSpecification',
'DiffusionBranchTableController' => 'DiffusionController',
'DiffusionBranchTableView' => 'DiffusionView', 'DiffusionBranchTableView' => 'DiffusionView',
'DiffusionBrowseController' => 'DiffusionController', 'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController', 'DiffusionBrowseFileController' => 'DiffusionController',

View file

@ -248,6 +248,7 @@ class AphrontDefaultApplicationConfiguration
'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController', 'lastmodified/(?P<dblob>.*)' => 'DiffusionLastModifiedController',
'diff/' => 'DiffusionDiffController', 'diff/' => 'DiffusionDiffController',
'tags/(?P<dblob>.*)' => 'DiffusionTagListController', 'tags/(?P<dblob>.*)' => 'DiffusionTagListController',
'branches/(?P<dblob>.*)' => 'DiffusionBranchTableController',
), ),
'inline/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController', 'inline/(?P<phid>[^/]+)/' => 'DiffusionInlineCommentController',
'services/' => array( 'services/' => array(

View file

@ -164,6 +164,7 @@ abstract class DiffusionController extends PhabricatorController {
$spec = $spec + array( $spec = $spec + array(
'commit' => null, 'commit' => null,
'tags' => null, 'tags' => null,
'branches' => null,
'view' => null, 'view' => null,
); );
@ -193,16 +194,17 @@ abstract class DiffusionController extends PhabricatorController {
$callsign = $repository->getCallsign(); $callsign = $repository->getCallsign();
$repository_name = phutil_escape_html($repository->getName()).' Repository'; $repository_name = phutil_escape_html($repository->getName()).' Repository';
if (!$spec['commit'] && !$spec['tags']) { if (!$spec['commit'] && !$spec['tags'] && !$spec['branches']) {
$branch_name = $drequest->getBranch(); $branch_name = $drequest->getBranch();
if ($branch_name) { if ($branch_name) {
$repository_name .= ' ('.phutil_escape_html($branch_name).')'; $repository_name .= ' ('.phutil_escape_html($branch_name).')';
} }
} }
if (!$spec['view'] && !$spec['commit'] && !$spec['tags']) { if (!$spec['view'] && !$spec['commit']
$crumb_list[] = $repository_name; && !$spec['tags'] && !$spec['branches']) {
return $crumb_list; $crumb_list[] = $repository_name;
return $crumb_list;
} }
$crumb_list[] = phutil_render_tag( $crumb_list[] = phutil_render_tag(
@ -232,6 +234,11 @@ abstract class DiffusionController extends PhabricatorController {
return $crumb_list; return $crumb_list;
} }
if ($spec['branches']) {
$crumb_list[] = 'Branches';
return $crumb_list;
}
if ($spec['commit']) { if ($spec['commit']) {
$crumb_list[] = "r{$callsign}{$raw_commit}"; $crumb_list[] = "r{$callsign}{$raw_commit}";
return $crumb_list; return $crumb_list;

View file

@ -0,0 +1,85 @@
<?php
/*
* Copyright 2012 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
final class DiffusionBranchTableController extends DiffusionController {
public function processRequest() {
$drequest = $this->getDiffusionRequest();
$request = $this->getRequest();
$user = $request->getUser();
$repository = $drequest->getRepository();
$pager = new AphrontPagerView();
$pager->setURI($request->getRequestURI(), 'offset');
$pager->setOffset($request->getInt('offset'));
// TODO: Add support for branches that contain commit
$query = DiffusionBranchQuery::newFromDiffusionRequest($drequest);
$query->setOffset($pager->getOffset());
// we add 2 here, because of removed HEAD branch
$query->setLimit($pager->getPageSize() + 2);
$branches = $query->loadBranches();
$branches = $pager->sliceResults($branches);
$content = null;
if (!$branches) {
$content = new AphrontErrorView();
$content->setTitle('No Branches');
$content->appendChild('This repository has no branches.');
$content->setSeverity(AphrontErrorView::SEVERITY_NODATA);
} else {
$commits = id(new PhabricatorAuditCommitQuery())
->withIdentifiers(
$drequest->getRepository()->getID(),
mpull($branches, 'getHeadCommitIdentifier'))
->needCommitData(true)
->execute();
$view = id(new DiffusionBranchTableView())
->setBranches($branches)
->setUser($user)
->setCommits($commits)
->setDiffusionRequest($drequest);
$panel = id(new AphrontPanelView())
->setHeader('Branches')
->appendChild($view)
->appendChild($pager);
$content = $panel;
}
return $this->buildStandardPageResponse(
array(
$this->buildCrumbs(
array(
'branches' => true,
)),
$content,
),
array(
'title' => array(
'Branches',
$repository->getCallsign().' Repository',
),
));
}
}

View file

@ -0,0 +1,20 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/audit/query/commit');
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
phutil_require_module('phabricator', 'applications/diffusion/query/branch/base');
phutil_require_module('phabricator', 'applications/diffusion/view/branchtable');
phutil_require_module('phabricator', 'view/control/pager');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'utils');
phutil_require_source('DiffusionBranchTableController.php');

View file

@ -95,29 +95,7 @@ final class DiffusionRepositoryController extends DiffusionController {
$content[] = $this->buildTagListTable($drequest); $content[] = $this->buildTagListTable($drequest);
if ($drequest->getBranch() !== null) { $content[] = $this->buildBranchListTable($drequest);
$branch_query = DiffusionBranchQuery::newFromDiffusionRequest($drequest);
$branches = $branch_query->loadBranches();
$commits = id(new PhabricatorAuditCommitQuery())
->withIdentifiers(
$drequest->getRepository()->getID(),
mpull($branches, 'getHeadCommitIdentifier'))
->needCommitData(true)
->execute();
$branch_table = new DiffusionBranchTableView();
$branch_table->setDiffusionRequest($drequest);
$branch_table->setBranches($branches);
$branch_table->setCommits($commits);
$branch_table->setUser($this->getRequest()->getUser());
$branch_panel = new AphrontPanelView();
$branch_panel->setHeader('Branches');
$branch_panel->appendChild($branch_table);
$content[] = $branch_panel;
}
$readme = $browse_query->renderReadme($browse_results); $readme = $browse_query->renderReadme($browse_results);
if ($readme) { if ($readme) {
@ -171,8 +149,64 @@ final class DiffusionRepositoryController extends DiffusionController {
return $panel; return $panel;
} }
private function buildBranchListTable(DiffusionRequest $drequest) {
if ($drequest->getBranch() !== null) {
$limit = 15;
$branch_query = DiffusionBranchQuery::newFromDiffusionRequest($drequest);
// we add 2 here, because of removed HEAD branch
$branch_query->setLimit($limit + 2);
$branches = $branch_query->loadBranches();
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('Branches');
if ($more_branches) {
$panel->setCaption('Showing the ' . $limit . ' most recent branches.');
}
$panel->addButton(
phutil_render_tag(
'a',
array(
'href' => $drequest->generateURI(
array(
'action' => 'branches',
)),
'class' => 'grey button',
),
"Show All Branches \xC2\xBB"));
$panel->appendChild($table);
return $panel;
}
return null;
}
private function buildTagListTable(DiffusionRequest $drequest) { private function buildTagListTable(DiffusionRequest $drequest) {
$tag_limit = 25; $tag_limit = 15;
$query = DiffusionTagListQuery::newFromDiffusionRequest($drequest); $query = DiffusionTagListQuery::newFromDiffusionRequest($drequest);
$query->setLimit($tag_limit + 1); $query->setLimit($tag_limit + 1);

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -19,6 +19,26 @@
abstract class DiffusionBranchQuery { abstract class DiffusionBranchQuery {
private $request; private $request;
private $limit;
private $offset;
public function setOffset($offset) {
$this->offset = $offset;
return $this;
}
public function getOffset() {
return $this->offset;
}
public function setLimit($limit) {
$this->limit = $limit;
return $this;
}
protected function getLimit() {
return $this->limit;
}
final private function __construct() { final private function __construct() {
// <private> // <private>

View file

@ -21,11 +21,13 @@ final class DiffusionGitBranchQuery extends DiffusionBranchQuery {
protected function executeQuery() { protected function executeQuery() {
$drequest = $this->getRequest(); $drequest = $this->getRequest();
$repository = $drequest->getRepository(); $repository = $drequest->getRepository();
$count = $this->getOffset() + $this->getLimit();
$local_path = $repository->getDetail('local-path');
list($stdout) = $repository->execxLocalCommand( list($stdout) = $repository->execxLocalCommand(
'branch -r --verbose --no-abbrev'); 'for-each-ref %C --sort=-creatordate --format=%s refs/remotes',
$count ? '--count='.(int)$count : null,
'%(refname:short) %(objectname)'
);
$branch_list = self::parseGitRemoteBranchOutput( $branch_list = self::parseGitRemoteBranchOutput(
$stdout, $stdout,
@ -43,6 +45,11 @@ final class DiffusionGitBranchQuery extends DiffusionBranchQuery {
$branches[] = $branch; $branches[] = $branch;
} }
$offset = $this->getOffset();
if ($offset) {
$branches = array_slice($branches, $offset);
}
return $branches; return $branches;
} }
@ -75,22 +82,27 @@ final class DiffusionGitBranchQuery extends DiffusionBranchQuery {
foreach ($lines as $line) { foreach ($lines as $line) {
$matches = null; $matches = null;
if (preg_match('/^ (\S+)\s+-> (\S+)$/', $line, $matches)) { if (preg_match('/^ (\S+)\s+-> (\S+)$/', $line, $matches)) {
// This is a line like: // This is a line like:
// //
// origin/HEAD -> origin/master // origin/HEAD -> origin/master
// //
// ...which we don't currently do anything interesting with, although // ...which we don't currently do anything interesting with, although
// in theory we could use it to automatically choose the default // in theory we could use it to automatically choose the default
// branch. // branch.
continue; continue;
} }
if (!preg_match('/^[ *] (\S+)\s+([a-z0-9]{40}) /', $line, $matches)) { if (!preg_match('/^ *(\S+)\s+([a-z0-9]{40})/', $line, $matches)) {
throw new Exception("Failed to parse {$line}!"); throw new Exception("Failed to parse {$line}!");
} }
$remote_branch = $matches[1]; $remote_branch = $matches[1];
$branch_head = $matches[2]; $branch_head = $matches[2];
if (strpos($remote_branch, 'HEAD') !== false) {
// let's assume that no one will call their remote or branch HEAD
continue;
}
if ($only_this_remote) { if ($only_this_remote) {
$matches = null; $matches = null;
if (!preg_match('#^([^/]+)/(.*)$#', $remote_branch, $matches)) { if (!preg_match('#^([^/]+)/(.*)$#', $remote_branch, $matches)) {

View file

@ -1,7 +1,7 @@
<?php <?php
/* /*
* Copyright 2011 Facebook, Inc. * Copyright 2012 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -27,23 +27,29 @@ final class DiffusionGitBranchQueryTestCase
origin/eventordering 185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3 RFC: Order... origin/eventordering 185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3 RFC: Order...
origin/master 713f1fc54f9cfc830acbf6bbdb46a2883f772896 Automat... origin/master 713f1fc54f9cfc830acbf6bbdb46a2883f772896 Automat...
alternate/stuff 4444444444444444444444444444444444444444 Hmm... alternate/stuff 4444444444444444444444444444444444444444 Hmm...
origin/HEAD 713f1fc54f9cfc830acbf6bbdb46a2883f772896
origin/weekend-refactoring 6e947ab0498b82075ca6195ac168385a11326c4b
alternate/release-1.0.0 9ddd5d67962dd89fa167f9989954468b6c517b87
EOTXT; EOTXT;
$this->assertEqual( $this->assertEqual(
array( array(
'origin/accent-folding' => 'bfaea2e72197506e028c604cd1a294b6e37aa17d', 'origin/accent-folding' => 'bfaea2e72197506e028c604cd1a294b6e37aa17d',
'origin/eventordering' => '185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3', 'origin/eventordering' => '185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3',
'origin/master' => '713f1fc54f9cfc830acbf6bbdb46a2883f772896', 'origin/master' => '713f1fc54f9cfc830acbf6bbdb46a2883f772896',
'alternate/stuff' => '4444444444444444444444444444444444444444', 'alternate/stuff' => '4444444444444444444444444444444444444444',
'origin/weekend-refactoring' => '6e947ab0498b82075ca6195ac168385a11326c4b',
'alternate/release-1.0.0' => '9ddd5d67962dd89fa167f9989954468b6c517b87',
), ),
DiffusionGitBranchQuery::parseGitRemoteBranchOutput($output)); DiffusionGitBranchQuery::parseGitRemoteBranchOutput($output));
$this->assertEqual( $this->assertEqual(
array( array(
'accent-folding' => 'bfaea2e72197506e028c604cd1a294b6e37aa17d', 'accent-folding' => 'bfaea2e72197506e028c604cd1a294b6e37aa17d',
'eventordering' => '185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3', 'eventordering' => '185a90a3c1b0556015e5f318fb86ccf8f7a6f3e3',
'master' => '713f1fc54f9cfc830acbf6bbdb46a2883f772896', 'master' => '713f1fc54f9cfc830acbf6bbdb46a2883f772896',
'weekend-refactoring' => '6e947ab0498b82075ca6195ac168385a11326c4b',
), ),
DiffusionGitBranchQuery::parseGitRemoteBranchOutput($output, 'origin')); DiffusionGitBranchQuery::parseGitRemoteBranchOutput($output, 'origin'));
} }

View file

@ -369,6 +369,7 @@ abstract class DiffusionRequest {
case 'change': case 'change':
case 'lastmodified': case 'lastmodified':
case 'tags': case 'tags':
case 'branches':
$req_callsign = true; $req_callsign = true;
break; break;
case 'branch': case 'branch':
@ -402,6 +403,7 @@ abstract class DiffusionRequest {
case 'browse': case 'browse':
case 'lastmodified': case 'lastmodified':
case 'tags': case 'tags':
case 'branches':
$uri = "/diffusion/{$callsign}{$action}/{$path}{$commit}{$line}"; $uri = "/diffusion/{$callsign}{$action}/{$path}{$commit}{$line}";
break; break;
case 'branch': case 'branch':

View file

@ -19,6 +19,8 @@
final class DiffusionBranchTableView extends DiffusionView { final class DiffusionBranchTableView extends DiffusionView {
private $branches; private $branches;
private $user;
private $commits = array();
public function setBranches(array $branches) { public function setBranches(array $branches) {
assert_instances_of($branches, 'DiffusionBranchInformation'); assert_instances_of($branches, 'DiffusionBranchInformation');