├── settings.gradle ├── README.md ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitignore ├── LICENSE.txt ├── src └── main │ └── java │ └── codechicken │ └── diffpatch │ └── gradle │ ├── util │ ├── ConsumingOutputStream.java │ └── Utils.java │ ├── diff │ ├── DiffTask.java │ ├── DiffSpec.java │ └── DiffAction.java │ └── patch │ ├── PatchTask.java │ ├── PatchAction.java │ └── PatchSpec.java ├── gradlew.bat └── gradlew /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'DiffPatchGradle' 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DiffPatchGradle 2 | Super simple Gradle Task implementation of: https://github.com/TheCBProject/DiffPatch 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCBProject/DiffPatchGradle/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.3-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # exclude all 2 | /* 3 | 4 | # Include Important Folders 5 | !src/ 6 | 7 | # Other Files. 8 | !LICENSE.txt 9 | !README.md 10 | 11 | # Gradle stuff 12 | !gradle/ 13 | !gradlew 14 | !gradlew.bat 15 | !build.gradle 16 | !settings.gradle 17 | 18 | # Include git important files 19 | !.gitmodules 20 | !.gitignore 21 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 covers1624 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/util/ConsumingOutputStream.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.util; 2 | 3 | import java.io.OutputStream; 4 | import java.util.function.Consumer; 5 | 6 | /** 7 | * Created by covers1624 on 20/12/18. 8 | */ 9 | public class ConsumingOutputStream extends OutputStream { 10 | 11 | private static final char CR = '\r'; 12 | private static final char LF = '\n'; 13 | 14 | private final Consumer consumer; 15 | private final StringBuilder buffer = new StringBuilder(); 16 | 17 | public ConsumingOutputStream(Consumer consumer) { 18 | this.consumer = consumer; 19 | } 20 | 21 | @Override 22 | public void write(int b) { 23 | char ch = (char) (b & 0xFF); 24 | if (ch == CR) { 25 | return; 26 | } 27 | buffer.append(ch); 28 | if (ch == LF) { 29 | flush(); 30 | } 31 | } 32 | 33 | @Override 34 | public void flush() { 35 | String str = buffer.toString(); 36 | if (str.endsWith("\n")) { 37 | str = str.replaceAll("\n", ""); 38 | consumer.accept(str); 39 | buffer.setLength(0); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/diff/DiffTask.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.diff; 2 | 3 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 4 | import org.gradle.api.DefaultTask; 5 | import org.gradle.api.tasks.TaskAction; 6 | 7 | import java.io.File; 8 | 9 | /** 10 | * Incredibly simple Task implementation of {@link DiffAction}. 11 | * Does no Input/Output caching, it is recommended to extend this 12 | * and implement those yourself as desired for your use case. 13 | *

