Skip to content

Commit 3eafe9e

Browse files
author
epriestley
committed
Fix Diffusion rendering of SVN files which did not change
Summary: Share code with the new PhabricatorDifferenceEngine, which handles diffs with no changes correctly. (This isn't the same issue as file moves, but I ran into it while generating a repro case.) Test Plan: Previously, changes which didn't change file content (e.g., property changes) would throw. Now they work. Reviewed By: tuomaspelkonen Reviewers: tuomaspelkonen, jungejason, aran CC: aran, epriestley, tuomaspelkonen Differential Revision: 698
1 parent ed5c466 commit 3eafe9e

File tree

3 files changed

+70
-23
lines changed

3 files changed

+70
-23
lines changed

src/applications/diffusion/query/diff/svn/DiffusionSvnDiffQuery.php

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,17 @@ protected function executeQuery() {
9090
$futures = array_filter($futures);
9191

9292
foreach (Futures($futures) as $key => $future) {
93-
$futures[$key] = $future->resolvex();
93+
list($stdout) = $future->resolvex();
94+
$futures[$key] = $stdout;
9495
}
9596

9697
$old_data = idx($futures, 'old', '');
9798
$new_data = idx($futures, 'new', '');
9899

99-
$old_tmp = new TempFile();
100-
$new_tmp = new TempFile();
101-
102-
Filesystem::writeFile($old_tmp, $old_data);
103-
Filesystem::writeFile($new_tmp, $new_data);
104-
105-
list($err, $raw_diff) = exec_manual(
106-
'diff -L %s -L %s -U65535 %s %s',
107-
nonempty($old_name, '/dev/universe').' 9999-99-99',
108-
nonempty($new_name, '/dev/universe').' 9999-99-99',
109-
$old_tmp,
110-
$new_tmp);
100+
$engine = new PhabricatorDifferenceEngine();
101+
$engine->setOldName($old_name);
102+
$engine->setNewName($new_name);
103+
$raw_diff = $engine->generateRawDiffFromFileContent($old_data, $new_data);
111104

112105
$parser = new ArcanistDiffParser();
113106
$parser->setDetectBinaryFiles(true);

src/applications/diffusion/query/diff/svn/__init__.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
phutil_require_module('phabricator', 'applications/diffusion/data/pathchange');
1414
phutil_require_module('phabricator', 'applications/diffusion/query/diff/base');
1515
phutil_require_module('phabricator', 'applications/diffusion/query/pathchange/base');
16+
phutil_require_module('phabricator', 'infrastructure/diff/engine');
1617

17-
phutil_require_module('phutil', 'filesystem');
18-
phutil_require_module('phutil', 'filesystem/tempfile');
1918
phutil_require_module('phutil', 'future');
2019
phutil_require_module('phutil', 'future/exec');
2120
phutil_require_module('phutil', 'utils');

src/infrastructure/diff/engine/PhabricatorDifferenceEngine.php

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@
2525
*/
2626
final class PhabricatorDifferenceEngine {
2727

28+
2829
private $ignoreWhitespace;
30+
private $oldName;
31+
private $newName;
2932

3033

3134
/* -( Configuring the Engine )--------------------------------------------- */
@@ -44,20 +47,46 @@ public function setIgnoreWhitespace($ignore_whitespace) {
4447
}
4548

4649

50+
/**
51+
* Set the name to identify the old file with. Primarily cosmetic.
52+
*
53+
* @param string Old file name.
54+
* @return this
55+
* @task config
56+
*/
57+
public function setOldName($old_name) {
58+
$this->oldName = $old_name;
59+
return $this;
60+
}
61+
62+
63+
/**
64+
* Set the name to identify the new file with. Primarily cosmetic.
65+
*
66+
* @param string New file name.
67+
* @return this
68+
* @task config
69+
*/
70+
public function setNewName($new_name) {
71+
$this->newName = $new_name;
72+
return $this;
73+
}
74+
75+
4776
/* -( Generating Diffs )--------------------------------------------------- */
4877

4978

5079
/**
51-
* Generate an @{class:DifferentialChangeset} from two raw files. This is
52-
* principally useful because you can feed the output to
53-
* @{class:DifferentialChangesetParser} in order to render it.
80+
* Generate a raw diff from two raw files. This is a lower-level API than
81+
* @{method:generateChangesetFromFileContent}, but may be useful if you need
82+
* to use a custom parser configuration, as with Diffusion.
5483
*
5584
* @param string Entire previous file content.
5685
* @param string Entire current file content.
57-
* @return @{class:DifferentialChangeset} Synthetic changeset.
86+
* @return string Raw diff between the two files.
5887
* @task diff
5988
*/
60-
public function generateChangesetFromFileContent($old, $new) {
89+
public function generateRawDiffFromFileContent($old, $new) {
6190

6291
$options = array();
6392
if ($this->ignoreWhitespace) {
@@ -67,6 +96,14 @@ public function generateChangesetFromFileContent($old, $new) {
6796
// Generate diffs with full context.
6897
$options[] = '-U65535';
6998

99+
$old_name = nonempty($this->oldName, '/dev/universe').' 9999-99-99';
100+
$new_name = nonempty($this->newName, '/dev/universe').' 9999-99-99';
101+
102+
$options[] = '-L';
103+
$options[] = $old_name;
104+
$options[] = '-L';
105+
$options[] = $new_name;
106+
70107
$old_tmp = new TempFile();
71108
$new_tmp = new TempFile();
72109

@@ -78,13 +115,14 @@ public function generateChangesetFromFileContent($old, $new) {
78115
$old_tmp,
79116
$new_tmp);
80117

81-
if (!strlen($diff)) {
118+
if (!$err) {
82119
// This indicates that the two files are the same (or, possibly, the
83120
// same modulo whitespace differences, which is why we can't do this
84121
// check trivially before running `diff`). Build a synthetic, changeless
85122
// diff so that we can still render the raw, unchanged file instead of
86123
// being forced to just say "this file didn't change" since we don't have
87124
// the content.
125+
88126
$entire_file = explode("\n", $old);
89127
foreach ($entire_file as $k => $line) {
90128
$entire_file[$k] = ' '.$line;
@@ -93,12 +131,29 @@ public function generateChangesetFromFileContent($old, $new) {
93131
$entire_file = implode("\n", $entire_file);
94132

95133
// This is a bit hacky but the diff parser can handle it.
96-
$diff = "--- ignored 9999-99-99\n".
97-
"+++ ignored 9999-99-99\n".
134+
$diff = "--- {$old_name}\n".
135+
"+++ {$new_name}\n".
98136
"@@ -1,{$len} +1,{$len} @@\n".
99137
$entire_file."\n";
100138
}
101139

140+
return $diff;
141+
}
142+
143+
144+
/**
145+
* Generate an @{class:DifferentialChangeset} from two raw files. This is
146+
* principally useful because you can feed the output to
147+
* @{class:DifferentialChangesetParser} in order to render it.
148+
*
149+
* @param string Entire previous file content.
150+
* @param string Entire current file content.
151+
* @return @{class:DifferentialChangeset} Synthetic changeset.
152+
* @task diff
153+
*/
154+
public function generateChangesetFromFileContent($old, $new) {
155+
$diff = $this->generateRawDiffFromFileContent($old, $new);
156+
102157
$changes = id(new ArcanistDiffParser())->parseDiff($diff);
103158
$diff = DifferentialDiff::newFromRawChanges($changes);
104159
return head($diff->getChangesets());

0 commit comments

Comments
 (0)