forked from Qortal/qortal
Create a "unified-diff" patch using java-diff-utils instead of including the entire modified file. I still need to test how well this works with binary files.
This commit is contained in:
parent
a6154cbb43
commit
cb6fc466d1
@ -1,13 +1,17 @@
|
||||
package org.qortal.arbitrary;
|
||||
|
||||
import com.github.difflib.DiffUtils;
|
||||
import com.github.difflib.UnifiedDiffUtils;
|
||||
import com.github.difflib.patch.Patch;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
|
||||
import org.qortal.crypto.Crypto;
|
||||
import org.qortal.settings.Settings;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.ArrayList;
|
||||
@ -133,9 +137,14 @@ public class ArbitraryDataDiff {
|
||||
wasModified = true;
|
||||
}
|
||||
|
||||
if (wasAdded | wasModified) {
|
||||
if (wasAdded) {
|
||||
ArbitraryDataDiff.copyFilePathToBaseDir(after, diffPathAbsolute, filePathAfter);
|
||||
}
|
||||
if (wasModified) {
|
||||
// Create patch using java-diff-utils
|
||||
Path destination = Paths.get(diffPathAbsolute.toString(), filePathAfter.toString());
|
||||
ArbitraryDataDiff.createAndCopyDiffUtilsPatch(filePathBefore, after, destination);
|
||||
}
|
||||
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
@ -159,7 +168,7 @@ public class ArbitraryDataDiff {
|
||||
}
|
||||
}
|
||||
|
||||
private void findRemovedFiles() {
|
||||
private void findRemovedFiles() throws IOException {
|
||||
try {
|
||||
final Path pathBeforeAbsolute = this.pathBefore.toAbsolutePath();
|
||||
final Path pathAfterAbsolute = this.pathAfter.toAbsolutePath();
|
||||
@ -219,7 +228,7 @@ public class ArbitraryDataDiff {
|
||||
|
||||
});
|
||||
} catch (IOException e) {
|
||||
LOGGER.info("IOException when walking through file tree: {}", e.getMessage());
|
||||
throw new IOException(String.format("IOException when walking through file tree: %s", e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,6 +240,7 @@ public class ArbitraryDataDiff {
|
||||
|
||||
private void writeMetadata() throws IOException {
|
||||
ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.diffPath);
|
||||
metadata.setPatchType("unified-diff");
|
||||
metadata.setAddedPaths(this.addedPaths);
|
||||
metadata.setModifiedPaths(this.modifiedPaths);
|
||||
metadata.setRemovedPaths(this.removedPaths);
|
||||
@ -264,6 +274,50 @@ public class ArbitraryDataDiff {
|
||||
LOGGER.trace("Copying {} to {}", source, dest);
|
||||
Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
private static void createAndCopyDiffUtilsPatch(Path before, Path after, Path destination) throws IOException {
|
||||
if (!Files.exists(before)) {
|
||||
throw new IOException(String.format("File not found (before): %s", before.toString()));
|
||||
}
|
||||
if (!Files.exists(after)) {
|
||||
throw new IOException(String.format("File not found (after): %s", after.toString()));
|
||||
}
|
||||
|
||||
// Ensure parent folders exist in the destination
|
||||
File file = new File(destination.toString());
|
||||
File parent = file.getParentFile();
|
||||
if (parent != null) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
|
||||
// Delete an existing file if it exists
|
||||
File destFile = destination.toFile();
|
||||
if (destFile.exists() && destFile.isFile()) {
|
||||
Files.delete(destination);
|
||||
}
|
||||
|
||||
// Load the two files into memory
|
||||
List<String> original = FileUtils.readLines(before.toFile(), StandardCharsets.UTF_8);
|
||||
List<String> revised = FileUtils.readLines(after.toFile(), StandardCharsets.UTF_8);
|
||||
|
||||
// Generate diff information
|
||||
Patch<String> diff = DiffUtils.diff(original, revised);
|
||||
|
||||
// Generate unified diff format
|
||||
String originalFileName = before.getFileName().toString();
|
||||
String revisedFileName = after.getFileName().toString();
|
||||
List<String> unifiedDiff = UnifiedDiffUtils.generateUnifiedDiff(originalFileName, revisedFileName, original, diff, 0);
|
||||
|
||||
// Write the diff to the destination directory
|
||||
FileWriter fileWriter = new FileWriter(destination.toString(), true);
|
||||
BufferedWriter writer = new BufferedWriter(fileWriter);
|
||||
for (String line : unifiedDiff) {
|
||||
writer.append(line);
|
||||
writer.newLine();
|
||||
}
|
||||
writer.flush();
|
||||
writer.close();
|
||||
}
|
||||
|
||||
|
||||
public Path getDiffPath() {
|
||||
|
@ -17,6 +17,7 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataMetadataPatch.class);
|
||||
|
||||
private String patchType;
|
||||
private List<Path> addedPaths;
|
||||
private List<Path> modifiedPaths;
|
||||
private List<Path> removedPaths;
|
||||
@ -43,6 +44,12 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
||||
}
|
||||
|
||||
JSONObject patch = new JSONObject(this.jsonString);
|
||||
if (patch.has("patchType")) {
|
||||
String patchType = patch.getString("patchType");
|
||||
if (patchType != null) {
|
||||
this.patchType = patchType;
|
||||
}
|
||||
}
|
||||
if (patch.has("prevSig")) {
|
||||
String prevSig = patch.getString("prevSig");
|
||||
if (prevSig != null) {
|
||||
@ -94,8 +101,9 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
||||
changeMap.set(patch, new LinkedHashMap<>());
|
||||
changeMap.setAccessible(false);
|
||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
||||
// Don't worry about failures as this is for ordering only
|
||||
// Don't worry about failures as this is for optional ordering only
|
||||
}
|
||||
patch.put("patchType", this.patchType);
|
||||
patch.put("prevSig", Base58.encode(this.previousSignature));
|
||||
patch.put("prevHash", Base58.encode(this.previousHash));
|
||||
patch.put("added", new JSONArray(this.addedPaths));
|
||||
@ -107,6 +115,14 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
||||
}
|
||||
|
||||
|
||||
public void setPatchType(String patchType) {
|
||||
this.patchType = patchType;
|
||||
}
|
||||
|
||||
public String getPatchType() {
|
||||
return this.patchType;
|
||||
}
|
||||
|
||||
public void setAddedPaths(List<Path> addedPaths) {
|
||||
this.addedPaths = addedPaths;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user