2011-01-25 00:52:35 +01:00
|
|
|
<?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 DifferentialChangesetViewController extends DifferentialController {
|
|
|
|
|
|
|
|
|
|
|
|
public function processRequest() {
|
2011-02-01 05:38:13 +01:00
|
|
|
$request = $this->getRequest();
|
|
|
|
|
2011-02-02 01:42:36 +01:00
|
|
|
$author_phid = $request->getUser()->getPHID();
|
2011-02-01 05:38:13 +01:00
|
|
|
|
2011-02-04 00:41:58 +01:00
|
|
|
$id = $request->getStr('id');
|
|
|
|
$vs = $request->getInt('vs');
|
|
|
|
|
|
|
|
|
2011-02-01 05:38:13 +01:00
|
|
|
$changeset = id(new DifferentialChangeset())->load($id);
|
2011-01-25 00:52:35 +01:00
|
|
|
if (!$changeset) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
2011-05-06 21:58:53 +02:00
|
|
|
$view = $request->getStr('view');
|
|
|
|
if ($view) {
|
|
|
|
$changeset->attachHunks($changeset->loadHunks());
|
|
|
|
switch ($view) {
|
|
|
|
case 'new':
|
|
|
|
return $this->buildRawFileResponse($changeset->makeNewFile());
|
|
|
|
case 'old':
|
|
|
|
return $this->buildRawFileResponse($changeset->makeOldFile());
|
|
|
|
default:
|
|
|
|
return new Aphront400Response();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-04 00:41:58 +01:00
|
|
|
if ($vs && ($vs != -1)) {
|
|
|
|
$vs_changeset = id(new DifferentialChangeset())->load($vs);
|
|
|
|
if (!$vs_changeset) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!$vs) {
|
|
|
|
$right = $changeset;
|
|
|
|
$left = null;
|
|
|
|
|
|
|
|
$right_source = $right->getID();
|
|
|
|
$right_new = true;
|
|
|
|
$left_source = $right->getID();
|
|
|
|
$left_new = false;
|
2011-05-05 16:08:10 +02:00
|
|
|
|
|
|
|
$render_cache_key = $right->getID();
|
2011-02-04 00:41:58 +01:00
|
|
|
} else if ($vs == -1) {
|
|
|
|
$right = null;
|
|
|
|
$left = $changeset;
|
|
|
|
|
|
|
|
$right_source = $left->getID();
|
|
|
|
$right_new = false;
|
|
|
|
$left_source = $left->getID();
|
|
|
|
$left_new = true;
|
2011-05-05 16:08:10 +02:00
|
|
|
|
|
|
|
$render_cache_key = null;
|
2011-02-04 00:41:58 +01:00
|
|
|
} else {
|
|
|
|
$right = $changeset;
|
|
|
|
$left = $vs_changeset;
|
|
|
|
|
|
|
|
$right_source = $right->getID();
|
|
|
|
$right_new = true;
|
|
|
|
$left_source = $left->getID();
|
|
|
|
$left_new = true;
|
2011-05-05 16:08:10 +02:00
|
|
|
|
|
|
|
$render_cache_key = null;
|
2011-02-04 00:41:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if ($left) {
|
|
|
|
$left->attachHunks($left->loadHunks());
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($right) {
|
|
|
|
$right->attachHunks($right->loadHunks());
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($left) {
|
|
|
|
|
|
|
|
$left_data = $left->makeNewFile();
|
|
|
|
if ($right) {
|
|
|
|
$right_data = $right->makeNewFile();
|
|
|
|
} else {
|
|
|
|
$right_data = $left->makeOldFile();
|
|
|
|
}
|
|
|
|
|
|
|
|
$left_tmp = new TempFile();
|
|
|
|
$right_tmp = new TempFile();
|
|
|
|
Filesystem::writeFile($left_tmp, $left_data);
|
|
|
|
Filesystem::writeFile($right_tmp, $right_data);
|
|
|
|
list($err, $stdout) = exec_manual(
|
|
|
|
'/usr/bin/diff -U65535 %s %s',
|
|
|
|
$left_tmp,
|
|
|
|
$right_tmp);
|
|
|
|
|
|
|
|
$choice = nonempty($left, $right);
|
|
|
|
if ($stdout) {
|
|
|
|
$parser = new ArcanistDiffParser();
|
|
|
|
$changes = $parser->parseDiff($stdout);
|
|
|
|
$diff = DifferentialDiff::newFromRawChanges($changes);
|
|
|
|
$changesets = $diff->getChangesets();
|
|
|
|
$first = reset($changesets);
|
|
|
|
$choice->attachHunks($first->getHunks());
|
|
|
|
} else {
|
|
|
|
$choice->attachHunks(array());
|
|
|
|
}
|
|
|
|
|
|
|
|
$changeset = $choice;
|
|
|
|
$changeset->setID(null);
|
|
|
|
}
|
2011-01-25 00:52:35 +01:00
|
|
|
|
2011-02-01 05:38:13 +01:00
|
|
|
$range_s = null;
|
|
|
|
$range_e = null;
|
|
|
|
$mask = array();
|
|
|
|
|
|
|
|
$range = $request->getStr('range');
|
|
|
|
if ($range) {
|
|
|
|
$match = null;
|
|
|
|
if (preg_match('@^(\d+)-(\d+)(?:/(\d+)-(\d+))?$@', $range, $match)) {
|
|
|
|
$range_s = (int)$match[1];
|
|
|
|
$range_e = (int)$match[2];
|
|
|
|
if (count($match) > 3) {
|
|
|
|
$start = (int)$match[3];
|
|
|
|
$len = (int)$match[4];
|
|
|
|
for ($ii = $start; $ii < $start + $len; $ii++) {
|
|
|
|
$mask[$ii] = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-01-25 00:52:35 +01:00
|
|
|
$parser = new DifferentialChangesetParser();
|
|
|
|
$parser->setChangeset($changeset);
|
2011-05-05 16:08:10 +02:00
|
|
|
$parser->setRenderCacheKey($render_cache_key);
|
2011-02-04 00:41:58 +01:00
|
|
|
$parser->setRightSideCommentMapping($right_source, $right_new);
|
|
|
|
$parser->setLeftSideCommentMapping($left_source, $left_new);
|
2011-04-18 22:38:54 +02:00
|
|
|
$parser->setWhitespaceMode($request->getStr('whitespace'));
|
2011-02-02 22:48:52 +01:00
|
|
|
|
2011-05-09 06:22:25 +02:00
|
|
|
// Load both left-side and right-side inline comments.
|
|
|
|
$inlines = $this->loadInlineComments(
|
|
|
|
array($left_source, $right_source),
|
|
|
|
$author_phid);
|
|
|
|
|
2011-02-02 01:42:36 +01:00
|
|
|
$phids = array();
|
|
|
|
foreach ($inlines as $inline) {
|
|
|
|
$parser->parseInlineComment($inline);
|
|
|
|
$phids[$inline->getAuthorPHID()] = true;
|
|
|
|
}
|
|
|
|
$phids = array_keys($phids);
|
2011-02-02 22:48:52 +01:00
|
|
|
|
2011-02-02 01:42:36 +01:00
|
|
|
$handles = id(new PhabricatorObjectHandleData($phids))
|
|
|
|
->loadHandles();
|
|
|
|
$parser->setHandles($handles);
|
2011-02-02 22:48:52 +01:00
|
|
|
|
2011-02-02 01:42:36 +01:00
|
|
|
$factory = new DifferentialMarkupEngineFactory();
|
|
|
|
$engine = $factory->newDifferentialCommentMarkupEngine();
|
|
|
|
$parser->setMarkupEngine($engine);
|
2011-01-25 00:52:35 +01:00
|
|
|
|
2011-02-02 19:10:25 +01:00
|
|
|
if ($request->isAjax()) {
|
|
|
|
// TODO: This is sort of lazy, the effect is just to not render "Edit"
|
|
|
|
// links on the "standalone view".
|
|
|
|
$parser->setUser($request->getUser());
|
|
|
|
}
|
|
|
|
|
|
|
|
$output = $parser->render($range_s, $range_e, $mask);
|
2011-01-25 00:52:35 +01:00
|
|
|
|
2011-01-25 20:57:47 +01:00
|
|
|
if ($request->isAjax()) {
|
|
|
|
return id(new AphrontAjaxResponse())
|
|
|
|
->setContent($output);
|
|
|
|
}
|
|
|
|
|
2011-02-01 05:38:13 +01:00
|
|
|
Javelin::initBehavior('differential-show-more', array(
|
|
|
|
'uri' => '/differential/changeset/',
|
2011-05-11 02:36:06 +02:00
|
|
|
'whitespace' => $request->getStr('whitespace'),
|
2011-02-01 05:38:13 +01:00
|
|
|
));
|
|
|
|
|
2011-05-11 21:25:29 +02:00
|
|
|
Javelin::initBehavior('differential-comment-jump', array());
|
|
|
|
|
2011-01-25 20:57:47 +01:00
|
|
|
$detail = new DifferentialChangesetDetailView();
|
|
|
|
$detail->setChangeset($changeset);
|
|
|
|
$detail->appendChild($output);
|
2011-05-06 21:58:53 +02:00
|
|
|
|
|
|
|
if (!$vs) {
|
|
|
|
$detail->addButton(
|
|
|
|
phutil_render_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $request->getRequestURI()->alter('view', 'old'),
|
|
|
|
'class' => 'grey button small',
|
|
|
|
),
|
|
|
|
'View Raw File (Old Version)'));
|
|
|
|
$detail->addButton(
|
|
|
|
phutil_render_tag(
|
|
|
|
'a',
|
|
|
|
array(
|
|
|
|
'href' => $request->getRequestURI()->alter('view', 'new'),
|
|
|
|
'class' => 'grey button small',
|
|
|
|
),
|
|
|
|
'View Raw File (New Version)'));
|
|
|
|
}
|
|
|
|
|
2011-04-15 23:25:23 +02:00
|
|
|
$detail->setRevisionID($request->getInt('revision_id'));
|
2011-01-25 20:57:47 +01:00
|
|
|
|
2011-01-25 00:52:35 +01:00
|
|
|
$output =
|
2011-01-26 00:19:06 +01:00
|
|
|
'<div class="differential-primary-pane">'.
|
2011-05-11 21:25:29 +02:00
|
|
|
'<div class="differential-review-stage" '.
|
|
|
|
'id="differential-review-stage">'.
|
2011-01-26 00:19:06 +01:00
|
|
|
$detail->render().
|
2011-01-25 00:52:35 +01:00
|
|
|
'</div>'.
|
|
|
|
'</div>';
|
|
|
|
|
|
|
|
return $this->buildStandardPageResponse(
|
|
|
|
array(
|
|
|
|
$output
|
|
|
|
),
|
|
|
|
array(
|
|
|
|
'title' => 'Changeset View',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
2011-05-09 06:22:25 +02:00
|
|
|
private function loadInlineComments(array $changeset_ids, $author_phid) {
|
|
|
|
$changeset_ids = array_unique(array_filter($changeset_ids));
|
|
|
|
if (!$changeset_ids) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-02-02 01:42:36 +01:00
|
|
|
return id(new DifferentialInlineComment())->loadAllWhere(
|
2011-05-09 06:22:25 +02:00
|
|
|
'changesetID IN (%Ld) AND (commentID IS NOT NULL OR authorPHID = %s)',
|
|
|
|
$changeset_ids,
|
2011-02-02 01:42:36 +01:00
|
|
|
$author_phid);
|
|
|
|
}
|
|
|
|
|
2011-05-06 21:58:53 +02:00
|
|
|
private function buildRawFileResponse($text) {
|
|
|
|
return id(new AphrontFileResponse())
|
|
|
|
->setMimeType('text/plain')
|
|
|
|
->setContent($text);
|
|
|
|
}
|
2011-02-02 01:42:36 +01:00
|
|
|
|
2011-01-25 00:52:35 +01:00
|
|
|
}
|