Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.github.java-diff-utils</groupId>
<artifactId>java-diff-utils</artifactId>
<version>4.12</version>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>5.13.5.202508271544-r</version>
</dependency>
</dependencies>

Expand Down
120 changes: 66 additions & 54 deletions src/main/java/com/evolvedbinary/maven/plugins/patch/PatchMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,20 @@
*/
package com.evolvedbinary.maven.plugins.patch;

import com.github.difflib.patch.PatchFailedException;
import com.github.difflib.unifieddiff.UnifiedDiff;
import com.github.difflib.unifieddiff.UnifiedDiffFile;
import com.github.difflib.unifieddiff.UnifiedDiffReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.eclipse.jgit.api.ApplyResult;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;

/**
* Applies unified diff patches.
Expand All @@ -56,62 +51,79 @@ public void execute() throws MojoExecutionException {
getLog().info("Applying patches...");

File[] patchFiles = patchDirectory.listFiles(
(dir, name) -> name.endsWith(".diff") || name.endsWith(".patch"));
(dir, name) -> name.endsWith(".diff") || name.endsWith(".patch"));
if (patchFiles == null || !patchDirectory.isDirectory()) {
throw new MojoExecutionException("'patchDirectory' must be a directory.");
}
if (!targetDirectory.isDirectory()) {
throw new MojoExecutionException("'targetDirectory' must be a directory.");
}

final File tempGitDir;
try {
for (File patchFile : patchFiles) {
String patchFileName = patchFile.getName();
getLog().info(String.format("Applying patch '%s'...", patchFile.getName()));

UnifiedDiff diff = UnifiedDiffReader.parseUnifiedDiff(
new FileInputStream(patchFile));

Map<Path, List<String>> writeResults = new HashMap<>();
for (UnifiedDiffFile file : diff.getFiles()) {
Path targetFile = targetDirectory.toPath().resolve(file.getToFile());
String targetFileName = targetFile.getFileName().toString();

try {
List<String> results = file.getPatch().applyTo(
Files.readAllLines(targetFile)
);

writeResults.put(targetFile, results);

getLog().info(
String.format("Applied diff to '%s' successfully.", targetFileName));
} catch (PatchFailedException pfe1) {
String failureMessage = String.format(
"Failed to apply patch file '%s' to file '%s'. (It may already have been applied!)",
patchFileName, targetFileName);

if (failOnFailedPatch) {
throw new MojoExecutionException(failureMessage);
} else {
getLog().warn(failureMessage);
tempGitDir = Files.createTempDirectory("jgit-temp-folder-").toFile();
//tempGitDir points to the jgit-temp-folder-2324344343 directory now.
} catch (IOException e) {
throw new MojoExecutionException("Could not create a temporary directory for JGit", e);
}

try {

try (Repository repository = new FileRepositoryBuilder()
.setGitDir(tempGitDir)
.setWorkTree(targetDirectory)
.build()) {

repository.create();

try (Git git = new Git(repository)) {
for (File patchFile : patchFiles) {
String patchFileName = patchFile.getName();
getLog().info("Apply: ");
getLog().info(patchFileName);

try (FileInputStream patchStream = new FileInputStream(patchFile)) {
ApplyResult result = git.apply()
.setPatch(patchStream)
.call();

for (File updatedFile : result.getUpdatedFiles()) {
getLog().info("Applied diff successfully");
getLog().info(updatedFile.getName());
}

} catch (GitAPIException | IOException applyException) {
String failureMessage = "Failed to apply patch file " + patchFileName +
" to directory " + targetDirectory + " (It may already have been applied)";

if (failOnFailedPatch) {
throw new MojoExecutionException(failureMessage, applyException);
} else {
getLog().warn("Failed to apply patch: ");
getLog().warn(patchFileName);
getLog().warn("It may already have been applied. ");
}
}
break;
getLog().info("Finished applying patch: ");
getLog().info(patchFileName);
}
getLog().info(String.format("Finished applying diff to '%s'.", targetFileName));
}
for (Entry<Path, List<String>> entry : writeResults.entrySet()) {
Files.write(entry.getKey(), entry.getValue());
}
getLog().info(String.format("Finished applying patch '%s'.", patchFileName));
} catch (IOException e) {
throw new MojoExecutionException("Something went wrong with IO Operations. ", e);
}
} finally {
deleteDirectoryQuietly(tempGitDir);
}
getLog().info("Finished applying patches");
}

} catch (NoSuchFileException nsfe) {
throw new MojoExecutionException(
String.format("Could not find the file '%s' for patching. ", nsfe.getFile()));
} catch (IOException e) {
throw new MojoExecutionException("Something went wrong with IO Operations.", e);
private void deleteDirectoryQuietly(File directory) {
File[] children = directory.listFiles();
if (children != null) {
for (File child : children) {
deleteDirectoryQuietly(child);
}
}
getLog().info("Finished applying patches.");
directory.delete();
}
}
}