1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-26 00:32:42 +01:00

Browse / git improvements.

This commit is contained in:
epriestley 2011-03-13 22:03:30 -07:00
parent 7963d7fa06
commit b5db12b6b2
21 changed files with 339 additions and 16 deletions

View file

@ -150,6 +150,7 @@ phutil_register_library_map(array(
'DiffusionBrowseFileController' => 'applications/diffusion/controller/file', 'DiffusionBrowseFileController' => 'applications/diffusion/controller/file',
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base', 'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable', 'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
'DiffusionChangeController' => 'applications/diffusion/controller/change',
'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable', 'DiffusionCommitChangeTableView' => 'applications/diffusion/view/commitchangetable',
'DiffusionCommitController' => 'applications/diffusion/controller/commit', 'DiffusionCommitController' => 'applications/diffusion/controller/commit',
'DiffusionController' => 'applications/diffusion/controller/base', 'DiffusionController' => 'applications/diffusion/controller/base',
@ -170,6 +171,7 @@ phutil_register_library_map(array(
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath', 'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
'DiffusionRequest' => 'applications/diffusion/request/base', 'DiffusionRequest' => 'applications/diffusion/request/base',
'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn', 'DiffusionSvnBrowseQuery' => 'applications/diffusion/query/browse/svn',
'DiffusionSvnFileContentQuery' => 'applications/diffusion/query/filecontent/svn',
'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn', 'DiffusionSvnHistoryQuery' => 'applications/diffusion/query/history/svn',
'DiffusionView' => 'applications/diffusion/view/base', 'DiffusionView' => 'applications/diffusion/view/base',
'Javelin' => 'infrastructure/javelin/api', 'Javelin' => 'infrastructure/javelin/api',
@ -474,6 +476,7 @@ phutil_register_library_map(array(
'DiffusionBrowseController' => 'DiffusionController', 'DiffusionBrowseController' => 'DiffusionController',
'DiffusionBrowseFileController' => 'DiffusionController', 'DiffusionBrowseFileController' => 'DiffusionController',
'DiffusionBrowseTableView' => 'DiffusionView', 'DiffusionBrowseTableView' => 'DiffusionView',
'DiffusionChangeController' => 'DiffusionController',
'DiffusionCommitChangeTableView' => 'DiffusionView', 'DiffusionCommitChangeTableView' => 'DiffusionView',
'DiffusionCommitController' => 'DiffusionController', 'DiffusionCommitController' => 'DiffusionController',
'DiffusionController' => 'PhabricatorController', 'DiffusionController' => 'PhabricatorController',
@ -487,6 +490,7 @@ phutil_register_library_map(array(
'DiffusionHomeController' => 'DiffusionController', 'DiffusionHomeController' => 'DiffusionController',
'DiffusionRepositoryController' => 'DiffusionController', 'DiffusionRepositoryController' => 'DiffusionController',
'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery', 'DiffusionSvnBrowseQuery' => 'DiffusionBrowseQuery',
'DiffusionSvnFileContentQuery' => 'DiffusionFileContentQuery',
'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery', 'DiffusionSvnHistoryQuery' => 'DiffusionHistoryQuery',
'DiffusionView' => 'AphrontView', 'DiffusionView' => 'AphrontView',
'ManiphestController' => 'PhabricatorController', 'ManiphestController' => 'PhabricatorController',

View file

@ -189,6 +189,11 @@ class AphrontDefaultApplicationConfiguration
'$' => 'DiffusionHomeController', '$' => 'DiffusionHomeController',
'(?P<callsign>[A-Z]+)/' => array( '(?P<callsign>[A-Z]+)/' => array(
'$' => 'DiffusionRepositoryController', '$' => 'DiffusionRepositoryController',
'change/'.
'(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'.
'$'
=> 'DiffusionChangeController',
'history/'. 'history/'.
'(?P<path>.*?)'. '(?P<path>.*?)'.
'(?:[;](?P<commit>[a-z0-9]+))?'. '(?:[;](?P<commit>[a-z0-9]+))?'.

View file

@ -151,6 +151,10 @@ abstract class DiffusionController extends PhabricatorController {
case 'browse': case 'browse':
$view_name = 'Browse'; $view_name = 'Browse';
break; break;
case 'change':
$crumb_list[] = 'TODO CHANGE';
$crumbs->setCrumbs($crumb_list);
return $crumbs;
} }
$path = null; $path = null;

View file

@ -49,6 +49,16 @@ class DiffusionBrowseController extends DiffusionController {
$deleted = $browse_query->getDeletedAtCommit(); $deleted = $browse_query->getDeletedAtCommit();
$existed = $browse_query->getExistedAtCommit(); $existed = $browse_query->getExistedAtCommit();
$callsign = $drequest->getRepository()->getCallsign();
if ($commit) {
$commit = "r{$callsign}{$commit}";
} else {
$commit = 'HEAD';
}
$deleted = "r{$callsign}{$deleted}";
$existed = "r{$callsign}{$existed}";
$title = 'Path Was Deleted'; $title = 'Path Was Deleted';
$body = "This path does not exist at {$commit}. It was deleted in ". $body = "This path does not exist at {$commit}. It was deleted in ".
"{$deleted} and last existed at {$existed}."; "{$deleted} and last existed at {$existed}.";

View file

@ -0,0 +1,96 @@
<?php
/*
* Copyright 2011 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.
*/
class DiffusionChangeController extends DiffusionController {
public function processRequest() {
$drequest = $this->diffusionRequest;
// $browse_query = DiffusionBrowseQuery::newFromDiffusionRequest($drequest);
// $results = $browse_query->loadPaths();
$content = array();
$content[] = $this->buildCrumbs(
array(
'branch' => true,
'path' => true,
'view' => 'change',
));
/*
if (!$results) {
switch ($browse_query->getReasonForEmptyResultSet()) {
case DiffusionBrowseQuery::REASON_IS_NONEXISTENT:
$title = 'Path Does Not Exist';
// TODO: Under git, this error message should be more specific. It
// may exist on some other branch.
$body = "This path does not exist anywhere.";
$severity = AphrontErrorView::SEVERITY_ERROR;
break;
case DiffusionBrowseQuery::REASON_IS_DELETED:
// TODO: Format all these commits into nice VCS-agnostic links.
$commit = $drequest->getCommit();
$deleted = $browse_query->getDeletedAtCommit();
$existed = $browse_query->getExistedAtCommit();
$title = 'Path Was Deleted';
$body = "This path does not exist at {$commit}. It was deleted in ".
"{$deleted} and last existed at {$existed}.";
$severity = AphrontErrorView::SEVERITY_WARNING;
break;
case DiffusionBrowseQuery::REASON_IS_FILE:
$controller = new DiffusionBrowseFileController($this->getRequest());
$controller->setDiffusionRequest($drequest);
return $this->delegateToController($controller);
break;
default:
throw new Exception("Unknown failure reason!");
}
$error_view = new AphrontErrorView();
$error_view->setSeverity($severity);
$error_view->setTitle($title);
$error_view->appendChild('<p>'.$body.'</p>');
$content[] = $error_view;
} else {
$browse_table = new DiffusionBrowseTableView();
$browse_table->setDiffusionRequest($drequest);
$browse_table->setPaths($results);
$browse_panel = new AphrontPanelView();
$browse_panel->appendChild($browse_table);
$content[] = $browse_panel;
}
*/
$nav = $this->buildSideNav('change', true);
$nav->appendChild($content);
return $this->buildStandardPageResponse(
$nav,
array(
'title' => 'Change',
));
}
}

View file

@ -0,0 +1,12 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
phutil_require_source('DiffusionChangeController.php');

View file

@ -35,7 +35,12 @@ final class DiffusionSvnBrowseQuery extends DiffusionBrowseQuery {
PhabricatorRepository::TABLE_PATH, PhabricatorRepository::TABLE_PATH,
array($path_normal)); array($path_normal));
$paths = ipull($paths, 'id', 'path'); $paths = ipull($paths, 'id', 'path');
$path_id = $paths[$path_normal]; $path_id = idx($paths, $path_normal);
if (empty($path_id)) {
$this->reason = self::REASON_IS_NONEXISTENT;
return array();
}
if ($commit) { if ($commit) {
$slice_clause = 'AND svnCommit <= '.(int)$commit; $slice_clause = 'AND svnCommit <= '.(int)$commit;
@ -54,8 +59,38 @@ final class DiffusionSvnBrowseQuery extends DiffusionBrowseQuery {
$slice_clause); $slice_clause);
if (!$index) { if (!$index) {
// TODO: ! if ($this->path == '/') {
return false; $this->reason = self::REASON_IS_EMPTY;
} else {
$reasons = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE repositoryID = %d AND pathID = %d
%Q ORDER BY svnCommit DESC LIMIT 2',
PhabricatorRepository::TABLE_FILESYSTEM,
$repository->getID(),
$path_id,
$slice_clause);
$reason = reset($reasons);
if (!$reason) {
$this->reason = self::REASON_IS_NONEXISTENT;
} else {
$file_type = $reason['fileType'];
if (empty($reason['existed'])) {
$this->reason = self::REASON_IS_DELETED;
$this->deletedAtCommit = $reason['svnCommit'];
if (!empty($reasons[1])) {
$this->existedAtCommit = $reasons[1]['svnCommit'];
}
} else if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
$this->reason = self::REASON_IS_EMPTY;
} else {
$this->reason = self::REASON_IS_FILE;
}
}
}
return array();
} }
$sql = array(); $sql = array();

View file

@ -6,6 +6,7 @@
phutil_require_module('phabricator', 'applications/differential/constants/changetype');
phutil_require_module('phabricator', 'applications/diffusion/data/repositorypath'); phutil_require_module('phabricator', 'applications/diffusion/data/repositorypath');
phutil_require_module('phabricator', 'applications/diffusion/query/browse/base'); phutil_require_module('phabricator', 'applications/diffusion/query/browse/base');
phutil_require_module('phabricator', 'applications/repository/storage/repository'); phutil_require_module('phabricator', 'applications/repository/storage/repository');

View file

@ -30,9 +30,12 @@ abstract class DiffusionFileContentQuery {
$repository = $request->getRepository(); $repository = $request->getRepository();
switch ($repository->getVersionControlSystem()) { switch ($repository->getVersionControlSystem()) {
case 'git': case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$class = 'DiffusionGitFileContentQuery'; $class = 'DiffusionGitFileContentQuery';
break; break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$class = 'DiffusionSvnFileContentQuery';
break;
default: default:
throw new Exception("Unsupported VCS!"); throw new Exception("Unsupported VCS!");
} }

View file

@ -6,6 +6,8 @@
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phutil', 'symbols'); phutil_require_module('phutil', 'symbols');

View file

@ -0,0 +1,42 @@
<?php
/*
* Copyright 2011 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 DiffusionSvnFileContentQuery extends DiffusionFileContentQuery {
protected function executeQuery() {
$drequest = $this->getRequest();
$repository = $drequest->getRepository();
$path = $drequest->getPath();
$commit = $drequest->getCommit();
$remote_uri = $repository->getDetail('remote-uri');
list($corpus) = execx(
'svn --non-interactive cat %s%s@%s',
$remote_uri,
$path,
$commit);
$file_content = new DiffusionFileContent();
$file_content->setCorpus($corpus);
return $file_content;
}
}

View file

@ -0,0 +1,15 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/diffusion/data/filecontent');
phutil_require_module('phabricator', 'applications/diffusion/query/filecontent/base');
phutil_require_module('phutil', 'future/exec');
phutil_require_source('DiffusionSvnFileContentQuery.php');

View file

@ -26,18 +26,15 @@ final class DiffusionGitHistoryQuery extends DiffusionHistoryQuery {
$commit_hash = $drequest->getCommit(); $commit_hash = $drequest->getCommit();
$local_path = $repository->getDetail('local-path'); $local_path = $repository->getDetail('local-path');
$git = $drequest->getPathToGitBinary();
list($stdout) = execx( list($stdout) = execx(
'(cd %s && %s log '. '(cd %s && git log '.
'--skip=%d '. '--skip=%d '.
'-n %d '. '-n %d '.
'-t '.
'--abbrev=40 '. '--abbrev=40 '.
'--pretty=format:%%H '. '--pretty=format:%%H '.
'%s -- %s)', '%s -- %s)',
$local_path, $local_path,
$git,
$this->getOffset(), $this->getOffset(),
$this->getLimit(), $this->getLimit(),
$commit_hash, $commit_hash,
@ -48,6 +45,9 @@ final class DiffusionGitHistoryQuery extends DiffusionHistoryQuery {
$commits = array(); $commits = array();
$commit_data = array(); $commit_data = array();
$path_changes = array();
$conn_r = $repository->establishConnection('r');
if ($hashes) { if ($hashes) {
$commits = id(new PhabricatorRepositoryCommit())->loadAllWhere( $commits = id(new PhabricatorRepositoryCommit())->loadAllWhere(
@ -61,7 +61,27 @@ final class DiffusionGitHistoryQuery extends DiffusionHistoryQuery {
mpull($commits, 'getID')); mpull($commits, 'getID'));
$commit_data = mpull($commit_data, null, 'getCommitID'); $commit_data = mpull($commit_data, null, 'getCommitID');
} }
if ($commits) {
$path_normal = '/'.trim($path, '/');
$paths = queryfx_all(
$conn_r,
'SELECT id, path FROM %T WHERE path IN (%Ls)',
PhabricatorRepository::TABLE_PATH,
array($path_normal));
$paths = ipull($paths, 'id', 'path');
$path_id = idx($paths, $path_normal);
$path_changes = queryfx_all(
$conn_r,
'SELECT * FROM %T WHERE commitID IN (%Ld) AND pathID = %d',
PhabricatorRepository::TABLE_PATHCHANGE,
mpull($commits, 'getID'),
$path_id);
$path_changes = ipull($path_changes, null, 'commitID');
} }
}
$history = array(); $history = array();
foreach ($hashes as $hash) { foreach ($hashes as $hash) {
@ -74,6 +94,11 @@ final class DiffusionGitHistoryQuery extends DiffusionHistoryQuery {
if ($data) { if ($data) {
$item->setCommitData($data); $item->setCommitData($data);
} }
$change = idx($path_changes, $commit->getID());
if ($change) {
$item->setChangeType($change['changeType']);
$item->setFileType($change['fileType']);
}
} }
$history[] = $item; $history[] = $item;
} }

View file

@ -35,6 +35,8 @@ final class DiffusionSvnHistoryQuery extends DiffusionHistoryQuery {
$paths = ipull($paths, 'id', 'path'); $paths = ipull($paths, 'id', 'path');
$path_id = $paths['/'.trim($path, '/')]; $path_id = $paths['/'.trim($path, '/')];
// TODO: isDirect junk
$history_data = queryfx_all( $history_data = queryfx_all(
$conn_r, $conn_r,
'SELECT * FROM %T WHERE repositoryID = %d AND pathID = %d 'SELECT * FROM %T WHERE repositoryID = %d AND pathID = %d
@ -63,8 +65,6 @@ final class DiffusionSvnHistoryQuery extends DiffusionHistoryQuery {
} }
} }
$history = array(); $history = array();
foreach ($history_data as $row) { foreach ($history_data as $row) {
$item = new DiffusionPathChange(); $item = new DiffusionPathChange();
@ -77,6 +77,11 @@ final class DiffusionSvnHistoryQuery extends DiffusionHistoryQuery {
$item->setCommitData($data); $item->setCommitData($data);
} }
} }
$item->setChangeType($row['changeType']);
$item->setFileType($row['fileType']);
$history[] = $item; $history[] = $item;
} }

View file

@ -29,6 +29,39 @@ abstract class DiffusionView extends AphrontView {
return $this->diffusionRequest; return $this->diffusionRequest;
} }
final public function linkChange($change_type, $file_type) {
$text = DifferentialChangeType::getFullNameForChangeType($change_type);
if ($change_type == DifferentialChangeType::TYPE_CHILD) {
// TODO: Don't link COPY_AWAY without a direct change.
return $text;
}
if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
return $text;
}
$drequest = $this->getDiffusionRequest();
if ($drequest->getRawCommit()) {
$commit = ';'.$drequest->getCommitURIComponent($drequest->getRawCommit());
} else {
$commit = null;
}
$repository = $drequest->getRepository();
$callsign = $repository->getCallsign();
$branch = $drequest->getBranchURIComponent($drequest->getBranch());
$path = $branch.$drequest->getPath();
return phutil_render_tag(
'a',
array(
'href' => "/diffusion/{$callsign}/change/{$path}{$commit}",
),
$text);
}
final public function linkHistory($path) { final public function linkHistory($path) {
$drequest = $this->getDiffusionRequest(); $drequest = $this->getDiffusionRequest();

View file

@ -28,10 +28,17 @@ final class DiffusionCommitChangeTableView extends DiffusionView {
public function render() { public function render() {
$rows = array(); $rows = array();
foreach ($this->pathChanges as $change) { foreach ($this->pathChanges as $change) {
$change_verb = DifferentialChangeType::getFullNameForChangeType(
$change->getChangeType());
$rows[] = array( $rows[] = array(
$this->linkHistory($change->getPath()), $this->linkHistory($change->getPath()),
$this->linkBrowse($change->getPath()), $this->linkBrowse($change->getPath()),
'-', $this->linkChange(
$change->getPath(),
array(
'text' => $change_verb,
)),
phutil_escape_html($change->getPath()), phutil_escape_html($change->getPath()),
); );
} }

View file

@ -6,6 +6,7 @@
phutil_require_module('phabricator', 'applications/differential/constants/changetype');
phutil_require_module('phabricator', 'applications/diffusion/view/base'); phutil_require_module('phabricator', 'applications/diffusion/view/base');
phutil_require_module('phabricator', 'view/control/table'); phutil_require_module('phabricator', 'view/control/table');

View file

@ -49,7 +49,9 @@ final class DiffusionHistoryTableView extends DiffusionView {
self::linkCommit( self::linkCommit(
$drequest->getRepository(), $drequest->getRepository(),
$history->getCommitIdentifier()), $history->getCommitIdentifier()),
'-', $this->linkChange(
$history->getChangeType(),
$history->getFileType()),
$date, $date,
$time, $time,
phutil_escape_html($history->getAuthorName()), phutil_escape_html($history->getAuthorName()),

View file

@ -73,6 +73,7 @@ class PhabricatorRepositoryGitCommitChangeParserWorker
$change_type = null; $change_type = null;
$change_path = $src_path; $change_path = $src_path;
$change_target = null; $change_target = null;
$is_direct = true;
switch ($action[0]) { switch ($action[0]) {
case 'A': case 'A':
@ -94,7 +95,12 @@ class PhabricatorRepositoryGitCommitChangeParserWorker
$move_away[$change_target][] = $change_path; $move_away[$change_target][] = $change_path;
break; break;
case 'M': case 'M':
if ($file_type == DifferentialChangeType::FILE_DIRECTORY) {
$change_type = DifferentialChangeType::TYPE_CHILD;
$is_direct = false;
} else {
$change_type = DifferentialChangeType::TYPE_CHANGE; $change_type = DifferentialChangeType::TYPE_CHANGE;
}
break; break;
default: default:
throw new Exception("Failed to parse line '{$line}'."); throw new Exception("Failed to parse line '{$line}'.");
@ -107,7 +113,7 @@ class PhabricatorRepositoryGitCommitChangeParserWorker
'path' => $change_path, 'path' => $change_path,
'changeType' => $change_type, 'changeType' => $change_type,
'fileType' => $file_type, 'fileType' => $file_type,
'isDirect' => true, 'isDirect' => $is_direct,
'commitSequence' => $commit->getEpoch(), 'commitSequence' => $commit->getEpoch(),
'targetPath' => $change_target, 'targetPath' => $change_target,
@ -115,6 +121,21 @@ class PhabricatorRepositoryGitCommitChangeParserWorker
); );
} }
// Add a change to '/' since git doesn't mention it.
$changes['/'] = array(
'repositoryID' => $repository->getID(),
'commitID' => $commit->getID(),
'path' => '/',
'changeType' => DifferentialChangeType::TYPE_CHILD,
'fileType' => DifferentialChangeType::FILE_DIRECTORY,
'isDirect' => false,
'commitSequence' => $commit->getEpoch(),
'targetPath' => null,
'targetCommitID' => null,
);
foreach ($copy_away as $change_path => $destinations) { foreach ($copy_away as $change_path => $destinations) {
if (isset($move_away[$change_path])) { if (isset($move_away[$change_path])) {
$change_type = DifferentialChangeType::TYPE_MULTICOPY; $change_type = DifferentialChangeType::TYPE_MULTICOPY;

View file

@ -13,6 +13,7 @@ td.aphront-side-nav-content {
th.aphront-side-nav-navigation { th.aphront-side-nav-navigation {
border-right: 1px solid #bbbbbb; border-right: 1px solid #bbbbbb;
padding-bottom: 8em;
} }
th.aphront-side-nav-navigation a, th.aphront-side-nav-navigation a,

View file

@ -24,8 +24,7 @@
color: #444444; color: #444444;
text-align: right; text-align: right;
white-space: nowrap; white-space: nowrap;
padding: 2px 4px; padding: 2px 4px 2px 24px;
width: 100px;
} }
.diffusion-commit-properties td { .diffusion-commit-properties td {