2011-01-24 15:52:35 -08: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-01-31 20:38:13 -08:00
|
|
|
$request = $this->getRequest();
|
|
|
|
|
2011-02-01 16:42:36 -08:00
|
|
|
$author_phid = $request->getUser()->getPHID();
|
2011-01-31 20:38:13 -08:00
|
|
|
|
2011-02-03 15:41:58 -08:00
|
|
|
$id = $request->getStr('id');
|
|
|
|
$vs = $request->getInt('vs');
|
|
|
|
|
|
|
|
|
2011-01-31 20:38:13 -08:00
|
|
|
$changeset = id(new DifferentialChangeset())->load($id);
|
2011-01-24 15:52:35 -08:00
|
|
|
if (!$changeset) {
|
|
|
|
return new Aphront404Response();
|
|
|
|
}
|
|
|
|
|
2011-05-06 12:58:53 -07: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-03 15:41:58 -08: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 07:08:10 -07:00
|
|
|
|
|
|
|
$render_cache_key = $right->getID();
|
2011-02-03 15:41:58 -08: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 07:08:10 -07:00
|
|
|
|
|
|
|
$render_cache_key = null;
|
2011-02-03 15:41:58 -08:00
|
|
|
} else {
|
|
|
|
$right = $changeset;
|
|
|
|
$left = $vs_changeset;
|
|
|
|
|
|
|
|
$right_source = $right->getID();
|
|
|
|
$right_new = true;
|
|
|
|
$left_source = $left->getID();
|
|
|
|
$left_new = true;
|
2011-05-05 07:08:10 -07:00
|
|
|
|
|
|
|
$render_cache_key = null;
|
2011-02-03 15:41:58 -08: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-24 15:52:35 -08:00
|
|
|
|
2011-01-31 20:38:13 -08: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-24 15:52:35 -08:00
|
|
|
$parser = new DifferentialChangesetParser();
|
|
|
|
$parser->setChangeset($changeset);
|
2011-05-05 07:08:10 -07:00
|
|
|
$parser->setRenderCacheKey($render_cache_key);
|
2011-02-03 15:41:58 -08:00
|
|
|
$parser->setRightSideCommentMapping($right_source, $right_new);
|
|
|
|
$parser->setLeftSideCommentMapping($left_source, $left_new);
|
2011-04-18 13:38:54 -07:00
|
|
|
$parser->setWhitespaceMode($request->getStr('whitespace'));
|
2011-02-02 13:48:52 -08:00
|
|
|
|
Make DifferentialChangesetParser explicitly map display to storage for comments
Summary:
This is a followup to D228. Basically, we use "changeset" (and, implicitly,
changesetID) for way too much stuff now.
One thing it can't possibly capture is the complete, arbitrary mapping between
the left and right sides of the displayed diff and the places we want to store
the left and right side comments. This causes a bunch of bugs; basically adding
inline comments is completely broken in diff-of-diff views prior to this patch.
Make this mapping explicit.
Note that the renderer already passes this mapping to
DifferentialChangesetParser which is why there are no changes outside this file,
I just didn't finish the implementation during the port.
This has the nice side-effect of fixing T132 and several other bugs.
Test Plan:
Made new-file and old-file comments on a normal diff; reloaded page, verified
comments didn't do anything crazy.
Expanded text on a normal diff, made new-file and old-file comments; reloaded
page, verified comments.
Repeated these steps for a previous diff in the same revision; verified
comments.
Loaded diff-of-diffs and verified expected comments appeared. Made new left and
right hand side comments, which almost work, see below.
NOTE: There is still a bug where comments made in the left-display-side of a
diff-of-diffs will incorrectly be written to the right-storage-side of the
right-display-side diff. However, this is an issue with the JS (the PHP is
correct) so I want to pull it out of scope for this patch since I think I need
to fix some other JS stuff too and this improves the overall state of the world
even if not everything is fixed.
Reviewed By: tuomaspelkonen
Reviewers: jungejason, tuomaspelkonen, aran, ola
CC: aran, tuomaspelkonen, epriestley
Differential Revision: 237
2011-05-06 07:18:09 -07:00
|
|
|
// Load both left-side and right-side inline comments.
|
|
|
|
$inlines = $this->loadInlineComments(
|
|
|
|
array($left_source, $right_source),
|
|
|
|
$author_phid);
|
|
|
|
|
2011-02-01 16:42:36 -08:00
|
|
|
$phids = array();
|
|
|
|
foreach ($inlines as $inline) {
|
|
|
|
$parser->parseInlineComment($inline);
|
|
|
|
$phids[$inline->getAuthorPHID()] = true;
|
|
|
|
}
|
|
|
|
$phids = array_keys($phids);
|
2011-02-02 13:48:52 -08:00
|
|
|
|
2011-02-01 16:42:36 -08:00
|
|
|
$handles = id(new PhabricatorObjectHandleData($phids))
|
|
|
|
->loadHandles();
|
|
|
|
$parser->setHandles($handles);
|
2011-02-02 13:48:52 -08:00
|
|
|
|
2011-02-01 16:42:36 -08:00
|
|
|
$factory = new DifferentialMarkupEngineFactory();
|
|
|
|
$engine = $factory->newDifferentialCommentMarkupEngine();
|
|
|
|
$parser->setMarkupEngine($engine);
|
2011-01-24 15:52:35 -08:00
|
|
|
|
2011-02-02 10:10:25 -08: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-24 15:52:35 -08:00
|
|
|
|
2011-01-25 11:57:47 -08:00
|
|
|
if ($request->isAjax()) {
|
|
|
|
return id(new AphrontAjaxResponse())
|
|
|
|
->setContent($output);
|
|
|
|
}
|
|
|
|
|
2011-01-31 20:38:13 -08:00
|
|
|
Javelin::initBehavior('differential-show-more', array(
|
|
|
|
'uri' => '/differential/changeset/',
|
|
|
|
));
|
|
|
|
|
2011-01-25 11:57:47 -08:00
|
|
|
$detail = new DifferentialChangesetDetailView();
|
|
|
|
$detail->setChangeset($changeset);
|
|
|
|
$detail->appendChild($output);
|
2011-05-06 12:58:53 -07: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 14:25:23 -07:00
|
|
|
$detail->setRevisionID($request->getInt('revision_id'));
|
2011-01-25 11:57:47 -08:00
|
|
|
|
2011-01-24 15:52:35 -08:00
|
|
|
$output =
|
2011-01-25 15:19:06 -08:00
|
|
|
'<div class="differential-primary-pane">'.
|
|
|
|
'<div class="differential-review-stage">'.
|
|
|
|
$detail->render().
|
2011-01-24 15:52:35 -08:00
|
|
|
'</div>'.
|
|
|
|
'</div>';
|
|
|
|
|
|
|
|
return $this->buildStandardPageResponse(
|
|
|
|
array(
|
|
|
|
$output
|
|
|
|
),
|
|
|
|
array(
|
|
|
|
'title' => 'Changeset View',
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
Make DifferentialChangesetParser explicitly map display to storage for comments
Summary:
This is a followup to D228. Basically, we use "changeset" (and, implicitly,
changesetID) for way too much stuff now.
One thing it can't possibly capture is the complete, arbitrary mapping between
the left and right sides of the displayed diff and the places we want to store
the left and right side comments. This causes a bunch of bugs; basically adding
inline comments is completely broken in diff-of-diff views prior to this patch.
Make this mapping explicit.
Note that the renderer already passes this mapping to
DifferentialChangesetParser which is why there are no changes outside this file,
I just didn't finish the implementation during the port.
This has the nice side-effect of fixing T132 and several other bugs.
Test Plan:
Made new-file and old-file comments on a normal diff; reloaded page, verified
comments didn't do anything crazy.
Expanded text on a normal diff, made new-file and old-file comments; reloaded
page, verified comments.
Repeated these steps for a previous diff in the same revision; verified
comments.
Loaded diff-of-diffs and verified expected comments appeared. Made new left and
right hand side comments, which almost work, see below.
NOTE: There is still a bug where comments made in the left-display-side of a
diff-of-diffs will incorrectly be written to the right-storage-side of the
right-display-side diff. However, this is an issue with the JS (the PHP is
correct) so I want to pull it out of scope for this patch since I think I need
to fix some other JS stuff too and this improves the overall state of the world
even if not everything is fixed.
Reviewed By: tuomaspelkonen
Reviewers: jungejason, tuomaspelkonen, aran, ola
CC: aran, tuomaspelkonen, epriestley
Differential Revision: 237
2011-05-06 07:18:09 -07:00
|
|
|
private function loadInlineComments(array $changeset_ids, $author_phid) {
|
|
|
|
$changeset_ids = array_unique(array_filter($changeset_ids));
|
|
|
|
if (!$changeset_ids) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-02-01 16:42:36 -08:00
|
|
|
return id(new DifferentialInlineComment())->loadAllWhere(
|
Make DifferentialChangesetParser explicitly map display to storage for comments
Summary:
This is a followup to D228. Basically, we use "changeset" (and, implicitly,
changesetID) for way too much stuff now.
One thing it can't possibly capture is the complete, arbitrary mapping between
the left and right sides of the displayed diff and the places we want to store
the left and right side comments. This causes a bunch of bugs; basically adding
inline comments is completely broken in diff-of-diff views prior to this patch.
Make this mapping explicit.
Note that the renderer already passes this mapping to
DifferentialChangesetParser which is why there are no changes outside this file,
I just didn't finish the implementation during the port.
This has the nice side-effect of fixing T132 and several other bugs.
Test Plan:
Made new-file and old-file comments on a normal diff; reloaded page, verified
comments didn't do anything crazy.
Expanded text on a normal diff, made new-file and old-file comments; reloaded
page, verified comments.
Repeated these steps for a previous diff in the same revision; verified
comments.
Loaded diff-of-diffs and verified expected comments appeared. Made new left and
right hand side comments, which almost work, see below.
NOTE: There is still a bug where comments made in the left-display-side of a
diff-of-diffs will incorrectly be written to the right-storage-side of the
right-display-side diff. However, this is an issue with the JS (the PHP is
correct) so I want to pull it out of scope for this patch since I think I need
to fix some other JS stuff too and this improves the overall state of the world
even if not everything is fixed.
Reviewed By: tuomaspelkonen
Reviewers: jungejason, tuomaspelkonen, aran, ola
CC: aran, tuomaspelkonen, epriestley
Differential Revision: 237
2011-05-06 07:18:09 -07:00
|
|
|
'changesetID IN (%Ld) AND (commentID IS NOT NULL OR authorPHID = %s)',
|
|
|
|
$changeset_ids,
|
2011-02-01 16:42:36 -08:00
|
|
|
$author_phid);
|
|
|
|
}
|
|
|
|
|
2011-05-06 12:58:53 -07:00
|
|
|
private function buildRawFileResponse($text) {
|
|
|
|
return id(new AphrontFileResponse())
|
|
|
|
->setMimeType('text/plain')
|
|
|
|
->setContent($text);
|
|
|
|
}
|
2011-02-01 16:42:36 -08:00
|
|
|
|
2011-01-24 15:52:35 -08:00
|
|
|
}
|