mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-09 16:32:39 +01:00
Diffusion: basic browse view
Summary: Synthesizes elements of Diffusion's browse view, Confusion's git support and Phabricator's repository infrastructure to provide a basic browse view for Phabricator Diffusion. This is basically a straight port of Confusion but uses Phabricator's Repository object and uses a real data object instead of arrays. Test Plan: Browsed Javelin in Phabricator at a very basic level. Reviewed By: jwilson Reviewers: aran, jwilson CC: jwilson, epriestley Differential Revision: 58
This commit is contained in:
parent
7c413fc580
commit
0d8bac97ae
15 changed files with 458 additions and 0 deletions
|
@ -286,4 +286,10 @@ return array(
|
|||
|
||||
'controller.oauth-registration' =>
|
||||
'PhabricatorOAuthDefaultRegistrationController',
|
||||
|
||||
|
||||
// Path to the 'git' binary to execute when running git commands. By default
|
||||
// this should work fine, but if you have a weird environment you may need
|
||||
// to set it explicitly (e.g., apache may not have it in its PATH).
|
||||
'git.path' => 'git',
|
||||
);
|
||||
|
|
|
@ -142,8 +142,13 @@ phutil_register_library_map(array(
|
|||
'DifferentialRevisionViewController' => 'applications/differential/controller/revisionview',
|
||||
'DifferentialSubscribeController' => 'applications/differential/controller/subscribe',
|
||||
'DifferentialUnitStatus' => 'applications/differential/constants/unitstatus',
|
||||
'DiffusionBrowseController' => 'applications/diffusion/controller/browse',
|
||||
'DiffusionBrowseQuery' => 'applications/diffusion/query/browse/base',
|
||||
'DiffusionBrowseTableView' => 'applications/diffusion/view/browsetable',
|
||||
'DiffusionController' => 'applications/diffusion/controller/base',
|
||||
'DiffusionGitBrowseQuery' => 'applications/diffusion/query/browse/git',
|
||||
'DiffusionHomeController' => 'applications/diffusion/controller/home',
|
||||
'DiffusionRepositoryPath' => 'applications/diffusion/data/repositorypath',
|
||||
'Javelin' => 'infrastructure/javelin/api',
|
||||
'LiskDAO' => 'storage/lisk/dao',
|
||||
'ManiphestController' => 'applications/maniphest/controller/base',
|
||||
|
@ -422,7 +427,10 @@ phutil_register_library_map(array(
|
|||
'DifferentialRevisionUpdateHistoryView' => 'AphrontView',
|
||||
'DifferentialRevisionViewController' => 'DifferentialController',
|
||||
'DifferentialSubscribeController' => 'DifferentialController',
|
||||
'DiffusionBrowseController' => 'DiffusionController',
|
||||
'DiffusionBrowseTableView' => 'AphrontView',
|
||||
'DiffusionController' => 'PhabricatorController',
|
||||
'DiffusionGitBrowseQuery' => 'DiffusionBrowseQuery',
|
||||
'DiffusionHomeController' => 'DiffusionController',
|
||||
'ManiphestController' => 'PhabricatorController',
|
||||
'ManiphestDAO' => 'PhabricatorLiskDAO',
|
||||
|
|
|
@ -185,6 +185,11 @@ class AphrontDefaultApplicationConfiguration
|
|||
|
||||
'/diffusion/' => array(
|
||||
'$' => 'DiffusionHomeController',
|
||||
'(?P<callsign>[A-Z]+)/browse/'.
|
||||
'(?P<path>.*?)'.
|
||||
'(?:[;](?P<commit>[a-z0-9]+))?'.
|
||||
'(?:[$](?P<line>\d+))?$'
|
||||
=> 'DiffusionBrowseController',
|
||||
),
|
||||
|
||||
);
|
||||
|
|
|
@ -32,4 +32,14 @@ abstract class DiffusionController extends PhabricatorController {
|
|||
return $response->setContent($page->render());
|
||||
}
|
||||
|
||||
protected function loadRepositoryByCallsign($callsign) {
|
||||
$repository = id(new PhabricatorRepository())->loadOneWhere(
|
||||
'callsign = %s',
|
||||
$callsign);
|
||||
if (!$repository) {
|
||||
throw new Exception("No such repository '{$callsign}'.");
|
||||
}
|
||||
return $repository;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
phutil_require_module('phabricator', 'aphront/response/webpage');
|
||||
phutil_require_module('phabricator', 'applications/base/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/repository/storage/repository');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
<?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 DiffusionBrowseController extends DiffusionController {
|
||||
|
||||
private $callsign;
|
||||
private $path;
|
||||
private $line;
|
||||
private $commit;
|
||||
|
||||
private $repository;
|
||||
|
||||
public function willProcessRequest(array $data) {
|
||||
$this->callsign = $data['callsign'];
|
||||
$this->path = rtrim($data['path'], '/');
|
||||
|
||||
$this->line = idx($data, 'line');
|
||||
$this->commit = idx($data, 'commit');
|
||||
}
|
||||
|
||||
public function processRequest() {
|
||||
$repository = $this->loadRepositoryByCallsign($this->callsign);
|
||||
|
||||
$browse_data = DiffusionBrowseQuery::newFromRepository(
|
||||
$repository,
|
||||
$this->path,
|
||||
$this->commit);
|
||||
$results = $browse_data->loadPaths();
|
||||
|
||||
if (!$results) {
|
||||
// TODO: useful output (path does not exist / never existed), or file
|
||||
// data.
|
||||
throw new Exception("No browse results.");
|
||||
} else {
|
||||
$browse_table = new DiffusionBrowseTableView();
|
||||
$browse_table->setRepository($repository);
|
||||
$browse_table->setPaths($results);
|
||||
$browse_table->setRoot($this->path);
|
||||
$browse_table->setCommit($this->commit);
|
||||
|
||||
$browse_panel = new AphrontPanelView();
|
||||
$browse_panel->setHeader($this->path);
|
||||
$browse_panel->appendChild($browse_table);
|
||||
|
||||
// TODO: Branch table
|
||||
}
|
||||
|
||||
// TODO: Crumbs
|
||||
// TODO: Side nav
|
||||
|
||||
return $this->buildStandardPageResponse(
|
||||
$browse_panel,
|
||||
array(
|
||||
'title' => basename($this->path),
|
||||
));
|
||||
}
|
||||
|
||||
}
|
17
src/applications/diffusion/controller/browse/__init__.php
Normal file
17
src/applications/diffusion/controller/browse/__init__.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/diffusion/controller/base');
|
||||
phutil_require_module('phabricator', 'applications/diffusion/query/browse/base');
|
||||
phutil_require_module('phabricator', 'applications/diffusion/view/browsetable');
|
||||
phutil_require_module('phabricator', 'view/layout/panel');
|
||||
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('DiffusionBrowseController.php');
|
|
@ -0,0 +1,62 @@
|
|||
<?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 DiffusionRepositoryPath {
|
||||
|
||||
private $path;
|
||||
private $hash;
|
||||
private $fileType;
|
||||
private $fileSize;
|
||||
|
||||
final public function setPath($path) {
|
||||
$this->path = $path;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getPath() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
final public function setHash($hash) {
|
||||
$this->hash = $hash;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getHash() {
|
||||
return $this->hash;
|
||||
}
|
||||
|
||||
final public function setFileType($file_type) {
|
||||
$this->fileType = $file_type;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getFileType() {
|
||||
return $this->fileType;
|
||||
}
|
||||
|
||||
final public function setFileSize($file_size) {
|
||||
$this->fileSize = $file_size;
|
||||
return $this;
|
||||
}
|
||||
|
||||
final public function getFileSize() {
|
||||
return $this->fileSize;
|
||||
}
|
||||
|
||||
}
|
10
src/applications/diffusion/data/repositorypath/__init__.php
Normal file
10
src/applications/diffusion/data/repositorypath/__init__.php
Normal file
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
phutil_require_source('DiffusionRepositoryPath.php');
|
|
@ -0,0 +1,79 @@
|
|||
<?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.
|
||||
*/
|
||||
|
||||
abstract class DiffusionBrowseQuery {
|
||||
|
||||
private $repository;
|
||||
private $path;
|
||||
private $commit;
|
||||
|
||||
protected $reason;
|
||||
|
||||
const REASON_IS_FILE = 'is-file';
|
||||
const REASON_IS_NONEXISTENT = 'nonexistent';
|
||||
|
||||
final private function __construct() {
|
||||
// <private>
|
||||
}
|
||||
|
||||
final public static function newFromRepository(
|
||||
PhabricatorRepository $repository,
|
||||
$path = '/',
|
||||
$commit = null) {
|
||||
|
||||
switch ($repository->getVersionControlSystem()) {
|
||||
case 'git':
|
||||
// TODO: Verify local-path?
|
||||
$class = 'DiffusionGitBrowseQuery';
|
||||
break;
|
||||
default:
|
||||
throw new Exception("Unsupported VCS!");
|
||||
}
|
||||
|
||||
PhutilSymbolLoader::loadClass($class);
|
||||
$query = new $class();
|
||||
|
||||
$query->repository = $repository;
|
||||
$query->path = $path;
|
||||
$query->commit = $commit;
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
final protected function getRepository() {
|
||||
return $this->repository;
|
||||
}
|
||||
|
||||
final protected function getPath() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
final protected function getCommit() {
|
||||
return $this->commit;
|
||||
}
|
||||
|
||||
final public function getReasonForEmptyResultSet() {
|
||||
return $this->reason;
|
||||
}
|
||||
|
||||
final public function loadPaths() {
|
||||
return $this->executeQuery();
|
||||
}
|
||||
|
||||
abstract protected function executeQuery();
|
||||
}
|
12
src/applications/diffusion/query/browse/base/__init__.php
Normal file
12
src/applications/diffusion/query/browse/base/__init__.php
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phutil', 'symbols');
|
||||
|
||||
|
||||
phutil_require_source('DiffusionBrowseQuery.php');
|
|
@ -0,0 +1,79 @@
|
|||
<?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 DiffusionGitBrowseQuery extends DiffusionBrowseQuery {
|
||||
|
||||
protected function executeQuery() {
|
||||
$repository = $this->getRepository();
|
||||
$path = $this->getPath();
|
||||
$commit = nonempty($this->getCommit(), 'HEAD');
|
||||
|
||||
$local_path = $repository->getDetail('local-path');
|
||||
|
||||
$git = PhabricatorEnv::getEnvConfig('git.path');
|
||||
|
||||
try {
|
||||
list($stdout) = execx(
|
||||
"(cd %s && %s cat-file -t %s:%s)",
|
||||
$local_path,
|
||||
$git,
|
||||
$commit,
|
||||
$path);
|
||||
} catch (CommandException $e) {
|
||||
if (preg_match('/^fatal: Not a valid object name/', $e->getStderr())) {
|
||||
$this->reason = self::REASON_IS_NONEXISTENT;
|
||||
return array();
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if (trim($stdout) == 'blob') {
|
||||
$this->reason = self::REASON_IS_FILE;
|
||||
return array();
|
||||
}
|
||||
|
||||
list($stdout) = execx(
|
||||
"(cd %s && %s ls-tree -l %s:%s)",
|
||||
$local_path,
|
||||
$git,
|
||||
$commit,
|
||||
$path);
|
||||
|
||||
$results = array();
|
||||
foreach (explode("\n", rtrim($stdout)) as $line) {
|
||||
list($mode, $type, $hash, $size, $name) = preg_split('/\s+/', $line);
|
||||
if ($type == 'tree') {
|
||||
$file_type = DifferentialChangeType::FILE_DIRECTORY;
|
||||
} else {
|
||||
$file_type = DifferentialChangeType::FILE_NORMAL;
|
||||
}
|
||||
|
||||
$result = new DiffusionRepositoryPath();
|
||||
$result->setPath($name);
|
||||
$result->setHash($hash);
|
||||
$result->setFileType($file_type);
|
||||
$result->setFileSize($size);
|
||||
|
||||
$results[] = $result;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
}
|
18
src/applications/diffusion/query/browse/git/__init__.php
Normal file
18
src/applications/diffusion/query/browse/git/__init__.php
Normal file
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'applications/differential/constants/changetype');
|
||||
phutil_require_module('phabricator', 'applications/diffusion/data/repositorypath');
|
||||
phutil_require_module('phabricator', 'applications/diffusion/query/browse/base');
|
||||
phutil_require_module('phabricator', 'infrastructure/env');
|
||||
|
||||
phutil_require_module('phutil', 'future/exec');
|
||||
phutil_require_module('phutil', 'utils');
|
||||
|
||||
|
||||
phutil_require_source('DiffusionGitBrowseQuery.php');
|
|
@ -0,0 +1,63 @@
|
|||
<?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 DiffusionBrowseTableView extends AphrontView {
|
||||
|
||||
private $repository;
|
||||
private $paths;
|
||||
private $root;
|
||||
private $commit;
|
||||
|
||||
public function setRepository($repository) {
|
||||
$this->repository = $repository;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setPaths(array $paths) {
|
||||
$this->paths = $paths;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setRoot($root) {
|
||||
$this->root = $root;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function setCommit($commit) {
|
||||
$this->commit = $commit;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function render() {
|
||||
$rows = array();
|
||||
foreach ($this->paths as $path) {
|
||||
$rows[] = array(
|
||||
phutil_escape_html($path->getPath()), // TODO: link
|
||||
// TODO: etc etc
|
||||
);
|
||||
}
|
||||
|
||||
$view = new AphrontTableView($rows);
|
||||
$view->setHeaders(
|
||||
array(
|
||||
'Path',
|
||||
));
|
||||
return $view->render();
|
||||
}
|
||||
|
||||
}
|
15
src/applications/diffusion/view/browsetable/__init__.php
Normal file
15
src/applications/diffusion/view/browsetable/__init__.php
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?php
|
||||
/**
|
||||
* This file is automatically generated. Lint this module to rebuild it.
|
||||
* @generated
|
||||
*/
|
||||
|
||||
|
||||
|
||||
phutil_require_module('phabricator', 'view/base');
|
||||
phutil_require_module('phabricator', 'view/control/table');
|
||||
|
||||
phutil_require_module('phutil', 'markup');
|
||||
|
||||
|
||||
phutil_require_source('DiffusionBrowseTableView.php');
|
Loading…
Reference in a new issue