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;
|
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.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
|
import org.qortal.arbitrary.metadata.ArbitraryDataMetadataPatch;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.settings.Settings;
|
import org.qortal.settings.Settings;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -133,9 +137,14 @@ public class ArbitraryDataDiff {
|
|||||||
wasModified = true;
|
wasModified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasAdded | wasModified) {
|
if (wasAdded) {
|
||||||
ArbitraryDataDiff.copyFilePathToBaseDir(after, diffPathAbsolute, filePathAfter);
|
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;
|
return FileVisitResult.CONTINUE;
|
||||||
}
|
}
|
||||||
@ -159,7 +168,7 @@ public class ArbitraryDataDiff {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findRemovedFiles() {
|
private void findRemovedFiles() throws IOException {
|
||||||
try {
|
try {
|
||||||
final Path pathBeforeAbsolute = this.pathBefore.toAbsolutePath();
|
final Path pathBeforeAbsolute = this.pathBefore.toAbsolutePath();
|
||||||
final Path pathAfterAbsolute = this.pathAfter.toAbsolutePath();
|
final Path pathAfterAbsolute = this.pathAfter.toAbsolutePath();
|
||||||
@ -219,7 +228,7 @@ public class ArbitraryDataDiff {
|
|||||||
|
|
||||||
});
|
});
|
||||||
} catch (IOException e) {
|
} 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 {
|
private void writeMetadata() throws IOException {
|
||||||
ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.diffPath);
|
ArbitraryDataMetadataPatch metadata = new ArbitraryDataMetadataPatch(this.diffPath);
|
||||||
|
metadata.setPatchType("unified-diff");
|
||||||
metadata.setAddedPaths(this.addedPaths);
|
metadata.setAddedPaths(this.addedPaths);
|
||||||
metadata.setModifiedPaths(this.modifiedPaths);
|
metadata.setModifiedPaths(this.modifiedPaths);
|
||||||
metadata.setRemovedPaths(this.removedPaths);
|
metadata.setRemovedPaths(this.removedPaths);
|
||||||
@ -265,6 +275,50 @@ public class ArbitraryDataDiff {
|
|||||||
Files.copy(source, dest, StandardCopyOption.REPLACE_EXISTING);
|
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() {
|
public Path getDiffPath() {
|
||||||
return this.diffPath;
|
return this.diffPath;
|
||||||
|
@ -17,6 +17,7 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataMetadataPatch.class);
|
private static final Logger LOGGER = LogManager.getLogger(ArbitraryDataMetadataPatch.class);
|
||||||
|
|
||||||
|
private String patchType;
|
||||||
private List<Path> addedPaths;
|
private List<Path> addedPaths;
|
||||||
private List<Path> modifiedPaths;
|
private List<Path> modifiedPaths;
|
||||||
private List<Path> removedPaths;
|
private List<Path> removedPaths;
|
||||||
@ -43,6 +44,12 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JSONObject patch = new JSONObject(this.jsonString);
|
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")) {
|
if (patch.has("prevSig")) {
|
||||||
String prevSig = patch.getString("prevSig");
|
String prevSig = patch.getString("prevSig");
|
||||||
if (prevSig != null) {
|
if (prevSig != null) {
|
||||||
@ -94,8 +101,9 @@ public class ArbitraryDataMetadataPatch extends ArbitraryDataMetadata {
|
|||||||
changeMap.set(patch, new LinkedHashMap<>());
|
changeMap.set(patch, new LinkedHashMap<>());
|
||||||
changeMap.setAccessible(false);
|
changeMap.setAccessible(false);
|
||||||
} catch (IllegalAccessException | NoSuchFieldException e) {
|
} 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("prevSig", Base58.encode(this.previousSignature));
|
||||||
patch.put("prevHash", Base58.encode(this.previousHash));
|
patch.put("prevHash", Base58.encode(this.previousHash));
|
||||||
patch.put("added", new JSONArray(this.addedPaths));
|
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) {
|
public void setAddedPaths(List<Path> addedPaths) {
|
||||||
this.addedPaths = addedPaths;
|
this.addedPaths = addedPaths;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user