Skip to content

Commit 555d7e5

Browse files
meteorcloudycopybara-github
authored andcommitted
Fixes a bug in PatchUtil after upgrading java-diff-utils
Apply the chunks separately and in reverse order to workaround an issue in applyFuzzy. See java-diff-utils/java-diff-utils#125 (comment) Fixes #17897 (comment) RELNOTES: None PiperOrigin-RevId: 571336806 Change-Id: I8eb6b859d1ce8fb990d9237f728198af34e0d393
1 parent 0937e01 commit 555d7e5

3 files changed

Lines changed: 76 additions & 8 deletions

File tree

src/main/java/com/google/devtools/build/lib/bazel/repository/PatchUtil.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,14 @@
1717
import static java.nio.charset.StandardCharsets.UTF_8;
1818

1919
import com.github.difflib.UnifiedDiffUtils;
20+
import com.github.difflib.patch.AbstractDelta;
2021
import com.github.difflib.patch.Patch;
2122
import com.github.difflib.patch.PatchFailedException;
2223
import com.google.common.base.Preconditions;
2324
import com.google.common.base.Splitter;
2425
import com.google.common.collect.ImmutableList;
2526
import com.google.common.collect.Iterables;
27+
import com.google.common.collect.Lists;
2628
import com.google.devtools.build.lib.vfs.FileSystemUtils;
2729
import com.google.devtools.build.lib.vfs.Path;
2830
import java.io.IOException;
@@ -212,13 +214,20 @@ private static void applyPatchToFile(
212214
}
213215
}
214216

215-
List<String> newContent;
216-
try {
217-
// By using applyFuzzy, the patch also applies when there is an offset.
218-
newContent = patch.applyFuzzy(oldContent, 0);
219-
} catch (PatchFailedException e) {
220-
throw new PatchFailedException(
221-
String.format("in patch applied to %s: %s", oldFile, e.getMessage()));
217+
List<String> newContent = new ArrayList<>(oldContent);
218+
// Apply the chunks separately and in reverse order to workaround an issue in applyFuzzy.
219+
// See https://github.com/java-diff-utils/java-diff-utils/pull/125#issuecomment-1749385825
220+
for (AbstractDelta<String> delta : Lists.reverse(patch.getDeltas())) {
221+
Patch<String> tmpPatch = new Patch<>();
222+
tmpPatch.addDelta(delta);
223+
try {
224+
newContent = tmpPatch.applyFuzzy(newContent, 0);
225+
} catch (PatchFailedException | IndexOutOfBoundsException e) {
226+
throw new PatchFailedException(
227+
String.format(
228+
"in patch applied to %s: %s, error applying change near line %s",
229+
oldFile, e.getMessage(), delta.getSource().getPosition() + 1));
230+
}
222231
}
223232

224233
// The file we should write newContent to.

src/test/java/com/google/devtools/build/lib/bazel/repository/PatchUtilTest.java

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,65 @@ public void testMatchWithOffset() throws IOException, PatchFailedException {
339339
assertThat(FileSystemUtils.readLines(foo, UTF_8)).isEqualTo(newFoo);
340340
}
341341

342+
@Test
343+
// regression test for https://github.com/bazelbuild/bazel/issues/17897#issuecomment-1749389613
344+
public void testMultipleChunks() throws IOException, PatchFailedException {
345+
Path foo =
346+
scratch.file(
347+
"/root/foo",
348+
"1",
349+
"2",
350+
"3",
351+
"4",
352+
"5",
353+
"6",
354+
"7",
355+
"8",
356+
"9",
357+
"10",
358+
"11",
359+
"12",
360+
"13",
361+
"14",
362+
"15",
363+
"16",
364+
"17",
365+
"18");
366+
Path patchFile =
367+
scratch.file(
368+
"/root/patchfile",
369+
"diff --git a/foo b/foo",
370+
"index c20ab12..b83bdb1 100644",
371+
"--- a/foo",
372+
"+++ b/foo",
373+
"@@ -1,12 +1,5 @@",
374+
" 1",
375+
" 2",
376+
"-3",
377+
"-4",
378+
"-5",
379+
"-6",
380+
"-7",
381+
"-8",
382+
"-9",
383+
" 10",
384+
" 11",
385+
" 12",
386+
"@@ -15,4 +8,7 @@",
387+
" 15",
388+
" 16",
389+
" 17",
390+
"+a",
391+
"+b",
392+
"+c",
393+
" 18");
394+
PatchUtil.apply(patchFile, 1, root);
395+
ImmutableList<String> newFoo =
396+
ImmutableList.of(
397+
"1", "2", "10", "11", "12", "13", "14", "15", "16", "17", "a", "b", "c", "18");
398+
assertThat(FileSystemUtils.readLines(foo, UTF_8)).isEqualTo(newFoo);
399+
}
400+
342401
@Test
343402
public void testMultipleChunksWithDifferentOffset() throws IOException, PatchFailedException {
344403
Path foo =

src/test/java/com/google/devtools/build/lib/bazel/repository/starlark/StarlarkRepositoryContextTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ public void testPatchErrorWasThrown() throws Exception {
377377
.isEqualTo(
378378
"Error applying patch /outputDir/my.patch: in patch applied to "
379379
+ "/outputDir/foo: could not apply patch due to"
380-
+ " CONTENT_DOES_NOT_MATCH_TARGET");
380+
+ " CONTENT_DOES_NOT_MATCH_TARGET, error applying change near line 1");
381381
}
382382
}
383383

0 commit comments

Comments
 (0)