14 | * Created by covers1624 on 14/8/20. 15 | */ 16 | public class DiffTask extends DefaultTask implements DiffSpec { 17 | 18 | private final DiffAction action; 19 | 20 | public DiffTask() { 21 | action = new DiffAction(getProject()); 22 | } 23 | 24 | @TaskAction 25 | public void doTask() throws Exception { 26 | action.execute(); 27 | } 28 | 29 | //@formatter:off 30 | @Override public File getBase() { return action.getBase(); } 31 | @Override public File getModified() { return action.getModified(); } 32 | @Override public File getOutput() { return action.getOutput(); } 33 | @Override public ArchiveFormat getOutputFormat() { return action.getOutputFormat(); } 34 | @Override public boolean isAutoHeader() { return action.isAutoHeader(); } 35 | @Override public int getContextLines() { return action.getContextLines(); } 36 | @Override public boolean isVerbose() { return action.isVerbose(); } 37 | @Override public boolean isPrintSummary() { return action.isPrintSummary(); } 38 | @Override public void setBase(Object base) { action.setBase(base); } 39 | @Override public void setModified(Object modified) { action.setModified(modified); } 40 | @Override public void setOutput(Object patches) { action.setOutput(patches); } 41 | @Override public void setOutputFormat(Object format) { action.setOutputFormat(format); } 42 | @Override public void setAutoHeader(boolean autoHeader) { action.setAutoHeader(autoHeader); } 43 | @Override public void setContextLines(int lines) { action.setContextLines(lines); } 44 | @Override public void setVerbose(boolean verbose) { action.setVerbose(verbose); } 45 | @Override public void setPrintSummary(boolean printSummary) { action.setPrintSummary(printSummary); } 46 | //@formatter:on 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/util/Utils.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.util; 2 | 3 | import codechicken.diffpatch.util.PatchMode; 4 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 5 | import groovy.lang.Closure; 6 | import org.gradle.api.Project; 7 | 8 | import java.io.File; 9 | import java.util.Locale; 10 | import java.util.function.Supplier; 11 | 12 | /** 13 | * Created by covers1624 on 14/8/20. 14 | */ 15 | public class Utils { 16 | 17 | public static File resolveFile(Project project, Object obj) { 18 | if (obj instanceof Closure) { 19 | return resolveFile(project, ((Closure) obj).call()); 20 | } else if (obj instanceof Supplier) { 21 | return resolveFile(project, ((Supplier) obj).get()); 22 | } else { 23 | return project.file(obj); 24 | } 25 | } 26 | 27 | public static PatchMode resolvePatchMode(Object value) { 28 | if (value == null) { 29 | throw new NullPointerException("value"); 30 | } 31 | if (value instanceof PatchMode) { 32 | return (PatchMode) value; 33 | } 34 | if (value instanceof CharSequence) { 35 | String upper = value.toString().toUpperCase(Locale.ROOT); 36 | try { 37 | return PatchMode.valueOf(upper); 38 | } catch (IllegalArgumentException e) { 39 | throw new IllegalArgumentException("Unknown PatchMode String value: " + value.toString()); 40 | } 41 | } 42 | throw new IllegalArgumentException("Unable to parse PatchMode, Unknown value: " + value.toString()); 43 | } 44 | 45 | public static ArchiveFormat resolveArchiveFormat(Object value) { 46 | if (value == null) { 47 | throw new NullPointerException("value"); 48 | } 49 | if (value instanceof ArchiveFormat) { 50 | return (ArchiveFormat) value; 51 | } 52 | if (value instanceof CharSequence) { 53 | String upper = value.toString().toUpperCase(Locale.ROOT); 54 | try { 55 | return ArchiveFormat.valueOf(upper); 56 | } catch (IllegalArgumentException e) { 57 | throw new IllegalArgumentException("Unknown ArchiveFormat String value: " + value.toString()); 58 | } 59 | } 60 | throw new IllegalArgumentException("Unable to parse ArchiveFormat, Unknown value: " + value.toString()); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/patch/PatchTask.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.patch; 2 | 3 | import codechicken.diffpatch.util.PatchMode; 4 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 5 | import org.gradle.api.DefaultTask; 6 | import org.gradle.api.tasks.TaskAction; 7 | 8 | import java.io.File; 9 | 10 | /** 11 | * Incredibly simple Task implementation of PatchAction. 12 | * Does no Input/Output caching, it is recommended to extend this 13 | * and implement those yourself as desired. 14 | *

15 | * Created by covers1624 on 14/8/20. 16 | */ 17 | public class PatchTask extends DefaultTask implements PatchSpec { 18 | 19 | private final PatchAction action; 20 | 21 | public PatchTask() { 22 | this.action = new PatchAction(getProject()); 23 | } 24 | 25 | @TaskAction 26 | public void doTask() throws Exception { 27 | action.execute(); 28 | } 29 | 30 | //@formatter:off 31 | @Override public File getBase() { return action.getBase(); } 32 | @Override public File getPatches() { return action.getPatches(); } 33 | @Override public File getOutput() { return action.getOutput(); } 34 | @Override public File getRejects() { return action.getRejects(); } 35 | @Override public ArchiveFormat getOutputFormat() { return action.getOutputFormat(); } 36 | @Override public ArchiveFormat getRejectsFormat() { return action.getRejectsFormat(); } 37 | @Override public float getMinFuzzQuality() { return action.getMinFuzzQuality(); } 38 | @Override public int getMaxFuzzOffset() { return action.getMaxFuzzOffset(); } 39 | @Override public PatchMode getPatchMode() { return action.getPatchMode(); } 40 | @Override public String getPatchesPrefix() { return action.getPatchesPrefix(); } 41 | @Override public boolean isVerbose() { return action.isVerbose(); } 42 | @Override public boolean isPrintSummary() { return action.isPrintSummary(); } 43 | @Override public boolean isFailOnError() { return action.isFailOnError(); } 44 | @Override public void setBase(Object base) { action.setBase(base); } 45 | @Override public void setPatches(Object patches) { action.setPatches(patches); } 46 | @Override public void setOutput(Object output) { action.setOutput(output); } 47 | @Override public void setRejects(Object rejects) { action.setRejects(rejects); } 48 | @Override public void setOutputFormat(Object outputFormat) { action.setOutputFormat(outputFormat); } 49 | @Override public void setRejectsFormat(Object rejectsFormat) { action.setRejectsFormat(rejectsFormat); } 50 | @Override public void setMinFuzzQuality(float fuzz) { action.setMinFuzzQuality(fuzz); } 51 | @Override public void setMaxFuzzOffset(int maxFuzzOffset) { action.setMaxFuzzOffset(maxFuzzOffset); } 52 | @Override public void setPatchMode(Object patchMode) { action.setPatchMode(patchMode); } 53 | @Override public void setPatchesPrefix(String prefix) { action.setPatchesPrefix(prefix); } 54 | @Override public void setVerbose(boolean verbose) { action.setVerbose(verbose); } 55 | @Override public void setPrintSummary(boolean printSummary) { action.setPrintSummary(printSummary); } 56 | @Override public void setFailOnError(boolean failOnError) { action.setFailOnError(failOnError); } 57 | //@formatter:on 58 | } 59 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto init 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto init 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :init 68 | @rem Get command-line arguments, handling Windows variants 69 | 70 | if not "%OS%" == "Windows_NT" goto win9xME_args 71 | 72 | :win9xME_args 73 | @rem Slurp the command line arguments. 74 | set CMD_LINE_ARGS= 75 | set _SKIP=2 76 | 77 | :win9xME_args_slurp 78 | if "x%~1" == "x" goto execute 79 | 80 | set CMD_LINE_ARGS=%* 81 | 82 | :execute 83 | @rem Setup the command line 84 | 85 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 86 | 87 | 88 | @rem Execute Gradle 89 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 90 | 91 | :end 92 | @rem End local scope for the variables with windows NT shell 93 | if "%ERRORLEVEL%"=="0" goto mainEnd 94 | 95 | :fail 96 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 97 | rem the _cmd.exe /c_ return code! 98 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 99 | exit /b 1 100 | 101 | :mainEnd 102 | if "%OS%"=="Windows_NT" endlocal 103 | 104 | :omega 105 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/diff/DiffSpec.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.diff; 2 | 3 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * Created by covers1624 on 14/8/20. 9 | */ 10 | public interface DiffSpec { 11 | 12 | /** 13 | * Gets the base file path for the diff operation. 14 | * 15 | * @return The path. 16 | */ 17 | File getBase(); 18 | 19 | /** 20 | * Gets the modified file path for the diff operation. 21 | * 22 | * @return The path. 23 | */ 24 | File getModified(); 25 | 26 | /** 27 | * Gets the patch output path. 28 | * 29 | * @return The path. 30 | */ 31 | File getOutput(); 32 | 33 | /** 34 | * Gets the ArchiveFormat to write patches into.l 35 | * 36 | * @return The format. 37 | */ 38 | ArchiveFormat getOutputFormat(); 39 | 40 | /** 41 | * If the Differ will generate patches including an automatic header, 42 | * Substituting start2 in the hunk header with _ 43 | * 44 | * @return If AutoHeader is enabled. 45 | */ 46 | boolean isAutoHeader(); 47 | 48 | /** 49 | * The number of context lines to generate in a patch file. 50 | * 51 | * @return The number of lines. 52 | */ 53 | int getContextLines(); 54 | 55 | /** 56 | * @return If verbose information will be printed or not. 57 | */ 58 | boolean isVerbose(); 59 | 60 | boolean isPrintSummary(); 61 | 62 | /** 63 | * Set the base file path for the diff operation. 64 | * Can be a File, Supplier, Closure, String. 65 | * A Supplier or Closure will be evaluated at task execution. 66 | * 67 | * @param base The path. 68 | */ 69 | void setBase(Object base); 70 | 71 | /** 72 | * Set the modified file path for the diff operation. 73 | * Can be a File, Supplier, Closure, String. 74 | * A Supplier or Closure will be evaluated at task execution. 75 | * 76 | * @param modified The path. 77 | */ 78 | void setModified(Object modified); 79 | 80 | /** 81 | * Set the patches output path. 82 | * Can be a File, Supplier, Closure, String. 83 | * A Supplier or Closure will be evaluated at task execution. 84 | * 85 | * @param patches The path. 86 | */ 87 | void setOutput(Object patches); 88 | 89 | /** 90 | * Sets the format for the patches output. 91 | * Can be a {@link ArchiveFormat} or a string 92 | * representing one of its values. 93 | * 94 | * @param format The format. 95 | */ 96 | void setOutputFormat(Object format); 97 | 98 | /** 99 | * Sets whether AutoHeaders are enabled or not. 100 | * 101 | * @param autoHeader The state. 102 | */ 103 | void setAutoHeader(boolean autoHeader); 104 | 105 | /** 106 | * Sets the number of context lines to generate in patches. 107 | * 108 | * @param lines The number of lines. 109 | */ 110 | void setContextLines(int lines); 111 | 112 | /** 113 | * Sets whether the Diff operation will print verbose 114 | * information or not. 115 | * 116 | * @param verbose The state. 117 | */ 118 | void setVerbose(boolean verbose); 119 | 120 | void setPrintSummary(boolean printSummary); 121 | 122 | //Groovy magic overloads. 123 | //@formatter:off 124 | default void base(Object base) { setBase(base); } 125 | default void modified(Object modified) { setModified(modified); } 126 | default void output(Object output) { setOutput(output); } 127 | default void outputFormat(Object format) { setOutputFormat(format); } 128 | default void autoHeader(boolean autoHeader) { setAutoHeader(autoHeader); } 129 | default void contextLines(int lines) { setContextLines(lines); } 130 | default void verbose(boolean quiet) { setVerbose(quiet); } 131 | default void printSummary(boolean quiet) { setPrintSummary(quiet); } 132 | //@formatter:on 133 | } 134 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/diff/DiffAction.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.diff; 2 | 3 | import codechicken.diffpatch.DiffPatch; 4 | import codechicken.diffpatch.gradle.util.ConsumingOutputStream; 5 | import codechicken.diffpatch.gradle.util.Utils; 6 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 7 | import org.gradle.api.Project; 8 | 9 | import java.io.File; 10 | import java.io.IOException; 11 | import java.io.PrintStream; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * Executes a Diff operation with DiffPatch. 18 | * 19 | * @see DiffSpec 20 | * Created by covers1624 on 14/8/20. 21 | */ 22 | public class DiffAction implements DiffSpec { 23 | 24 | private final boolean DEBUG = Boolean.getBoolean("codechicken.diffpatch.gradle.debug"); 25 | 26 | private final Project project; 27 | 28 | private Object base; 29 | private Object modified; 30 | private Object output; 31 | private Object outputFormat; 32 | private boolean autoHeader; 33 | private int contextLines = -1; 34 | private boolean verbose = true; 35 | private boolean printSummary = true; 36 | 37 | public DiffAction(Project project) { 38 | this.project = project; 39 | } 40 | 41 | public void execute() { 42 | if (base == null) { 43 | throw new IllegalStateException("Base path not specified."); 44 | } 45 | if (modified == null) { 46 | throw new IllegalStateException("Modified path not specified."); 47 | } 48 | if (output == null) { 49 | throw new IllegalStateException("Output path not specified."); 50 | } 51 | 52 | File base = getBase(); 53 | File modified = getModified(); 54 | File output = getOutput(); 55 | ArchiveFormat outputFormat = getOutputFormat(); 56 | int contextLines = getContextLines(); 57 | 58 | List args = new ArrayList<>(); 59 | args.add("-d"); 60 | if (isAutoHeader()) { 61 | args.add("--auto-header"); 62 | } 63 | if (contextLines != -1) { 64 | args.add("--context"); 65 | args.add(String.valueOf(contextLines)); 66 | } 67 | if (isVerbose()) { 68 | args.add("--verbose"); 69 | } 70 | if (isPrintSummary()) { 71 | args.add("--summary"); 72 | } 73 | args.add("--output"); 74 | args.add(output.getAbsolutePath()); 75 | if (outputFormat != null) { 76 | args.add("--archive"); 77 | args.add(outputFormat.name()); 78 | } 79 | args.add(base.getAbsolutePath()); 80 | args.add(modified.getAbsolutePath()); 81 | 82 | if (DEBUG) { 83 | String line = args.stream().map(e -> "\"" + e + "\"").collect(Collectors.joining(" ")); 84 | project.getLogger().info("Starting DiffPatch with arguments: {}", line); 85 | } 86 | 87 | PrintStream logger = new PrintStream(new ConsumingOutputStream(line -> project.getLogger().lifecycle(line))); 88 | int exit = 0; 89 | try { 90 | exit = DiffPatch.mainI(args.toArray(new String[0]), logger, null); 91 | } catch (IOException e) { 92 | codechicken.diffpatch.util.Utils.throwUnchecked(e); 93 | } 94 | if (exit != 0 && exit != 1) { 95 | throw new RuntimeException("DiffPatch failed with exit code: " + exit); 96 | } 97 | } 98 | 99 | //@formatter:off 100 | @Override public File getBase() { return base != null ? Utils.resolveFile(project, base) : null; } 101 | @Override public File getModified() { return modified != null ? Utils.resolveFile(project, modified) : null; } 102 | @Override public File getOutput() { return output != null ? Utils.resolveFile(project, output) : null; } 103 | @Override public ArchiveFormat getOutputFormat() { return outputFormat != null ? Utils.resolveArchiveFormat(outputFormat) : null; } 104 | @Override public boolean isAutoHeader() { return autoHeader; } 105 | @Override public int getContextLines() { return contextLines; } 106 | @Override public boolean isVerbose() { return verbose; } 107 | @Override public boolean isPrintSummary() { return printSummary; } 108 | @Override public void setBase(Object base) { this.base = base; } 109 | @Override public void setModified(Object modified) { this.modified = modified; } 110 | @Override public void setOutput(Object patches) { this.output = patches; } 111 | @Override public void setOutputFormat(Object format) { this.outputFormat = format; } 112 | @Override public void setAutoHeader(boolean autoHeader) { this.autoHeader = autoHeader; } 113 | @Override public void setContextLines(int lines) { this.contextLines = lines; } 114 | @Override public void setVerbose(boolean verbose) { this.verbose = verbose; } 115 | @Override public void setPrintSummary(boolean printSummary) { this.printSummary = printSummary; } 116 | //@formatter:on 117 | } 118 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | 86 | # Determine the Java command to use to start the JVM. 87 | if [ -n "$JAVA_HOME" ] ; then 88 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 89 | # IBM's JDK on AIX uses strange locations for the executables 90 | JAVACMD="$JAVA_HOME/jre/sh/java" 91 | else 92 | JAVACMD="$JAVA_HOME/bin/java" 93 | fi 94 | if [ ! -x "$JAVACMD" ] ; then 95 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 96 | 97 | Please set the JAVA_HOME variable in your environment to match the 98 | location of your Java installation." 99 | fi 100 | else 101 | JAVACMD="java" 102 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 103 | 104 | Please set the JAVA_HOME variable in your environment to match the 105 | location of your Java installation." 106 | fi 107 | 108 | # Increase the maximum file descriptors if we can. 109 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 110 | MAX_FD_LIMIT=`ulimit -H -n` 111 | if [ $? -eq 0 ] ; then 112 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 113 | MAX_FD="$MAX_FD_LIMIT" 114 | fi 115 | ulimit -n $MAX_FD 116 | if [ $? -ne 0 ] ; then 117 | warn "Could not set maximum file descriptor limit: $MAX_FD" 118 | fi 119 | else 120 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 121 | fi 122 | fi 123 | 124 | # For Darwin, add options to specify how the application appears in the dock 125 | if $darwin; then 126 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 127 | fi 128 | 129 | # For Cygwin or MSYS, switch paths to Windows format before running java 130 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then 131 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 132 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 133 | 134 | JAVACMD=`cygpath --unix "$JAVACMD"` 135 | 136 | # We build the pattern for arguments to be converted via cygpath 137 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 138 | SEP="" 139 | for dir in $ROOTDIRSRAW ; do 140 | ROOTDIRS="$ROOTDIRS$SEP$dir" 141 | SEP="|" 142 | done 143 | OURCYGPATTERN="(^($ROOTDIRS))" 144 | # Add a user-defined pattern to the cygpath arguments 145 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 146 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 147 | fi 148 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 149 | i=0 150 | for arg in "$@" ; do 151 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 152 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 153 | 154 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 155 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 156 | else 157 | eval `echo args$i`="\"$arg\"" 158 | fi 159 | i=`expr $i + 1` 160 | done 161 | case $i in 162 | 0) set -- ;; 163 | 1) set -- "$args0" ;; 164 | 2) set -- "$args0" "$args1" ;; 165 | 3) set -- "$args0" "$args1" "$args2" ;; 166 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; 167 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 168 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 169 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 170 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 171 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 172 | esac 173 | fi 174 | 175 | # Escape application args 176 | save () { 177 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 178 | echo " " 179 | } 180 | APP_ARGS=`save "$@"` 181 | 182 | # Collect all arguments for the java command, following the shell quoting and substitution rules 183 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 184 | 185 | exec "$JAVACMD" "$@" 186 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/patch/PatchAction.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.patch; 2 | 3 | import codechicken.diffpatch.DiffPatch; 4 | import codechicken.diffpatch.gradle.util.ConsumingOutputStream; 5 | import codechicken.diffpatch.gradle.util.Utils; 6 | import codechicken.diffpatch.util.PatchMode; 7 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 8 | import org.gradle.api.Project; 9 | 10 | import java.io.File; 11 | import java.io.IOException; 12 | import java.io.PrintStream; 13 | import java.util.ArrayList; 14 | import java.util.List; 15 | import java.util.stream.Collectors; 16 | 17 | /** 18 | * Executes a Patch operation with DiffPatch. 19 | * 20 | * @see PatchSpec 21 | * Created by covers1624 on 14/8/20. 22 | */ 23 | public class PatchAction implements PatchSpec { 24 | 25 | private final boolean DEBUG = Boolean.getBoolean("codechicken.diffpatch.gradle.debug"); 26 | 27 | private final Project project; 28 | 29 | private Object base; 30 | private Object patches; 31 | private Object output; 32 | private Object rejects; 33 | private Object outputFormat; 34 | private Object rejectsFormat; 35 | private float minFuzzQuality = -1; 36 | private int maxFuzzOffset = -1; 37 | private Object patchMode = PatchMode.EXACT; 38 | private String patchesPrefix; 39 | private boolean verbose = false; 40 | private boolean printSummary = true; 41 | private boolean failOnError = true; 42 | 43 | public PatchAction(Project project) { 44 | this.project = project; 45 | } 46 | 47 | public int execute() { 48 | if (base == null) { 49 | throw new IllegalStateException("Base path not specified."); 50 | } 51 | if (patches == null) { 52 | throw new IllegalStateException("Patches path not specified."); 53 | } 54 | if (output == null) { 55 | throw new IllegalStateException("Output path not specified."); 56 | } 57 | 58 | File base = getBase(); 59 | File patches = getPatches(); 60 | File output = getOutput(); 61 | File rejects = getRejects(); 62 | ArchiveFormat outputFormat = getOutputFormat(); 63 | ArchiveFormat rejectsFormat = getRejectsFormat(); 64 | float minFuzz = getMinFuzzQuality(); 65 | int maxOffset = getMaxFuzzOffset(); 66 | PatchMode mode = getPatchMode(); 67 | 68 | List args = new ArrayList<>(); 69 | args.add("-p"); 70 | if (minFuzz != -1) { 71 | args.add("--fuzz"); 72 | args.add(String.valueOf(minFuzz)); 73 | } 74 | if (maxOffset != -1) { 75 | args.add("--offset"); 76 | args.add(String.valueOf(maxOffset)); 77 | } 78 | if (isVerbose()) { 79 | args.add("--verbose"); 80 | } 81 | if (isPrintSummary()) { 82 | args.add("--summary"); 83 | } 84 | args.add("--output"); 85 | args.add(output.getAbsolutePath()); 86 | if (outputFormat != null) { 87 | args.add("--archive"); 88 | args.add(outputFormat.name()); 89 | } 90 | if (mode != null) { 91 | args.add("--mode"); 92 | args.add(mode.name()); 93 | } 94 | if (patchesPrefix != null) { 95 | args.add("--prefix"); 96 | args.add(patchesPrefix); 97 | } 98 | if (rejects != null) { 99 | args.add("--reject"); 100 | args.add(rejects.getAbsolutePath()); 101 | if (rejectsFormat != null) { 102 | args.add("--archive-rejects"); 103 | args.add(rejectsFormat.name()); 104 | } 105 | } 106 | args.add(base.getAbsolutePath()); 107 | args.add(patches.getAbsolutePath()); 108 | 109 | if (DEBUG) { 110 | String line = args.stream().map(e -> "\"" + e + "\"").collect(Collectors.joining(" ")); 111 | project.getLogger().info("Starting DiffPatch with arguments: {}", line); 112 | } 113 | 114 | PrintStream logger = new PrintStream(new ConsumingOutputStream(line -> project.getLogger().lifecycle(line))); 115 | int exit = 0; 116 | try { 117 | exit = DiffPatch.mainI(args.toArray(new String[0]), logger, null); 118 | } catch (IOException e) { 119 | codechicken.diffpatch.util.Utils.throwUnchecked(e); 120 | } 121 | if (exit != 0 && exit != 1) { 122 | throw new RuntimeException("DiffPatch failed with exit code: " + exit); 123 | } 124 | if (exit != 0 && isFailOnError()) { 125 | throw new RuntimeException("Patches failed to apply."); 126 | } 127 | return exit; 128 | } 129 | 130 | //@formatter:off 131 | @Override public File getBase() { return base != null ? Utils.resolveFile(project, base) : null; } 132 | @Override public File getPatches() { return patches != null ? Utils.resolveFile(project, patches) : null; } 133 | @Override public File getOutput() { return output != null ? Utils.resolveFile(project, output) : null; } 134 | @Override public File getRejects() { return rejects != null ? Utils.resolveFile(project, rejects) : null; } 135 | @Override public ArchiveFormat getOutputFormat() { return outputFormat != null ? Utils.resolveArchiveFormat(outputFormat) : null; } 136 | @Override public ArchiveFormat getRejectsFormat() { return rejectsFormat != null ? Utils.resolveArchiveFormat(rejectsFormat) : null; } 137 | @Override public float getMinFuzzQuality() { return minFuzzQuality; } 138 | @Override public int getMaxFuzzOffset() { return maxFuzzOffset; } 139 | @Override public PatchMode getPatchMode() { return Utils.resolvePatchMode(patchMode); } 140 | @Override public String getPatchesPrefix() { return patchesPrefix; } 141 | @Override public boolean isVerbose() { return verbose; } 142 | @Override public boolean isPrintSummary() { return printSummary; } 143 | @Override public boolean isFailOnError() { return failOnError; } 144 | @Override public void setBase(Object base) { this.base = base; } 145 | @Override public void setPatches(Object patches) { this.patches = patches; } 146 | @Override public void setOutput(Object output) { this.output = output; } 147 | @Override public void setRejects(Object rejects) { this.rejects = rejects; } 148 | @Override public void setOutputFormat(Object outputFormat) { this.outputFormat = outputFormat; } 149 | @Override public void setRejectsFormat(Object rejectsFormat) { this.rejectsFormat = rejectsFormat; } 150 | @Override public void setMinFuzzQuality(float minFuzzQuality) { this.minFuzzQuality = minFuzzQuality; } 151 | @Override public void setMaxFuzzOffset(int maxFuzzOffset) { this.maxFuzzOffset = maxFuzzOffset; } 152 | @Override public void setPatchMode(Object patchMode) { this.patchMode = patchMode; } 153 | @Override public void setPatchesPrefix(String patchesPrefix) { this.patchesPrefix = patchesPrefix; } 154 | @Override public void setVerbose(boolean verbose) { this.verbose = verbose; } 155 | @Override public void setPrintSummary(boolean printSummary) { this.printSummary = printSummary; } 156 | @Override public void setFailOnError(boolean failOnError) { this.failOnError = failOnError; } 157 | //@formatter:on 158 | } 159 | -------------------------------------------------------------------------------- /src/main/java/codechicken/diffpatch/gradle/patch/PatchSpec.java: -------------------------------------------------------------------------------- 1 | package codechicken.diffpatch.gradle.patch; 2 | 3 | import codechicken.diffpatch.util.PatchMode; 4 | import codechicken.diffpatch.util.archiver.ArchiveFormat; 5 | 6 | import java.io.File; 7 | 8 | /** 9 | * Created by covers1624 on 14/8/20. 10 | */ 11 | public interface PatchSpec { 12 | 13 | /** 14 | * Gets the base path to be patched. 15 | * 16 | * @return The base files. 17 | */ 18 | File getBase(); 19 | 20 | /** 21 | * Gets the patches to apply. 22 | * 23 | * @return The patch files. 24 | */ 25 | File getPatches(); 26 | 27 | /** 28 | * Gets the output path. 29 | * 30 | * @return The output location. 31 | */ 32 | File getOutput(); 33 | 34 | /** 35 | * Gets the path to save patch rejects. 36 | * 37 | * @return The reject location. 38 | */ 39 | File getRejects(); 40 | 41 | /** 42 | * Gets the {@link ArchiveFormat} to save the Output in. 43 | * Can be a {@link ArchiveFormat} or a string 44 | * representing one of its values. 45 | * 46 | * @return The format. 47 | */ 48 | ArchiveFormat getOutputFormat(); 49 | 50 | /** 51 | * Gets the {@link ArchiveFormat} to save rejects in. 52 | * Can be a {@link ArchiveFormat} or a string 53 | * representing one of its values. 54 | * 55 | * @return The format. 56 | */ 57 | ArchiveFormat getRejectsFormat(); 58 | 59 | /** 60 | * The minimum quality of a fuzzy match for DiffPatch to consider 61 | * successful. 62 | * 63 | * @return The quality. 64 | */ 65 | float getMinFuzzQuality(); 66 | 67 | /** 68 | * The maximum number of lines DiffPatch is allowed to wander 69 | * from the hunk target for a fuzzy patch. 70 | * 71 | * @return The number of lines. 72 | */ 73 | int getMaxFuzzOffset(); 74 | 75 | /** 76 | * The mode for this patching operation. 77 | * 78 | * @return The mode. 79 | */ 80 | PatchMode getPatchMode(); 81 | 82 | /** 83 | * A prefix DiffPatch will apply to the patches input. 84 | * Useful for reading patches out of a sub-directory of a zip. 85 | * 86 | * @return The offset. 87 | */ 88 | String getPatchesPrefix(); 89 | 90 | /** 91 | * @return If verbose output is enabled. 92 | */ 93 | boolean isVerbose(); 94 | 95 | /** 96 | * @return If summary output is enabled. 97 | */ 98 | boolean isPrintSummary(); 99 | 100 | /** 101 | * If the task should fail when patches fail to apply. 102 | * In some use cases it might be okay for patches to fail, 103 | * and let the rest of the build process continue. 104 | * Only patch rejects or missing files are considered failures. 105 | * 106 | * @return If the task should fail patches failing. 107 | */ 108 | boolean isFailOnError(); 109 | 110 | /** 111 | * Sets the base path to patch. 112 | * Can be a File, Supplier, Closure, String. 113 | * A Supplier or Closure will be evaluated at task execution. 114 | * 115 | * @param base The base path. 116 | */ 117 | void setBase(Object base); 118 | 119 | /** 120 | * Sets the location to patch from. 121 | * Can be a File, Supplier, Closure, String. 122 | * A Supplier or Closure will be evaluated at task execution. 123 | * 124 | * @param patches The patches path. 125 | */ 126 | void setPatches(Object patches); 127 | 128 | /** 129 | * Sets the location to output patched files. 130 | * Can be a File, Supplier, Closure, String. 131 | * A Supplier or Closure will be evaluated at task execution. 132 | * 133 | * @param output The output path. 134 | */ 135 | void setOutput(Object output); 136 | 137 | /** 138 | * Sets the location to output reject files. 139 | * Can be a File, Supplier, Closure, String. 140 | * A Supplier or Closure will be evaluated at task execution. 141 | * 142 | * @param rejects The rejects path. 143 | */ 144 | void setRejects(Object rejects); 145 | 146 | /** 147 | * Sets the format for the patched output. 148 | * Can be a {@link ArchiveFormat} or a string 149 | * representing one of its values. 150 | * 151 | * @param outputFormat The format. 152 | */ 153 | void setOutputFormat(Object outputFormat); 154 | 155 | /** 156 | * Sets the format for the rejects output. 157 | * Can be a {@link ArchiveFormat} or a string 158 | * representing one of its values. 159 | * 160 | * @param rejectsFormat The format. 161 | */ 162 | void setRejectsFormat(Object rejectsFormat); 163 | 164 | /** 165 | * The minimum quality of a fuzzy match for DiffPatch to consider 166 | * successful. 167 | * 168 | * @param fuzz The quality, [0-1] 169 | */ 170 | void setMinFuzzQuality(float fuzz); 171 | 172 | /** 173 | * Sets the maximum number of lines DiffPatch is allowed to wander 174 | * from the hunk target for a fuzzy patch. 175 | * 176 | * @param maxFuzzOffset The number of lines. 177 | */ 178 | void setMaxFuzzOffset(int maxFuzzOffset); 179 | 180 | /** 181 | * Sets the PatchMode to apply in. 182 | * May be a {@link PatchMode} or a string 183 | * representing one of its values. 184 | * 185 | * @param patchMode The mode. 186 | */ 187 | void setPatchMode(Object patchMode); 188 | 189 | /** 190 | * Sets the prefix DiffPatch will apply to the patches input. 191 | * Useful for reading patches out of a sub-directory of a zip. 192 | * 193 | * @param prefix The prefix. 194 | */ 195 | void setPatchesPrefix(String prefix); 196 | 197 | /** 198 | * If verbose output is enabled. 199 | * 200 | * @param verbose The value. 201 | */ 202 | void setVerbose(boolean verbose); 203 | 204 | /** 205 | * If summary output is enabled. 206 | * 207 | * @param printSummary The value. 208 | */ 209 | void setPrintSummary(boolean printSummary); 210 | 211 | /** 212 | * Sets if the task should fail when patches fail to apply. 213 | * In some use cases it might be okay for patches to fail, 214 | * and let the rest of the build process continue. 215 | * Only patch rejects or missing files are considered failures. 216 | * 217 | * @param failOnError The value. 218 | */ 219 | void setFailOnError(boolean failOnError); 220 | 221 | //Groovy magic overloads. 222 | //@formatter:off 223 | default void base(Object base) { setBase(base); } 224 | default void patches(Object patches) { setPatches(patches); } 225 | default void output(Object output) { setOutput(output); } 226 | default void rejects(Object rejects) { setRejects(rejects); } 227 | default void outputFormat(Object outputFormat) { setOutputFormat(outputFormat); } 228 | default void rejectsFormat(Object rejectsFormat) { setRejectsFormat(rejectsFormat); } 229 | default void minFuzzQuality(float fuzzQuality) { setMinFuzzQuality(fuzzQuality); } 230 | default void maxFuzzOffset(int maxOffset) { setMaxFuzzOffset(maxOffset); } 231 | default void patchMode(Object patchMode) { setPatchMode(patchMode); } 232 | default void patchesPrefix(String prefix) { setPatchesPrefix(prefix); } 233 | default void verbose(boolean verbose) { setVerbose(verbose); } 234 | default void printSummary(boolean printSummary) { setPrintSummary(printSummary); } 235 | default void failOnError(boolean failOnError) { setFailOnError(failOnError); } 236 | //@formatter:on 237 | } 238 | --------------------------------------------------------------------------------