1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-03 11:21:01 +01:00

Rough cut of diff-of-diffs.

This commit is contained in:
epriestley 2011-02-03 15:41:58 -08:00
parent 5fd28d35d9
commit 12df78ed6a
14 changed files with 238 additions and 136 deletions

View file

@ -22,15 +22,91 @@ class DifferentialChangesetViewController extends DifferentialController {
public function processRequest() { public function processRequest() {
$request = $this->getRequest(); $request = $this->getRequest();
$id = $request->getStr('id');
$author_phid = $request->getUser()->getPHID(); $author_phid = $request->getUser()->getPHID();
$id = $request->getStr('id');
$vs = $request->getInt('vs');
$changeset = id(new DifferentialChangeset())->load($id); $changeset = id(new DifferentialChangeset())->load($id);
if (!$changeset) { if (!$changeset) {
return new Aphront404Response(); return new Aphront404Response();
} }
$changeset->attachHunks($changeset->loadHunks()); 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;
} else if ($vs == -1) {
$right = null;
$left = $changeset;
$right_source = $left->getID();
$right_new = false;
$left_source = $left->getID();
$left_new = true;
} else {
$right = $changeset;
$left = $vs_changeset;
$right_source = $right->getID();
$right_new = true;
$left_source = $left->getID();
$left_new = true;
}
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);
}
$range_s = null; $range_s = null;
$range_e = null; $range_e = null;
@ -54,6 +130,8 @@ class DifferentialChangesetViewController extends DifferentialController {
$parser = new DifferentialChangesetParser(); $parser = new DifferentialChangesetParser();
$parser->setChangeset($changeset); $parser->setChangeset($changeset);
$parser->setRightSideCommentMapping($right_source, $right_new);
$parser->setLeftSideCommentMapping($left_source, $left_new);
$phids = array(); $phids = array();
$inlines = $this->loadInlineComments($id, $author_phid); $inlines = $this->loadInlineComments($id, $author_phid);

View file

@ -6,17 +6,23 @@
phutil_require_module('arcanist', 'parser/diff');
phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'aphront/response/ajax'); phutil_require_module('phabricator', 'aphront/response/ajax');
phutil_require_module('phabricator', 'applications/differential/controller/base'); phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/parser/changeset'); phutil_require_module('phabricator', 'applications/differential/parser/changeset');
phutil_require_module('phabricator', 'applications/differential/parser/markup'); phutil_require_module('phabricator', 'applications/differential/parser/markup');
phutil_require_module('phabricator', 'applications/differential/storage/changeset'); phutil_require_module('phabricator', 'applications/differential/storage/changeset');
phutil_require_module('phabricator', 'applications/differential/storage/diff');
phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment'); phutil_require_module('phabricator', 'applications/differential/storage/inlinecomment');
phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview'); phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview');
phutil_require_module('phabricator', 'applications/phid/handle/data'); phutil_require_module('phabricator', 'applications/phid/handle/data');
phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phutil', 'filesystem');
phutil_require_module('phutil', 'filesystem/tempfile');
phutil_require_module('phutil', 'future/exec');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -40,6 +40,35 @@ class DifferentialDiffViewController extends DifferentialController {
'When you are satisfied, either <strong>create a new revision</strong> '. 'When you are satisfied, either <strong>create a new revision</strong> '.
'or <strong>update an existing revision</strong>.'); 'or <strong>update an existing revision</strong>.');
// TODO: implmenent optgroup support in AphrontFormSelectControl?
$select = array();
$select[] = '<optgroup label="Create New Revision">';
$select[] = '<option value="">Create a new Revision...</option>';
$select[] = '</optgroup>';
$revision_data = new DifferentialRevisionListData(
DifferentialRevisionListData::QUERY_OPEN_OWNED,
array($request->getUser()->getPHID()));
$revisions = $revision_data->loadRevisions();
if ($revisions) {
$select[] = '<optgroup label="Update Existing Revision">';
foreach ($revisions as $revision) {
$select[] = phutil_render_tag(
'option',
array(
'value' => $revision->getID(),
),
phutil_escape_html($revision->getTitle()));
}
$select[] = '</optgroup>';
}
$select =
'<select name="revisionID">'.
implode("\n", $select).
'</select>';
$action_form = new AphrontFormView(); $action_form = new AphrontFormView();
$action_form $action_form
->setUser($request->getUser()) ->setUser($request->getUser())
@ -47,13 +76,9 @@ class DifferentialDiffViewController extends DifferentialController {
->addHiddenInput('diffID', $diff->getID()) ->addHiddenInput('diffID', $diff->getID())
->addHiddenInput('viaDiffView', 1) ->addHiddenInput('viaDiffView', 1)
->appendChild( ->appendChild(
id(new AphrontFormSelectControl()) id(new AphrontFormMarkupControl())
->setLabel('Attach To') ->setLabel('Attach To')
->setName('revisionID') ->setValue($select))
->setValue('')
->setOptions(array(
'' => "Create a new Revision...",
)))
->appendChild( ->appendChild(
id(new AphrontFormSubmitControl()) id(new AphrontFormSubmitControl())
->setValue('Continue')); ->setValue('Continue'));

View file

@ -8,6 +8,7 @@
phutil_require_module('phabricator', 'aphront/response/404'); phutil_require_module('phabricator', 'aphront/response/404');
phutil_require_module('phabricator', 'applications/differential/controller/base'); phutil_require_module('phabricator', 'applications/differential/controller/base');
phutil_require_module('phabricator', 'applications/differential/data/revisionlist');
phutil_require_module('phabricator', 'applications/differential/storage/diff'); phutil_require_module('phabricator', 'applications/differential/storage/diff');
phutil_require_module('phabricator', 'applications/differential/view/changesetlistview'); phutil_require_module('phabricator', 'applications/differential/view/changesetlistview');
phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents'); phutil_require_module('phabricator', 'applications/differential/view/difftableofcontents');
@ -15,6 +16,7 @@ phutil_require_module('phabricator', 'view/form/base');
phutil_require_module('phabricator', 'view/form/control/submit'); phutil_require_module('phabricator', 'view/form/control/submit');
phutil_require_module('phabricator', 'view/layout/panel'); phutil_require_module('phabricator', 'view/layout/panel');
phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -26,6 +26,12 @@ class DifferentialRevisionEditController extends DifferentialController {
public function processRequest() { public function processRequest() {
$request = $this->getRequest();
if (!$this->id) {
$this->id = $request->getInt('revisionID');
}
if ($this->id) { if ($this->id) {
$revision = id(new DifferentialRevision())->load($this->id); $revision = id(new DifferentialRevision())->load($this->id);
if (!$revision) { if (!$revision) {
@ -35,7 +41,6 @@ class DifferentialRevisionEditController extends DifferentialController {
$revision = new DifferentialRevision(); $revision = new DifferentialRevision();
} }
$request = $this->getRequest();
$diff_id = $request->getInt('diffID'); $diff_id = $request->getInt('diffID');
if ($diff_id) { if ($diff_id) {
$diff = id(new DifferentialDiff())->load($diff_id); $diff = id(new DifferentialDiff())->load($diff_id);

View file

@ -37,10 +37,16 @@ class DifferentialRevisionViewController extends DifferentialController {
$diffs = $revision->loadDiffs(); $diffs = $revision->loadDiffs();
$diff_vs = null; $diff_vs = $request->getInt('vs');
$target = end($diffs); $target = end($diffs);
$changesets = $target->loadChangesets(); $diffs = mpull($diffs, null, 'getID');
if (empty($diffs[$diff_vs])) {
$diff_vs = null;
}
list($changesets, $vs_map) =
$this->loadChangesetsAndVsMap($diffs, $diff_vs, $target);
$comments = $revision->loadComments(); $comments = $revision->loadComments();
$comments = array_merge( $comments = array_merge(
@ -89,6 +95,7 @@ class DifferentialRevisionViewController extends DifferentialController {
$changeset_view->setChangesets($changesets); $changeset_view->setChangesets($changesets);
$changeset_view->setEditable(true); $changeset_view->setEditable(true);
$changeset_view->setRevision($revision); $changeset_view->setRevision($revision);
$changeset_view->setVsMap($vs_map);
$comment_form = new DifferentialAddCommentView(); $comment_form = new DifferentialAddCommentView();
$comment_form->setRevision($revision); $comment_form->setRevision($revision);
@ -315,6 +322,44 @@ class DifferentialRevisionViewController extends DifferentialController {
return $inline_comments; return $inline_comments;
} }
private function loadChangesetsAndVsMap(array $diffs, $diff_vs, $target) {
$load_ids = array();
if ($diff_vs) {
$load_ids[] = $diff_vs;
}
$load_ids[] = $target->getID();
$raw_changesets = id(new DifferentialChangeset())
->loadAllWhere(
'diffID IN (%Ld)',
$load_ids);
$changeset_groups = mgroup($raw_changesets, 'getDiffID');
$changesets = idx($changeset_groups, $target->getID(), array());
$changesets = mpull($changesets, null, 'getID');
$vs_map = array();
if ($diff_vs) {
$vs_changesets = idx($changeset_groups, $diff_vs, array());
$vs_changesets = mpull($vs_changesets, null, 'getFilename');
foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename();
if (isset($vs_changesets[$file])) {
$vs_map[$changeset->getID()] = $vs_changesets[$file]->getID();
unset($vs_changesets[$file]);
}
}
foreach ($vs_changesets as $changeset) {
$changesets[$changeset->getID()] = $changeset;
$vs_map[$changeset->getID()] = -1;
}
}
$changesets = msort($changesets, 'getSortKey');
return array($changesets, $vs_map);
}
} }
/* /*
@ -417,16 +462,6 @@ class DifferentialRevisionViewController extends DifferentialController {
} }
} }
$reviewer_links = array();
foreach ($revision->getReviewers() as $reviewer) {
$reviewer_links[] = <tools:handle handle={$handles[$reviewer]}
link={true} />;
}
if ($reviewer_links) {
$fields['Reviewers'] = array_implode(', ', $reviewer_links);
} else {
$fields['Reviewers'] = <em>None</em>;
}
$ccs = $revision->getCCFBIDs(); $ccs = $revision->getCCFBIDs();
if ($ccs) { if ($ccs) {
@ -777,68 +812,8 @@ class DifferentialRevisionViewController extends DifferentialController {
$changesets = id(new DifferentialChangeset())->loadAllFromArray($objects); $changesets = id(new DifferentialChangeset())->loadAllFromArray($objects);
} }
$against_warn = null;
$against_map = array();
$visible_changesets = array();
if ($old) {
$old_diff = $diffs[$old];
$new_diff = $diff;
$old_path = $old_diff->getSourcePath();
$new_path = $new_diff->getSourcePath();
$old_prefix = null;
$new_prefix = null;
if ((strlen($old_path) < strlen($new_path)) &&
(!strncmp($old_path, $new_path, strlen($old_path)))) {
$old_prefix = substr($new_path, strlen($old_path));
}
if ((strlen($new_path) < strlen($old_path)) &&
(!strncmp($old_path, $new_path, strlen($new_path)))) {
$new_prefix = substr($old_path, strlen($new_path));
}
$old_changesets = id(new DifferentialChangeset())
->loadAllFromArray($raw_objects[$old]);
$old_changesets = array_pull($old_changesets, null, 'getFilename');
if ($new_prefix) {
$rekeyed_map = array();
foreach ($old_changesets as $key => $value) {
$rekeyed_map[$new_prefix.$key] = $value;
}
$old_changesets = $rekeyed_map;
}
foreach ($changesets as $key => $changeset) {
$file = $old_prefix.$changeset->getFilename();
if (isset($old_changesets[$file])) {
$checksum = $changeset->getChecksum();
if ($checksum !== null &&
$checksum == $old_changesets[$file]->getChecksum()) {
unset($changesets[$key]);
unset($old_changesets[$file]);
} else {
$against_map[$changeset->getID()] = $old_changesets[$file]->getID();
unset($old_changesets[$file]);
}
}
}
foreach ($old_changesets as $changeset) {
$changesets[$changeset->getID()] = $changeset;
$against_map[$changeset->getID()] = -1;
}
$against_warn =
<tools:notice title="NOTE - Diff of Diffs">
You are viewing a synthetic diff between two previous diffs in this
revision. You can not add new inline comments (for now).
</tools:notice>;
} else {
$visible_changesets = array_pull($changesets, 'getID');
}
$changesets = array_psort($changesets, 'getSortKey'); $changesets = array_psort($changesets, 'getSortKey');
$all_changesets = $changesets;
$warning = null; $warning = null;
$limit = 100; $limit = 100;

View file

@ -58,6 +58,13 @@ class DifferentialChangesetParser {
const WHITESPACE_IGNORE_TRAILING = 'ignore-trailing'; const WHITESPACE_IGNORE_TRAILING = 'ignore-trailing';
const WHITESPACE_IGNORE_ALL = 'ignore-all'; const WHITESPACE_IGNORE_ALL = 'ignore-all';
public function setRightSideCommentMapping($id, $is_new) {
}
public function setLeftSideCommentMapping($id, $is_new) {
}
public function setChangeset($changeset) { public function setChangeset($changeset) {
$this->changeset = $changeset; $this->changeset = $changeset;

View file

@ -21,6 +21,7 @@ class DifferentialChangesetListView extends AphrontView {
private $changesets = array(); private $changesets = array();
private $editable; private $editable;
private $revision; private $revision;
private $vsMap;
public function setChangesets($changesets) { public function setChangesets($changesets) {
$this->changesets = $changesets; $this->changesets = $changesets;
@ -37,48 +38,39 @@ class DifferentialChangesetListView extends AphrontView {
return $this; return $this;
} }
public function setVsMap(array $vs_map) {
$this->vsMap = $vs_map;
return $this;
}
public function render() { public function render() {
require_celerity_resource('differential-changeset-view-css'); require_celerity_resource('differential-changeset-view-css');
$against = array(); // TODO $vs_map = $this->vsMap;
$edit = false;
$changesets = $this->changesets; $changesets = $this->changesets;
foreach ($changesets as $key => $changeset) {
if (empty($against[$changeset->getID()])) {
$type = $changeset->getChangeType();
if ($type == DifferentialChangeType::TYPE_MOVE_AWAY ||
$type == DifferentialChangeType::TYPE_MULTICOPY) {
unset($changesets[$key]);
}
}
}
$output = array(); $output = array();
$mapping = array(); $mapping = array();
foreach ($changesets as $key => $changeset) { foreach ($changesets as $key => $changeset) {
$file = $changeset->getFilename(); $file = $changeset->getFilename();
$class = 'differential-changeset'; $class = 'differential-changeset';
if (!$edit) { if (!$this->editable) {
$class .= ' differential-changeset-noneditable'; $class .= ' differential-changeset-noneditable';
} }
$id = $changeset->getID(); $id = $changeset->getID();
if ($id) { if ($id) {
$against_id = idx($against, $id); $vs_id = idx($vs_map, $id);
} else { } else {
$against_id = null; $vs_id = null;
} }
/* $detail_uri = new PhutilURI('/differential/changeset/');
TODO $detail_uri->setQueryParams(
$detail_uri = URI($render_uri) array(
->addQueryData(array( 'id' => $id,
'changeset' => $id, 'vs' => $vs_id,
'against' => $against_id, 'whitespace' => 'TODO',
'whitespace' => $whitespace,
)); ));
*/
$detail_uri = '/differential/changeset/?id='.$changeset->getID();
$detail_button = phutil_render_tag( $detail_button = phutil_render_tag(
'a', 'a',
@ -104,7 +96,9 @@ class DifferentialChangesetListView extends AphrontView {
'<div class="differential-loading">Loading...</div>')); '<div class="differential-loading">Loading...</div>'));
$output[] = $detail->render(); $output[] = $detail->render();
$mapping[$uniq_id] = array($changeset->getID()); $mapping[$uniq_id] = array(
$changeset->getID(),
$vs_id);
} }
$whitespace = null; $whitespace = null;

View file

@ -6,13 +6,13 @@
phutil_require_module('phabricator', 'applications/differential/constants/changetype');
phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview'); phutil_require_module('phabricator', 'applications/differential/view/changesetdetailview');
phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'view/base'); phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'markup');
phutil_require_module('phutil', 'parser/uri');
phutil_require_module('phutil', 'utils'); phutil_require_module('phutil', 'utils');

View file

@ -69,18 +69,38 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
$idx = 0; $idx = 0;
$rows = array(); $rows = array();
$disable = false;
$radios = array();
foreach ($data as $row) { foreach ($data as $row) {
$name = phutil_escape_html($row['name']); $name = phutil_escape_html($row['name']);
$id = phutil_escape_html($row['id']); $id = phutil_escape_html($row['id']);
$radios = array();
$lint = '*'; $lint = '*';
$unit = '*'; $unit = '*';
$old_class = null; $old_class = null;
$new_class = null; $new_class = null;
if ($id) {
$new_checked = ($this->selectedDiffID == $id);
$new = javelin_render_tag(
'input',
array(
'type' => 'radio',
'name' => 'id',
'value' => $id,
'checked' => $new_checked ? 'checked' : null,
'sigil' => 'differential-new-radio',
));
if ($new_checked) {
$new_class = " revhistory-new-now";
$disable = true;
}
} else {
$new = null;
}
if ($max_id != $id) { if ($max_id != $id) {
$uniq = celerity_generate_unique_node_id(); $uniq = celerity_generate_unique_node_id();
$old_checked = ($this->selectedVersusDiffID == $id); $old_checked = ($this->selectedVersusDiffID == $id);
@ -89,9 +109,10 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
array( array(
'type' => 'radio', 'type' => 'radio',
'name' => 'vs', 'name' => 'vs',
'value' => '0', 'value' => $id,
'id' => $uniq, 'id' => $uniq,
'checked' => $old_checked ? 'checked' : null, 'checked' => $old_checked ? 'checked' : null,
'disabled' => $disable ? 'disabled' : null,
)); ));
$radios[] = $uniq; $radios[] = $uniq;
if ($old_checked) { if ($old_checked) {
@ -101,30 +122,6 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
$old = null; $old = null;
} }
if ($id) {
$new_checked = ($this->selectedDiffID == $id);
$new = phutil_render_tag(
'input',
array(
'type' => 'radio',
'name' => 'id',
'value' => $id,
'checked' => $new_checked ? 'checked' : null,
));
if ($new_checked) {
$new_class = " revhistory-new-now";
}
} else {
$new = null;
}
Javelin::initBehavior(
'differential-diff-radios',
array(
'radios' => $radios,
));
$desc = 'TODO'; $desc = 'TODO';
$age = '-'; $age = '-';
@ -147,6 +144,12 @@ final class DifferentialRevisionUpdateHistoryView extends AphrontView {
'</tr>'; '</tr>';
} }
Javelin::initBehavior(
'differential-diff-radios',
array(
'radios' => $radios,
));
$select = '<select><option>Ignore All</option></select>'; $select = '<select><option>Ignore All</option></select>';
return return

View file

@ -8,6 +8,7 @@
phutil_require_module('phabricator', 'infrastructure/celerity/api'); phutil_require_module('phabricator', 'infrastructure/celerity/api');
phutil_require_module('phabricator', 'infrastructure/javelin/api'); phutil_require_module('phabricator', 'infrastructure/javelin/api');
phutil_require_module('phabricator', 'infrastructure/javelin/markup');
phutil_require_module('phabricator', 'view/base'); phutil_require_module('phabricator', 'view/base');
phutil_require_module('phutil', 'markup'); phutil_require_module('phutil', 'markup');

View file

@ -65,6 +65,12 @@ select, input, button, textarea, button {
font: 99% 'lucida grande', tahoma, verdana, arial, clean, sans-serif; font: 99% 'lucida grande', tahoma, verdana, arial, clean, sans-serif;
} }
select {
/* NOTE: In Safari, specifying a border color makes the browser respect
"font-size" settings. */
border: 1px solid #999999;
}
table { table {
font-size: inherit; font-size: inherit;
font: 100%; font: 100%;

View file

@ -6,7 +6,7 @@
JX.behavior('differential-diff-radios', function(config) { JX.behavior('differential-diff-radios', function(config) {
JX.Stratcom.listen( JX.Stratcom.listen(
'click', 'click',
'new-radio', 'differential-new-radio',
function(e) { function(e) {
var target = e.getTarget(); var target = e.getTarget();
var adjust; var adjust;
@ -14,7 +14,7 @@ JX.behavior('differential-diff-radios', function(config) {
var reset = false; var reset = false;
for (var ii = 0; ii < config.radios.length; ii++) { for (var ii = 0; ii < config.radios.length; ii++) {
node = JX.$(config.radios[ii]); node = JX.$(config.radios[ii]);
if (node.value >= target.value) { if (parseInt(node.value, 10) >= parseInt(target.value, 10)) {
if (node.checked) { if (node.checked) {
node.checked = false; node.checked = false;
reset = true; reset = true;

View file

@ -13,7 +13,7 @@ JX.behavior('differential-populate', function(config) {
new JX.Request(config.uri, JX.bind(null, onresponse, k)) new JX.Request(config.uri, JX.bind(null, onresponse, k))
.setData({ .setData({
id: config.registry[k][0], id: config.registry[k][0],
against: config.registry[k][1], vs: config.registry[k][1],
whitespace: config.whitespace whitespace: config.whitespace
}) })
.send(); .send();