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

Add basic detail-parser functionality.

This commit is contained in:
epriestley 2011-04-01 17:11:05 -07:00
parent d23696a457
commit 82fffe466a
14 changed files with 336 additions and 12 deletions

View file

@ -0,0 +1 @@
ALTER TABLE phabricator_user.user ADD key (realName);

View file

@ -342,6 +342,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/base',
'PhabricatorRepositoryCommitData' => 'applications/repository/storage/commitdata',
'PhabricatorRepositoryCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/base',
'PhabricatorRepositoryCommitMessageDetailParser' => 'applications/repository/parser/base',
'PhabricatorRepositoryCommitMessageParserWorker' => 'applications/repository/worker/commitmessageparser/base',
'PhabricatorRepositoryCommitParserWorker' => 'applications/repository/worker/base',
'PhabricatorRepositoryCommitTaskDaemon' => 'applications/repository/daemon/committask',
@ -349,6 +350,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCreateController' => 'applications/repository/controller/create',
'PhabricatorRepositoryDAO' => 'applications/repository/storage/base',
'PhabricatorRepositoryDaemon' => 'applications/repository/daemon/base',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'applications/repository/parser/default',
'PhabricatorRepositoryEditController' => 'applications/repository/controller/edit',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'applications/repository/worker/commitchangeparser/git',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'applications/repository/daemon/commitdiscovery/git',
@ -690,6 +692,7 @@ phutil_register_library_map(array(
'PhabricatorRepositoryCreateController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryDAO' => 'PhabricatorLiskDAO',
'PhabricatorRepositoryDaemon' => 'PhabricatorDaemon',
'PhabricatorRepositoryDefaultCommitMessageDetailParser' => 'PhabricatorRepositoryCommitMessageDetailParser',
'PhabricatorRepositoryEditController' => 'PhabricatorRepositoryController',
'PhabricatorRepositoryGitCommitChangeParserWorker' => 'PhabricatorRepositoryCommitChangeParserWorker',
'PhabricatorRepositoryGitCommitDiscoveryDaemon' => 'PhabricatorRepositoryCommitDiscoveryDaemon',

View file

@ -46,6 +46,8 @@ class DiffusionCommitController extends DiffusionController {
require_celerity_resource('diffusion-commit-view-css');
require_celerity_resource('phabricator-remarkup-css');
$property_table = $this->renderPropertyTable($commit, $commit_data);
$detail_panel->appendChild(
'<div class="diffusion-commit-view">'.
'<div class="diffusion-commit-dateline">'.
@ -55,12 +57,7 @@ class DiffusionCommitController extends DiffusionController {
'</div>'.
'<h1>Revision Detail</h1>'.
'<div class="diffusion-commit-details">'.
'<table class="diffusion-commit-properties">'.
'<tr>'.
'<th>Author:</th>'.
'<td>'.phutil_escape_html($commit_data->getAuthorName()).'</td>'.
'</tr>'.
'</table>'.
$property_table.
'<hr />'.
'<div class="diffusion-commit-message phabricator-remarkup">'.
$engine->markupText($commit_data->getCommitMessage()).
@ -168,4 +165,62 @@ class DiffusionCommitController extends DiffusionController {
));
}
private function renderPropertyTable(
PhabricatorRepositoryCommit $commit,
PhabricatorRepositoryCommitData $data) {
$phids = array();
if ($data->getCommitDetail('authorPHID')) {
$phids[] = $data->getCommitDetail('authorPHID');
}
if ($data->getCommitDetail('reviewerPHID')) {
$phids[] = $data->getCommitDetail('reviewerPHID');
}
if ($data->getCommitDetail('differential.revisionPHID')) {
$phids[] = $data->getCommitDetail('differential.revisionPHID');
}
$handles = array();
if ($phids) {
$handles = id(new PhabricatorObjectHandleData($phids))
->loadHandles();
}
$props = array();
$author_phid = $data->getCommitDetail('authorPHID');
if ($data->getCommitDetail('authorPHID')) {
$props['Author'] = $handles[$author_phid]->renderLink();
} else {
$props['Author'] = phutil_escape_html($data->getAuthorName());
}
$reviewer_phid = $data->getCommitDetail('reviewerPHID');
$reviewer_name = $data->getCommitDetail('reviewerName');
if ($reviewer_phid) {
$props['Reviewer'] = $handles[$reviewer_phid]->renderLink();
} else if ($reviewer_name) {
$props['Reviewer'] = phutil_escape_html($reviewer_name);
}
$revision_phid = $data->getCommitDetail('differential.revisionPHID');
if ($revision_phid) {
$props['Differential Revision'] = $handles[$revision_phid]->renderLink();
}
$rows = array();
foreach ($props as $key => $value) {
$rows[] =
'<tr>'.
'<th>'.$key.':</th>'.
'<td>'.$value.'</td>'.
'</tr>';
}
return
'<table class="diffusion-commit-properties">'.
implode("\n", $rows).
'</table>';
}
}

View file

@ -105,6 +105,7 @@ class DiffusionHomeController extends DiffusionController {
'href' => '/diffusion/'.$repository->getCallsign().'/',
),
phutil_escape_html($repository->getName())),
phutil_escape_html($repository->getDetail('description')),
PhabricatorRepositoryType::getNameForRepositoryType(
$repository->getVersionControlSystem()),
$size ? number_format($size) : '-',
@ -122,6 +123,7 @@ class DiffusionHomeController extends DiffusionController {
$table->setHeaders(
array(
'Repository',
'Description',
'VCS',
'Size',
'Last',
@ -130,6 +132,7 @@ class DiffusionHomeController extends DiffusionController {
));
$table->setColumnClasses(
array(
'pri',
'wide',
'',
'n',

View file

@ -46,6 +46,10 @@ class DiffusionGitRequest extends DiffusionRequest {
$branch = $this->getBranch();
// TODO: Here, particularly, we should give the user a specific error
// message to indicate whether they've typed in some bogus branch and/or
// followed a bad link, or misconfigured the default branch in the
// Repository tool.
execx(
'(cd %s && git rev-parse --verify %s)',
$local_path,

View file

@ -115,6 +115,8 @@ class PhabricatorRepositoryEditController
$e_name = null;
}
$repository->setDetail('description', $request->getStr('description'));
if (!$errors) {
$repository->save();
return id(new AphrontRedirectResponse())
@ -146,6 +148,12 @@ class PhabricatorRepositoryEditController
->setValue($repository->getName())
->setError($e_name)
->setCaption('Human-readable repository name.'))
->appendChild(
id(new AphrontFormTextAreaControl())
->setLabel('Description')
->setName('description')
->setHeight(AphrontFormTextAreaControl::HEIGHT_VERY_SHORT)
->setValue($repository->getDetail('description')))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Callsign')
@ -156,10 +164,13 @@ class PhabricatorRepositoryEditController
->setLabel('Type')
->setName('type')
->setValue($repository->getVersionControlSystem()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('ID')
->setValue($repository->getID()))
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('PHID')
->setName('phid')
->setValue($repository->getPHID()))
->appendChild(
id(new AphrontFormSubmitControl())
@ -194,6 +205,20 @@ class PhabricatorRepositoryEditController
$e_uri = null;
$e_path = null;
$is_git = false;
$is_svn = false;
switch ($repository->getVersionControlSystem()) {
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$is_git = true;
break;
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$is_svn = true;
break;
default:
throw new Exception("Unsupported VCS!");
}
if ($request->isFormPost()) {
$tracking = ($request->getStr('tracking') == 'enabled' ? true : false);
$repository->setDetail('tracking-enabled', $tracking);
@ -203,6 +228,18 @@ class PhabricatorRepositoryEditController
'pull-frequency',
max(1, $request->getInt('frequency')));
if ($is_git) {
$repository->setDetail(
'default-branch',
$request->getStr('default-branch'));
}
$repository->setDetail(
'detail-parser',
$request->getStr(
'detail-parser',
'PhabricatorRepositoryDefaultCommitMessageDetailParser'));
if ($tracking) {
if (!$repository->getDetail('remote-uri')) {
$e_uri = 'Required';
@ -237,8 +274,11 @@ class PhabricatorRepositoryEditController
$uri_caption = null;
$path_caption = null;
switch ($repository->getVersionControlSystem()) {
case 'git':
case PhabricatorRepositoryType::REPOSITORY_TYPE_GIT:
$is_git = true;
$uri_caption =
'The user the tracking daemon runs as must have permission to '.
'<tt>git clone</tt> from this URI.';
@ -247,7 +287,8 @@ class PhabricatorRepositoryEditController
'repository (or create one if it does not yet exist). The daemon '.
'will regularly pull remote changes into this working copy.';
break;
case 'svn':
case PhabricatorRepositoryType::REPOSITORY_TYPE_SVN:
$is_svn = true;
$uri_caption =
'The user the tracking daemon runs as must have permission to '.
'<tt>svn log</tt> from this URI.';
@ -263,7 +304,7 @@ class PhabricatorRepositoryEditController
'repositories, importing commits as they happen and notifying '.
'Differential, Diffusion, Herald, and other services. To enable '.
'tracking for a repository, configure it here and then start (or '.
'restart) the PhabricatorRepositoryTrackingDaemon.</p>')
'restart) the daemons (TODO: explain this).</p>')
->appendChild(
id(new AphrontFormStaticControl())
->setLabel('Repository')
@ -301,7 +342,43 @@ class PhabricatorRepositoryEditController
->setValue($repository->getDetail('pull-frequency', 15))
->setCaption(
'Number of seconds daemon should sleep between requests. Larger '.
'numbers reduce load but also decrease responsiveness.'))
'numbers reduce load but also decrease responsiveness.'));
if ($is_git) {
$form
->appendChild(
id(new AphrontFormTextControl())
->setName('default-branch')
->setLabel('Default Branch')
->setValue(
$repository->getDetail(
'default-branch',
'origin/master'))
->setCaption(
'Default <strong>remote</strong> branch to show in Diffusion.'));
}
$parsers = id(new PhutilSymbolLoader())
->setAncestorClass('PhabricatorRepositoryCommitMessageDetailParser')
->selectSymbolsWithoutLoading();
$parsers = ipull($parsers, 'name', 'name');
$form
->appendChild(
'<p class="aphront-form-instructions">If you extend the commit '.
'message format, you can provide a new parser which will extract '.
'extra information from it when commits are imported. This is an '.
'advanced feature, and using the default parser will be suitable '.
'in most cases.</p>')
->appendChild(
id(new AphrontFormSelectControl())
->setName('detail-parser')
->setLabel('Detail Parser')
->setOptions($parsers)
->setValue(
$repository->getDetail(
'detail-parser',
'PhabricatorRepositoryDefaultCommitMessageDetailParser')))
->appendChild(
id(new AphrontFormSubmitControl())
->setValue('Save'));
@ -309,7 +386,7 @@ class PhabricatorRepositoryEditController
$panel = new AphrontPanelView();
$panel->setHeader('Repository Tracking');
$panel->appendChild($form);
$panel->setWidth(AphrontPanelView::WIDTH_FORM);
$panel->setWidth(AphrontPanelView::WIDTH_WIDE);
$nav = $this->sideNav;
$nav->appendChild($error_view);

View file

@ -9,6 +9,7 @@
phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/redirect');
phutil_require_module('phabricator', 'applications/differential/constants/revisioncontrolsystem');
phutil_require_module('phabricator', 'applications/repository/constants/repositorytype');
phutil_require_module('phabricator', 'applications/repository/controller/base');
phutil_require_module('phabricator', 'applications/repository/storage/githubnotification');
phutil_require_module('phabricator', 'applications/repository/storage/repository');
@ -16,6 +17,7 @@ phutil_require_module('phabricator', 'infrastructure/env');
phutil_require_module('phabricator', 'view/control/table');
phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/form/control/text');
phutil_require_module('phabricator', 'view/form/error');
phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phabricator', 'view/layout/sidenav');
@ -23,6 +25,7 @@ phutil_require_module('phabricator', 'view/utils');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');

View file

@ -0,0 +1,66 @@
<?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 PhabricatorRepositoryCommitMessageDetailParser {
private $commit;
private $commitData;
final public function __construct(
PhabricatorRepositoryCommit $commit,
PhabricatorRepositoryCommitData $data) {
$this->commit = $commit;
$this->commitData = $data;
}
final public function getCommit() {
return $this->commit;
}
final public function getCommitData() {
return $this->commitData;
}
public function resolveUserPHID($user_name) {
if (!strlen($user_name)) {
return null;
}
$by_username = id(new PhabricatorUser())->loadOneWhere(
'userName = %s',
$user_name);
if ($by_username) {
return $by_username->getPHID();
}
// Note, real names are not guaranteed unique, which is why we do it this
// way.
$by_realname = id(new PhabricatorUser())->loadAllWhere(
'realName = %s LIMIT 1',
$user_name);
if ($by_realname) {
$by_realname = reset($by_realname);
return $by_realname->getPHID();
}
return null;
}
abstract public function parseCommitDetails();
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/people/storage/user');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorRepositoryCommitMessageDetailParser.php');

View file

@ -0,0 +1,67 @@
<?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 PhabricatorRepositoryDefaultCommitMessageDetailParser
extends PhabricatorRepositoryCommitMessageDetailParser {
public function parseCommitDetails() {
$commit = $this->getCommit();
$data = $this->getCommitData();
$details = nonempty($data->getCommitDetails(), array());
$message = $data->getCommitMessage();
$author_name = $data->getAuthorName();
$match = null;
if (preg_match(
'/^\s*Differential Revision:\s*(\S+)\s*$/mi',
$message,
$match)) {
$id = (int)$match[1];
if ($id) {
$details['differential.revisionID'] = (int)$match[1];
$revision = id(new DifferentialRevision())->load($id);
if ($revision) {
$details['differential.revisionPHID'] = $revision->getPHID();
}
}
}
if (preg_match(
'/^\s*Reviewed By:\s*(\S+)\s*$/mi',
$message,
$match)) {
$details['reviewerName'] = $match[1];
$reviewer_phid = $this->resolveUserPHID($details['reviewerName']);
if ($reviewer_phid) {
$details['reviewerPHID'] = $reviewer_phid;
}
}
$author_phid = $this->resolveUserPHID($author_name);
if ($author_phid) {
$details['authorPHID'] = $author_phid;
}
$data->setCommitDetails($details);
}
}

View file

@ -0,0 +1,14 @@
<?php
/**
* This file is automatically generated. Lint this module to rebuild it.
* @generated
*/
phutil_require_module('phabricator', 'applications/repository/parser/base');
phutil_require_module('phutil', 'utils');
phutil_require_source('PhabricatorRepositoryDefaultCommitMessageDetailParser.php');

View file

@ -36,4 +36,8 @@ class PhabricatorRepositoryCommitData extends PhabricatorRepositoryDAO {
return substr($this->getCommitMessage(), 0, 80);
}
public function getCommitDetail($key, $default = null) {
return idx($this->commitDetails, $key, $default);
}
}

View file

@ -31,6 +31,18 @@ abstract class PhabricatorRepositoryCommitMessageParserWorker
$data->setCommitID($commit->getID());
$data->setAuthorName($author);
$data->setCommitMessage($message);
$repository = $this->repository;
$detail_parser = $repository->getDetail(
'detail-parser',
'PhabricatorRepositoryDefaultCommitMessageDetailParser');
if ($detail_parser) {
PhutilSymbolLoader::loadClass($detail_parser);
$parser_obj = newv($detail_parser, array($commit, $data));
$parser_obj->parseCommitDetails();
}
$data->save();
}

View file

@ -9,6 +9,7 @@
phutil_require_module('phabricator', 'applications/repository/storage/commitdata');
phutil_require_module('phabricator', 'applications/repository/worker/base');
phutil_require_module('phutil', 'symbols');
phutil_require_module('phutil', 'utils');