1 | NO CONTENT: new file 100644 |
|
NO CONTENT: new file 100644 |
@@ -0,0 +1,183 | |||||
|
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 | # Determine the Java command to use to start the JVM. | |||
|
86 | if [ -n "$JAVA_HOME" ] ; then | |||
|
87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then | |||
|
88 | # IBM's JDK on AIX uses strange locations for the executables | |||
|
89 | JAVACMD="$JAVA_HOME/jre/sh/java" | |||
|
90 | else | |||
|
91 | JAVACMD="$JAVA_HOME/bin/java" | |||
|
92 | fi | |||
|
93 | if [ ! -x "$JAVACMD" ] ; then | |||
|
94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME | |||
|
95 | ||||
|
96 | Please set the JAVA_HOME variable in your environment to match the | |||
|
97 | location of your Java installation." | |||
|
98 | fi | |||
|
99 | else | |||
|
100 | JAVACMD="java" | |||
|
101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |||
|
102 | ||||
|
103 | Please set the JAVA_HOME variable in your environment to match the | |||
|
104 | location of your Java installation." | |||
|
105 | fi | |||
|
106 | ||||
|
107 | # Increase the maximum file descriptors if we can. | |||
|
108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then | |||
|
109 | MAX_FD_LIMIT=`ulimit -H -n` | |||
|
110 | if [ $? -eq 0 ] ; then | |||
|
111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then | |||
|
112 | MAX_FD="$MAX_FD_LIMIT" | |||
|
113 | fi | |||
|
114 | ulimit -n $MAX_FD | |||
|
115 | if [ $? -ne 0 ] ; then | |||
|
116 | warn "Could not set maximum file descriptor limit: $MAX_FD" | |||
|
117 | fi | |||
|
118 | else | |||
|
119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" | |||
|
120 | fi | |||
|
121 | fi | |||
|
122 | ||||
|
123 | # For Darwin, add options to specify how the application appears in the dock | |||
|
124 | if $darwin; then | |||
|
125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" | |||
|
126 | fi | |||
|
127 | ||||
|
128 | # For Cygwin or MSYS, switch paths to Windows format before running java | |||
|
129 | if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then | |||
|
130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` | |||
|
131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` | |||
|
132 | JAVACMD=`cygpath --unix "$JAVACMD"` | |||
|
133 | ||||
|
134 | # We build the pattern for arguments to be converted via cygpath | |||
|
135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` | |||
|
136 | SEP="" | |||
|
137 | for dir in $ROOTDIRSRAW ; do | |||
|
138 | ROOTDIRS="$ROOTDIRS$SEP$dir" | |||
|
139 | SEP="|" | |||
|
140 | done | |||
|
141 | OURCYGPATTERN="(^($ROOTDIRS))" | |||
|
142 | # Add a user-defined pattern to the cygpath arguments | |||
|
143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then | |||
|
144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" | |||
|
145 | fi | |||
|
146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh | |||
|
147 | i=0 | |||
|
148 | for arg in "$@" ; do | |||
|
149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` | |||
|
150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option | |||
|
151 | ||||
|
152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition | |||
|
153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` | |||
|
154 | else | |||
|
155 | eval `echo args$i`="\"$arg\"" | |||
|
156 | fi | |||
|
157 | i=`expr $i + 1` | |||
|
158 | done | |||
|
159 | case $i in | |||
|
160 | 0) set -- ;; | |||
|
161 | 1) set -- "$args0" ;; | |||
|
162 | 2) set -- "$args0" "$args1" ;; | |||
|
163 | 3) set -- "$args0" "$args1" "$args2" ;; | |||
|
164 | 4) set -- "$args0" "$args1" "$args2" "$args3" ;; | |||
|
165 | 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; | |||
|
166 | 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; | |||
|
167 | 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; | |||
|
168 | 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; | |||
|
169 | 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; | |||
|
170 | esac | |||
|
171 | fi | |||
|
172 | ||||
|
173 | # Escape application args | |||
|
174 | save () { | |||
|
175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done | |||
|
176 | echo " " | |||
|
177 | } | |||
|
178 | APP_ARGS=`save "$@"` | |||
|
179 | ||||
|
180 | # Collect all arguments for the java command, following the shell quoting and substitution rules | |||
|
181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" | |||
|
182 | ||||
|
183 | exec "$JAVACMD" "$@" |
@@ -0,0 +1,100 | |||||
|
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 Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | |||
|
33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" | |||
|
34 | ||||
|
35 | @rem Find java.exe | |||
|
36 | if defined JAVA_HOME goto findJavaFromJavaHome | |||
|
37 | ||||
|
38 | set JAVA_EXE=java.exe | |||
|
39 | %JAVA_EXE% -version >NUL 2>&1 | |||
|
40 | if "%ERRORLEVEL%" == "0" goto init | |||
|
41 | ||||
|
42 | echo. | |||
|
43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. | |||
|
44 | echo. | |||
|
45 | echo Please set the JAVA_HOME variable in your environment to match the | |||
|
46 | echo location of your Java installation. | |||
|
47 | ||||
|
48 | goto fail | |||
|
49 | ||||
|
50 | :findJavaFromJavaHome | |||
|
51 | set JAVA_HOME=%JAVA_HOME:"=% | |||
|
52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe | |||
|
53 | ||||
|
54 | if exist "%JAVA_EXE%" goto init | |||
|
55 | ||||
|
56 | echo. | |||
|
57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% | |||
|
58 | echo. | |||
|
59 | echo Please set the JAVA_HOME variable in your environment to match the | |||
|
60 | echo location of your Java installation. | |||
|
61 | ||||
|
62 | goto fail | |||
|
63 | ||||
|
64 | :init | |||
|
65 | @rem Get command-line arguments, handling Windows variants | |||
|
66 | ||||
|
67 | if not "%OS%" == "Windows_NT" goto win9xME_args | |||
|
68 | ||||
|
69 | :win9xME_args | |||
|
70 | @rem Slurp the command line arguments. | |||
|
71 | set CMD_LINE_ARGS= | |||
|
72 | set _SKIP=2 | |||
|
73 | ||||
|
74 | :win9xME_args_slurp | |||
|
75 | if "x%~1" == "x" goto execute | |||
|
76 | ||||
|
77 | set CMD_LINE_ARGS=%* | |||
|
78 | ||||
|
79 | :execute | |||
|
80 | @rem Setup the command line | |||
|
81 | ||||
|
82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar | |||
|
83 | ||||
|
84 | @rem Execute Gradle | |||
|
85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% | |||
|
86 | ||||
|
87 | :end | |||
|
88 | @rem End local scope for the variables with windows NT shell | |||
|
89 | if "%ERRORLEVEL%"=="0" goto mainEnd | |||
|
90 | ||||
|
91 | :fail | |||
|
92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of | |||
|
93 | rem the _cmd.exe /c_ return code! | |||
|
94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 | |||
|
95 | exit /b 1 | |||
|
96 | ||||
|
97 | :mainEnd | |||
|
98 | if "%OS%"=="Windows_NT" endlocal | |||
|
99 | ||||
|
100 | :omega |
@@ -0,0 +1,17 | |||||
|
1 | plugins { | |||
|
2 | id "java-gradle-plugin" | |||
|
3 | } | |||
|
4 | ||||
|
5 | ||||
|
6 | repositories { | |||
|
7 | mavenCentral() | |||
|
8 | } | |||
|
9 | ||||
|
10 | gradlePlugin { | |||
|
11 | plugins { | |||
|
12 | containerPlugin { | |||
|
13 | id = 'org.implab.gradle-mercurial' | |||
|
14 | implementationClass = 'org.implab.gradle.mercurial.MercurialPlugin' | |||
|
15 | } | |||
|
16 | } | |||
|
17 | } |
@@ -0,0 +1,108 | |||||
|
1 | package org.implab.gradle; | |||
|
2 | ||||
|
3 | import java.io.ByteArrayOutputStream; | |||
|
4 | import java.io.Closeable; | |||
|
5 | import java.io.File; | |||
|
6 | import java.io.FileOutputStream; | |||
|
7 | import java.io.IOException; | |||
|
8 | import java.io.InputStream; | |||
|
9 | import java.io.OutputStream; | |||
|
10 | import java.util.List; | |||
|
11 | import java.util.Scanner; | |||
|
12 | ||||
|
13 | import org.gradle.api.Action; | |||
|
14 | import groovy.json.JsonGenerator; | |||
|
15 | import groovy.json.JsonOutput; | |||
|
16 | import groovy.json.JsonGenerator.Converter; | |||
|
17 | import groovy.lang.Closure; | |||
|
18 | ||||
|
19 | public final class Utils { | |||
|
20 | public static void redirectIO(final InputStream src, final Action<String> consumer) { | |||
|
21 | new Thread(() -> { | |||
|
22 | try (Scanner sc = new Scanner(src)) { | |||
|
23 | while (sc.hasNextLine()) { | |||
|
24 | consumer.execute(sc.nextLine()); | |||
|
25 | } | |||
|
26 | } | |||
|
27 | }).start(); | |||
|
28 | } | |||
|
29 | ||||
|
30 | public static String execCmd(List<String> args, String charset) throws IOException, InterruptedException, Exception { | |||
|
31 | if (args == null || args.size() == 0) | |||
|
32 | throw new IllegalArgumentException(); | |||
|
33 | ||||
|
34 | ProcessBuilder builder = new ProcessBuilder(args); | |||
|
35 | ||||
|
36 | Process p = builder.start(); | |||
|
37 | ||||
|
38 | String output = readAll(p.getInputStream(), charset); | |||
|
39 | ||||
|
40 | int code = p.waitFor(); | |||
|
41 | if (code != 0) | |||
|
42 | throw new Exception(String.format("The process `%s` failed with code: %s", args.get(0), code)); | |||
|
43 | ||||
|
44 | return output; | |||
|
45 | ||||
|
46 | } | |||
|
47 | ||||
|
48 | public static void redirectIO(final InputStream src, final File file) { | |||
|
49 | new Thread(() -> { | |||
|
50 | try (OutputStream out = new FileOutputStream(file)) { | |||
|
51 | src.transferTo(out); | |||
|
52 | } catch(Exception e) { | |||
|
53 | // silence! | |||
|
54 | } | |||
|
55 | }).start(); | |||
|
56 | } | |||
|
57 | ||||
|
58 | public static String readAll(final InputStream src) throws IOException { | |||
|
59 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
|
60 | src.transferTo(out); | |||
|
61 | return out.toString(); | |||
|
62 | } | |||
|
63 | ||||
|
64 | public static String readAll(final InputStream src, String charset) throws IOException { | |||
|
65 | ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
|
66 | src.transferTo(out); | |||
|
67 | return out.toString(charset); | |||
|
68 | } | |||
|
69 | ||||
|
70 | public static JsonGenerator createDefaultJsonGenerator() { | |||
|
71 | return new JsonGenerator.Options() | |||
|
72 | .excludeNulls() | |||
|
73 | .addConverter(new Converter() { | |||
|
74 | public boolean handles(Class<?> type) { | |||
|
75 | return (File.class == type); | |||
|
76 | } | |||
|
77 | public Object convert(Object value, String key) { | |||
|
78 | return ((File)value).getPath(); | |||
|
79 | } | |||
|
80 | }) | |||
|
81 | .build(); | |||
|
82 | } | |||
|
83 | ||||
|
84 | public static void closeSilent(Closeable handle) { | |||
|
85 | try { | |||
|
86 | handle.close(); | |||
|
87 | } catch(Exception e) { | |||
|
88 | // silence! | |||
|
89 | } | |||
|
90 | } | |||
|
91 | ||||
|
92 | public static String toJsonPretty(Object value) { | |||
|
93 | return JsonOutput.prettyPrint(createDefaultJsonGenerator().toJson(value)); | |||
|
94 | } | |||
|
95 | ||||
|
96 | public static boolean isNullOrEmptyString(String value) { | |||
|
97 | return (value == null || value.length() == 0); | |||
|
98 | } | |||
|
99 | ||||
|
100 | public static <T> Action<T> wrapClosure(Closure<?> closure) { | |||
|
101 | return x -> { | |||
|
102 | closure.setDelegate(x); | |||
|
103 | closure.setResolveStrategy(Closure.DELEGATE_FIRST); | |||
|
104 | closure.call(x); | |||
|
105 | }; | |||
|
106 | } | |||
|
107 | ||||
|
108 | } |
@@ -0,0 +1,115 | |||||
|
1 | package org.implab.gradle.mercurial; | |||
|
2 | ||||
|
3 | import java.nio.charset.Charset; | |||
|
4 | import java.util.ArrayList; | |||
|
5 | import java.util.Collections; | |||
|
6 | import java.util.List; | |||
|
7 | import java.util.Objects; | |||
|
8 | import java.util.Optional; | |||
|
9 | import java.util.regex.Matcher; | |||
|
10 | import java.util.regex.Pattern; | |||
|
11 | ||||
|
12 | import org.gradle.api.Project; | |||
|
13 | import org.implab.gradle.Utils; | |||
|
14 | ||||
|
15 | public class MercurialExtension { | |||
|
16 | private static final String COMMIT_INFO_TEMPLATE = "{latesttag('re:^v') % '{ifeq(tag,'null','',tag)}:{distance}'}:{branch}:{node|short}"; | |||
|
17 | ||||
|
18 | private static final Pattern versionPattern = Pattern.compile("^(?:v[\\-_\\.]?)?(.*)"); | |||
|
19 | ||||
|
20 | private final Project project; | |||
|
21 | ||||
|
22 | private Charset outputCharset = Charset.defaultCharset(); | |||
|
23 | ||||
|
24 | private WorkspaceInfo workspaceInfo; | |||
|
25 | ||||
|
26 | private String hgCmd = "hg"; | |||
|
27 | ||||
|
28 | private SemVersion defaultWorkspaceVersion = new SemVersion(0, 0, 1, "dev", null); | |||
|
29 | ||||
|
30 | public MercurialExtension(Project project) { | |||
|
31 | Objects.requireNonNull(project); | |||
|
32 | ||||
|
33 | this.project = project; | |||
|
34 | } | |||
|
35 | ||||
|
36 | public String hg(String... args) throws Exception { | |||
|
37 | List<String> commandLine = new ArrayList<>(); | |||
|
38 | commandLine.add(hgCmd); | |||
|
39 | Collections.addAll(commandLine, args); | |||
|
40 | ||||
|
41 | return Utils.execCmd(commandLine, outputCharset.name()); | |||
|
42 | } | |||
|
43 | ||||
|
44 | public Charset getOutputCharset() { | |||
|
45 | return outputCharset; | |||
|
46 | } | |||
|
47 | ||||
|
48 | public void setOutputCharset(Charset outputCharset) { | |||
|
49 | this.outputCharset = Optional.ofNullable(outputCharset).orElseGet(Charset::defaultCharset); | |||
|
50 | } | |||
|
51 | ||||
|
52 | public void setOutputCharset(String outputCharset) { | |||
|
53 | this.outputCharset = Optional.ofNullable(outputCharset).map(x -> Charset.forName(x)) | |||
|
54 | .orElseGet(Charset::defaultCharset); | |||
|
55 | } | |||
|
56 | ||||
|
57 | public String getHgCmd() { | |||
|
58 | return hgCmd; | |||
|
59 | } | |||
|
60 | ||||
|
61 | public void setHgCmd(String hgCmd) { | |||
|
62 | this.hgCmd = hgCmd; | |||
|
63 | } | |||
|
64 | ||||
|
65 | public WorkspaceInfo getWorkspaceInfo() throws Exception { | |||
|
66 | if (workspaceInfo == null) | |||
|
67 | workspaceInfo = loadWorkspaceInfo(); | |||
|
68 | return workspaceInfo; | |||
|
69 | } | |||
|
70 | ||||
|
71 | public SemVersion getWorkspaceVersion() throws Exception { | |||
|
72 | return tryParseVersion(getWorkspaceInfo().getVersionTag()).orElse(defaultWorkspaceVersion); | |||
|
73 | } | |||
|
74 | ||||
|
75 | public void applyVersioningPolicy() throws Exception { | |||
|
76 | Object version = project.getVersion(); | |||
|
77 | if (version == null || version.toString().isBlank() || version.toString().equalsIgnoreCase(Project.DEFAULT_VERSION)) { | |||
|
78 | int distance = getWorkspaceInfo().getVersionDistance(); | |||
|
79 | String changeset = getWorkspaceInfo().getChangeset(); | |||
|
80 | project.setVersion( | |||
|
81 | distance> 0 ? | |||
|
82 | getWorkspaceVersion().addPatch(distance).suffix("snapshot").meta(changeset) : | |||
|
83 | getWorkspaceVersion() | |||
|
84 | ); | |||
|
85 | } else { | |||
|
86 | project.setVersion(SemVersion.toSemVersion(version, false)); | |||
|
87 | } | |||
|
88 | } | |||
|
89 | ||||
|
90 | String[] queryLogInfo() throws Exception { | |||
|
91 | return hg("log", "-r", ".", "--template", COMMIT_INFO_TEMPLATE).split(":"); | |||
|
92 | } | |||
|
93 | ||||
|
94 | WorkspaceInfo loadWorkspaceInfo() throws Exception { | |||
|
95 | boolean isDirty = checkIsDirty(); | |||
|
96 | String[] info = queryLogInfo(); | |||
|
97 | return new WorkspaceInfo(info[0], Integer.parseInt(info[1]), info[2], info[3], isDirty); | |||
|
98 | } | |||
|
99 | ||||
|
100 | boolean checkIsDirty() throws Exception { | |||
|
101 | return !hg("status", "-mard").isBlank(); | |||
|
102 | } | |||
|
103 | ||||
|
104 | Optional<SemVersion> tryParseVersion(String version) { | |||
|
105 | if (version == null) | |||
|
106 | return Optional.empty(); | |||
|
107 | ||||
|
108 | Matcher m = versionPattern.matcher(version); | |||
|
109 | boolean isMatch = m.matches(); | |||
|
110 | ||||
|
111 | return isMatch ? SemVersion.tryParseLax(m.group(1)) : Optional.empty(); | |||
|
112 | } | |||
|
113 | ||||
|
114 | ||||
|
115 | } |
@@ -0,0 +1,85 | |||||
|
1 | package org.implab.gradle.mercurial; | |||
|
2 | ||||
|
3 | import org.codehaus.groovy.runtime.MethodClosure; | |||
|
4 | import org.gradle.api.Plugin; | |||
|
5 | import org.gradle.api.Project; | |||
|
6 | import org.gradle.api.plugins.ExtraPropertiesExtension; | |||
|
7 | import org.gradle.api.tasks.TaskExecutionException; | |||
|
8 | import org.gradle.api.tasks.TaskProvider; | |||
|
9 | import org.implab.gradle.mercurial.tasks.HgBookmark; | |||
|
10 | import org.implab.gradle.mercurial.tasks.HgTag; | |||
|
11 | import org.implab.gradle.mercurial.tasks.HgTask; | |||
|
12 | ||||
|
13 | public class MercurialPlugin implements Plugin<Project> { | |||
|
14 | ||||
|
15 | public final String MERCURIAL_EXTENSION_NAME = "mercurial"; | |||
|
16 | ||||
|
17 | private MercurialExtension mercurialExtension; | |||
|
18 | ||||
|
19 | @Override | |||
|
20 | public void apply(Project project) { | |||
|
21 | ||||
|
22 | mercurialExtension = new MercurialExtension(project); | |||
|
23 | ||||
|
24 | project.getExtensions().add(MERCURIAL_EXTENSION_NAME, mercurialExtension); | |||
|
25 | ||||
|
26 | ExtraPropertiesExtension extras = project.getExtensions().getExtraProperties(); | |||
|
27 | extras.set(HgTask.class.getSimpleName(), HgTask.class); | |||
|
28 | extras.set("semver", new MethodClosure(SemVersion.class, "toSemVersion")); | |||
|
29 | ||||
|
30 | project.getTasks().register("printVersion", t -> { | |||
|
31 | t.doLast(t2 -> { | |||
|
32 | t2.getLogger().quiet("version: {}", project.getVersion()); | |||
|
33 | }); | |||
|
34 | }); | |||
|
35 | ||||
|
36 | TaskProvider<HgBookmark> hgBookmarkTask = project.getTasks().register("hgBookmark", HgBookmark.class, t -> { | |||
|
37 | t.getInactive().set(true); | |||
|
38 | t.getForce().set(true); | |||
|
39 | }); | |||
|
40 | ||||
|
41 | TaskProvider<HgTag> hgTagTask = project.getTasks().register("hgTag", HgTag.class, t -> { | |||
|
42 | t.mustRunAfter(hgBookmarkTask); | |||
|
43 | }); | |||
|
44 | ||||
|
45 | project.getTasks().register("release", t -> { | |||
|
46 | t.finalizedBy(hgBookmarkTask, hgTagTask); | |||
|
47 | t.doLast(self -> { | |||
|
48 | try { | |||
|
49 | if (mercurialExtension.checkIsDirty()) | |||
|
50 | throw new Exception("The workspace is dirty, you need to commit changes first"); | |||
|
51 | ||||
|
52 | SemVersion version = (SemVersion) project.getVersion(); | |||
|
53 | SemVersion nextVersion = version.release(); | |||
|
54 | ||||
|
55 | self.getLogger().quiet("release {} -> {}", version, nextVersion); | |||
|
56 | ||||
|
57 | hgBookmarkTask.get().getBookmarks().add("prod"); | |||
|
58 | hgTagTask.get().getTags().add("v" + nextVersion.toString()); | |||
|
59 | } catch (Exception e) { | |||
|
60 | throw new TaskExecutionException(self, e); | |||
|
61 | } | |||
|
62 | }); | |||
|
63 | }); | |||
|
64 | ||||
|
65 | project.getTasks().register("staging", t -> { | |||
|
66 | t.finalizedBy(hgBookmarkTask, hgTagTask); | |||
|
67 | t.doLast(self -> { | |||
|
68 | try { | |||
|
69 | if (mercurialExtension.checkIsDirty()) | |||
|
70 | throw new Exception("The workspace is dirty, you need to commit changes first"); | |||
|
71 | ||||
|
72 | SemVersion version = (SemVersion) project.getVersion(); | |||
|
73 | SemVersion nextVersion = version.release().suffix("rc"); | |||
|
74 | ||||
|
75 | self.getLogger().quiet("staging {} -> {}", version, nextVersion); | |||
|
76 | ||||
|
77 | hgBookmarkTask.get().getBookmarks().add("staging"); | |||
|
78 | hgTagTask.get().getTags().add("v" + nextVersion.toString()); | |||
|
79 | } catch (Exception e) { | |||
|
80 | throw new TaskExecutionException(self, e); | |||
|
81 | } | |||
|
82 | }); | |||
|
83 | }); | |||
|
84 | } | |||
|
85 | } |
@@ -0,0 +1,211 | |||||
|
1 | package org.implab.gradle.mercurial; | |||
|
2 | ||||
|
3 | import java.io.Serializable; | |||
|
4 | import java.util.Objects; | |||
|
5 | import java.util.Optional; | |||
|
6 | import java.util.regex.Matcher; | |||
|
7 | import java.util.regex.Pattern; | |||
|
8 | ||||
|
9 | import javax.annotation.Nonnull; | |||
|
10 | ||||
|
11 | public class SemVersion implements Serializable, Comparable<SemVersion> { | |||
|
12 | ||||
|
13 | private static final long serialVersionUID = 1L; | |||
|
14 | ||||
|
15 | private static Pattern semVerPattern = Pattern.compile( | |||
|
16 | "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"); | |||
|
17 | ||||
|
18 | private static Pattern semVerLaxPattern = Pattern.compile( | |||
|
19 | "^(0|[1-9]\\d*)(?:\\.(0|[1-9]\\d*)(?:\\.(0|[1-9]\\d*))?)?(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"); | |||
|
20 | ||||
|
21 | private int major; | |||
|
22 | ||||
|
23 | private int minor; | |||
|
24 | ||||
|
25 | private int patch; | |||
|
26 | ||||
|
27 | private String suffix; | |||
|
28 | ||||
|
29 | private String meta; | |||
|
30 | ||||
|
31 | public SemVersion() { | |||
|
32 | } | |||
|
33 | ||||
|
34 | public SemVersion(int major, int minor, int patch, String suffix, String meta) { | |||
|
35 | this.major = major; | |||
|
36 | this.minor = minor; | |||
|
37 | this.patch = patch; | |||
|
38 | this.suffix = suffix; | |||
|
39 | this.meta = meta; | |||
|
40 | } | |||
|
41 | ||||
|
42 | public SemVersion(int major, int minor, int patch) { | |||
|
43 | this(major, minor, patch, null, null); | |||
|
44 | } | |||
|
45 | ||||
|
46 | public SemVersion(SemVersion src) { | |||
|
47 | this(src.major, src.minor, src.patch, src.suffix, src.meta); | |||
|
48 | } | |||
|
49 | ||||
|
50 | public int getMajor() { | |||
|
51 | return major; | |||
|
52 | } | |||
|
53 | ||||
|
54 | public void setMajor(int major) { | |||
|
55 | this.major = major; | |||
|
56 | } | |||
|
57 | ||||
|
58 | public int getMinor() { | |||
|
59 | return minor; | |||
|
60 | } | |||
|
61 | ||||
|
62 | public void setMinor(int minor) { | |||
|
63 | this.minor = minor; | |||
|
64 | } | |||
|
65 | ||||
|
66 | public int getPatch() { | |||
|
67 | return patch; | |||
|
68 | } | |||
|
69 | ||||
|
70 | public void setPatch(int patch) { | |||
|
71 | this.patch = patch; | |||
|
72 | } | |||
|
73 | ||||
|
74 | public Optional<String> getSuffix() { | |||
|
75 | return Optional.ofNullable(suffix); | |||
|
76 | } | |||
|
77 | ||||
|
78 | public void setSuffix(String suffix) { | |||
|
79 | this.suffix = suffix; | |||
|
80 | } | |||
|
81 | ||||
|
82 | public Optional<String> getMeta() { | |||
|
83 | return Optional.ofNullable(meta); | |||
|
84 | } | |||
|
85 | ||||
|
86 | public void setMeta(String meta) { | |||
|
87 | this.meta = meta; | |||
|
88 | } | |||
|
89 | ||||
|
90 | public boolean isRelease() { | |||
|
91 | return getSuffix().isEmpty(); | |||
|
92 | } | |||
|
93 | ||||
|
94 | @Override | |||
|
95 | public String toString() { | |||
|
96 | StringBuilder sb = new StringBuilder(); | |||
|
97 | ||||
|
98 | sb.append(major).append(".").append(minor).append(".").append(patch); | |||
|
99 | getSuffix().ifPresent(s -> sb.append("-").append(s)); | |||
|
100 | getMeta().ifPresent(m -> sb.append("+").append(m)); | |||
|
101 | ||||
|
102 | return sb.toString(); | |||
|
103 | } | |||
|
104 | ||||
|
105 | @Override | |||
|
106 | public int compareTo(SemVersion other) { | |||
|
107 | int res = Integer.compare(major, other.major); | |||
|
108 | if (res != 0) | |||
|
109 | return res; | |||
|
110 | res = Integer.compare(minor, other.minor); | |||
|
111 | if (res != 0) | |||
|
112 | return res; | |||
|
113 | res = Integer.compare(patch, other.patch); | |||
|
114 | ||||
|
115 | return getSuffix() | |||
|
116 | // if we have suffix, chech another suffix, if there is no another suffix | |||
|
117 | // then another version is bigger: 1.0.0-rc < 1.0.0 | |||
|
118 | .map(s1 -> other.getSuffix().map(s2 -> s1.compareTo(s2)).orElse(-1)) | |||
|
119 | // if we don't have the suffix | |||
|
120 | .orElse(other.getSuffix().isPresent() ? 1 : 0); | |||
|
121 | ||||
|
122 | } | |||
|
123 | ||||
|
124 | public SemVersion release() { | |||
|
125 | return new SemVersion(major, minor, patch, null, null); | |||
|
126 | } | |||
|
127 | ||||
|
128 | public SemVersion suffix(String suffix) { | |||
|
129 | return new SemVersion(major, minor, patch, suffix, meta); | |||
|
130 | } | |||
|
131 | ||||
|
132 | public SemVersion suffix() { | |||
|
133 | return new SemVersion(major, minor, patch, null, meta); | |||
|
134 | } | |||
|
135 | ||||
|
136 | public SemVersion meta(String meta) { | |||
|
137 | return new SemVersion(major, minor, patch, suffix, meta); | |||
|
138 | } | |||
|
139 | ||||
|
140 | public SemVersion meta() { | |||
|
141 | return new SemVersion(major, minor, patch, suffix, null); | |||
|
142 | } | |||
|
143 | ||||
|
144 | public SemVersion patch(int patch) { | |||
|
145 | return new SemVersion(major, minor, patch, suffix, meta); | |||
|
146 | } | |||
|
147 | ||||
|
148 | public SemVersion minor(int minor) { | |||
|
149 | return new SemVersion(major, minor, patch, suffix, meta); | |||
|
150 | } | |||
|
151 | ||||
|
152 | public SemVersion major(int major) { | |||
|
153 | return new SemVersion(major, minor, patch, suffix, meta); | |||
|
154 | } | |||
|
155 | ||||
|
156 | public SemVersion addPatch(int number) { | |||
|
157 | return new SemVersion(major, minor, patch + number, suffix, meta); | |||
|
158 | } | |||
|
159 | ||||
|
160 | public SemVersion addMinor(int number) { | |||
|
161 | return new SemVersion(major, minor + number, patch, suffix, meta); | |||
|
162 | } | |||
|
163 | ||||
|
164 | public SemVersion addMajor(int number) { | |||
|
165 | return new SemVersion(major + number, minor, patch, suffix, meta); | |||
|
166 | } | |||
|
167 | ||||
|
168 | public SemVersion nextMinor() { | |||
|
169 | return new SemVersion(major, minor + 1, 0, null, meta); | |||
|
170 | } | |||
|
171 | ||||
|
172 | public SemVersion nextMajor() { | |||
|
173 | return new SemVersion(major + 1, 0, 0, null, meta); | |||
|
174 | } | |||
|
175 | ||||
|
176 | public static Optional<SemVersion> tryParse(@Nonnull String str) { | |||
|
177 | Objects.requireNonNull(str); | |||
|
178 | ||||
|
179 | Matcher match = semVerPattern.matcher(str); | |||
|
180 | ||||
|
181 | return match.matches() ? Optional.of(new SemVersion(Integer.parseInt(match.group(1)), | |||
|
182 | Integer.parseInt(match.group(2)), Integer.parseInt(match.group(3)), match.group(4), match.group(5))) | |||
|
183 | : Optional.empty(); | |||
|
184 | } | |||
|
185 | ||||
|
186 | public static Optional<SemVersion> tryParseLax(@Nonnull String str) { | |||
|
187 | Objects.requireNonNull(str); | |||
|
188 | ||||
|
189 | Matcher match = semVerLaxPattern.matcher(str); | |||
|
190 | ||||
|
191 | return match.matches() ? Optional.of(new SemVersion(Integer.parseInt(match.group(1)), | |||
|
192 | Integer.parseInt(Optional.ofNullable(match.group(2)).orElse("0")), | |||
|
193 | Integer.parseInt(Optional.ofNullable(match.group(3)).orElse("0")), match.group(4), match.group(5))) | |||
|
194 | : Optional.empty(); | |||
|
195 | } | |||
|
196 | ||||
|
197 | public static SemVersion toSemVersion(Object value, boolean strict) { | |||
|
198 | if (value == null) { | |||
|
199 | return new SemVersion(); | |||
|
200 | } else if (value instanceof SemVersion) { | |||
|
201 | return new SemVersion((SemVersion) value); | |||
|
202 | } else { | |||
|
203 | Optional<SemVersion> semver = strict ? tryParse(value.toString()) : tryParseLax(value.toString()); | |||
|
204 | return semver.orElseThrow(() -> new IllegalArgumentException(String.format("Failed to parse semver '%s', strict=%s", value, strict))); | |||
|
205 | } | |||
|
206 | } | |||
|
207 | ||||
|
208 | public static SemVersion toSemVersion(Object value) { | |||
|
209 | return toSemVersion(value, false); | |||
|
210 | } | |||
|
211 | } |
@@ -0,0 +1,51 | |||||
|
1 | package org.implab.gradle.mercurial; | |||
|
2 | ||||
|
3 | import java.util.Objects; | |||
|
4 | ||||
|
5 | public class WorkspaceInfo { | |||
|
6 | private final String versionTag; | |||
|
7 | ||||
|
8 | private final int versionDistance; | |||
|
9 | ||||
|
10 | private final String branch; | |||
|
11 | ||||
|
12 | private final String changeset; | |||
|
13 | ||||
|
14 | private final boolean isDirty; | |||
|
15 | ||||
|
16 | public WorkspaceInfo(String versionTag, int versionDistance, String branch, String changeset, boolean isDirty) { | |||
|
17 | this.versionTag = versionTag; | |||
|
18 | this.versionDistance = versionDistance; | |||
|
19 | this.branch = Objects.requireNonNull(branch); | |||
|
20 | this.changeset = Objects.requireNonNull(changeset); | |||
|
21 | this.isDirty = isDirty; | |||
|
22 | } | |||
|
23 | ||||
|
24 | public String getChangeset() { | |||
|
25 | return changeset; | |||
|
26 | } | |||
|
27 | ||||
|
28 | public String getVersionTag() { | |||
|
29 | return versionTag; | |||
|
30 | } | |||
|
31 | ||||
|
32 | public int getVersionDistance() { | |||
|
33 | return versionDistance; | |||
|
34 | } | |||
|
35 | ||||
|
36 | public String getBranch() { | |||
|
37 | return branch; | |||
|
38 | } | |||
|
39 | ||||
|
40 | public boolean getIsDirty() { | |||
|
41 | return isDirty; | |||
|
42 | } | |||
|
43 | ||||
|
44 | ||||
|
45 | @Override | |||
|
46 | public String toString() { | |||
|
47 | return String.format("{ changeset=%s, branch=%s, versionTag=%s, distance=%s, isDirty=%s}", changeset, branch, | |||
|
48 | versionTag, versionDistance, isDirty); | |||
|
49 | } | |||
|
50 | ||||
|
51 | } |
@@ -0,0 +1,84 | |||||
|
1 | package org.implab.gradle.mercurial.tasks; | |||
|
2 | ||||
|
3 | import java.io.IOException; | |||
|
4 | import java.util.ArrayList; | |||
|
5 | import java.util.List; | |||
|
6 | ||||
|
7 | import javax.inject.Inject; | |||
|
8 | ||||
|
9 | import org.gradle.api.DefaultTask; | |||
|
10 | import org.gradle.api.model.ObjectFactory; | |||
|
11 | import org.gradle.api.provider.ListProperty; | |||
|
12 | import org.gradle.api.provider.Property; | |||
|
13 | import org.gradle.api.tasks.TaskAction; | |||
|
14 | import org.implab.gradle.Utils; | |||
|
15 | import org.implab.gradle.mercurial.MercurialExtension; | |||
|
16 | ||||
|
17 | import groovy.transform.Internal; | |||
|
18 | ||||
|
19 | public class HgBookmark extends DefaultTask { | |||
|
20 | ||||
|
21 | private final Property<String> cliCmd; | |||
|
22 | ||||
|
23 | private final Property<Boolean> inactive; | |||
|
24 | ||||
|
25 | private final Property<Boolean> force; | |||
|
26 | ||||
|
27 | private final ListProperty<String> bookmarks; | |||
|
28 | ||||
|
29 | private String commandOutput; | |||
|
30 | ||||
|
31 | protected MercurialExtension getMercurialExtension() { | |||
|
32 | return getProject().getExtensions().getByType(MercurialExtension.class); | |||
|
33 | } | |||
|
34 | ||||
|
35 | @Inject | |||
|
36 | public HgBookmark(ObjectFactory factory) { | |||
|
37 | cliCmd = factory.property(String.class); | |||
|
38 | inactive = factory.property(Boolean.class); | |||
|
39 | force = factory.property(Boolean.class); | |||
|
40 | bookmarks = factory.listProperty(String.class); | |||
|
41 | cliCmd.convention(getMercurialExtension().getHgCmd()); | |||
|
42 | ||||
|
43 | onlyIf(t -> !getBookmarks().get().isEmpty()); | |||
|
44 | } | |||
|
45 | ||||
|
46 | @Internal | |||
|
47 | public Property<Boolean> getInactive() { | |||
|
48 | return inactive; | |||
|
49 | } | |||
|
50 | ||||
|
51 | @Internal | |||
|
52 | public Property<Boolean> getForce() { | |||
|
53 | return force; | |||
|
54 | } | |||
|
55 | ||||
|
56 | @Internal | |||
|
57 | public String getCommandOutput() { | |||
|
58 | return commandOutput; | |||
|
59 | } | |||
|
60 | ||||
|
61 | @Internal | |||
|
62 | public ListProperty<String> getBookmarks() { | |||
|
63 | return bookmarks; | |||
|
64 | } | |||
|
65 | ||||
|
66 | @TaskAction | |||
|
67 | public void Run() throws IOException, InterruptedException, Exception { | |||
|
68 | List<String> commandLine = new ArrayList<>(); | |||
|
69 | ||||
|
70 | commandLine.add(cliCmd.get()); | |||
|
71 | commandLine.add("bookmark"); | |||
|
72 | if(inactive.isPresent()) | |||
|
73 | commandLine.add("-i"); | |||
|
74 | if(force.isPresent()) | |||
|
75 | commandLine.add("-f"); | |||
|
76 | ||||
|
77 | commandLine.addAll(bookmarks.get()); | |||
|
78 | ||||
|
79 | getLogger().info("Starting: {}", commandLine); | |||
|
80 | ||||
|
81 | commandOutput = Utils.execCmd(commandLine, getMercurialExtension().getOutputCharset().name()); | |||
|
82 | } | |||
|
83 | ||||
|
84 | } |
@@ -0,0 +1,79 | |||||
|
1 | package org.implab.gradle.mercurial.tasks; | |||
|
2 | ||||
|
3 | import java.io.IOException; | |||
|
4 | import java.util.ArrayList; | |||
|
5 | import java.util.List; | |||
|
6 | ||||
|
7 | import javax.inject.Inject; | |||
|
8 | ||||
|
9 | import org.gradle.api.DefaultTask; | |||
|
10 | import org.gradle.api.model.ObjectFactory; | |||
|
11 | import org.gradle.api.provider.ListProperty; | |||
|
12 | import org.gradle.api.provider.Property; | |||
|
13 | import org.gradle.api.tasks.Input; | |||
|
14 | import org.gradle.api.tasks.SkipWhenEmpty; | |||
|
15 | import org.gradle.api.tasks.TaskAction; | |||
|
16 | import org.implab.gradle.Utils; | |||
|
17 | import org.implab.gradle.mercurial.MercurialExtension; | |||
|
18 | ||||
|
19 | import groovy.transform.Internal; | |||
|
20 | ||||
|
21 | public class HgTag extends DefaultTask { | |||
|
22 | ||||
|
23 | private final Property<String> cliCmd; | |||
|
24 | ||||
|
25 | private final Property<Boolean> force; | |||
|
26 | ||||
|
27 | private final ListProperty<String> tags; | |||
|
28 | ||||
|
29 | private String commandOutput; | |||
|
30 | ||||
|
31 | protected MercurialExtension getMercurialExtension() { | |||
|
32 | return getProject().getExtensions().getByType(MercurialExtension.class); | |||
|
33 | } | |||
|
34 | ||||
|
35 | @Inject | |||
|
36 | public HgTag(ObjectFactory factory) { | |||
|
37 | cliCmd = factory.property(String.class); | |||
|
38 | force = factory.property(Boolean.class); | |||
|
39 | tags = factory.listProperty(String.class); | |||
|
40 | cliCmd.convention(getMercurialExtension().getHgCmd()); | |||
|
41 | ||||
|
42 | onlyIf(t -> !getTags().get().isEmpty()); | |||
|
43 | } | |||
|
44 | ||||
|
45 | @Internal | |||
|
46 | public Property<Boolean> getForce() { | |||
|
47 | return force; | |||
|
48 | } | |||
|
49 | ||||
|
50 | @Internal | |||
|
51 | public String getCommandOutput() { | |||
|
52 | return commandOutput; | |||
|
53 | } | |||
|
54 | ||||
|
55 | @Input | |||
|
56 | @SkipWhenEmpty | |||
|
57 | public ListProperty<String> getTags() { | |||
|
58 | return tags; | |||
|
59 | } | |||
|
60 | ||||
|
61 | @TaskAction | |||
|
62 | public void Run() throws IOException, InterruptedException, Exception { | |||
|
63 | List<String> commandLine = new ArrayList<>(); | |||
|
64 | ||||
|
65 | commandLine.add(cliCmd.get()); | |||
|
66 | ||||
|
67 | commandLine.add("tag"); | |||
|
68 | ||||
|
69 | if(force.isPresent()) | |||
|
70 | commandLine.add("-f"); | |||
|
71 | ||||
|
72 | commandLine.addAll(tags.get()); | |||
|
73 | ||||
|
74 | getLogger().info("Starting: {}", commandLine); | |||
|
75 | ||||
|
76 | commandOutput = Utils.execCmd(commandLine, getMercurialExtension().getOutputCharset().name()); | |||
|
77 | } | |||
|
78 | ||||
|
79 | } |
@@ -0,0 +1,67 | |||||
|
1 | package org.implab.gradle.mercurial.tasks; | |||
|
2 | ||||
|
3 | import java.io.IOException; | |||
|
4 | import java.util.ArrayList; | |||
|
5 | import java.util.List; | |||
|
6 | ||||
|
7 | import org.gradle.api.DefaultTask; | |||
|
8 | import org.gradle.api.provider.Property; | |||
|
9 | import org.gradle.api.provider.Provider; | |||
|
10 | import org.gradle.api.tasks.TaskAction; | |||
|
11 | import org.implab.gradle.Utils; | |||
|
12 | import org.implab.gradle.mercurial.MercurialExtension; | |||
|
13 | ||||
|
14 | public class HgTask extends DefaultTask { | |||
|
15 | ||||
|
16 | private final Property<String> cliCmd; | |||
|
17 | ||||
|
18 | private List<Provider<String>> commandArgs; | |||
|
19 | ||||
|
20 | private String commandOutput; | |||
|
21 | ||||
|
22 | protected MercurialExtension getMercurialExtension() { | |||
|
23 | return getProject().getExtensions().getByType(MercurialExtension.class); | |||
|
24 | } | |||
|
25 | ||||
|
26 | public HgTask() { | |||
|
27 | cliCmd = getProject().getObjects().property(String.class); | |||
|
28 | cliCmd.convention(getMercurialExtension().getHgCmd()); | |||
|
29 | ||||
|
30 | } | |||
|
31 | ||||
|
32 | public String getCommandOutput() { | |||
|
33 | return commandOutput; | |||
|
34 | } | |||
|
35 | ||||
|
36 | public void clearCommandArgs() { | |||
|
37 | commandArgs.clear(); | |||
|
38 | } | |||
|
39 | ||||
|
40 | public void commandArgs(Object... args) { | |||
|
41 | for (Object arg : args) { | |||
|
42 | if (arg == null) | |||
|
43 | continue; | |||
|
44 | if (arg instanceof Provider<?>) | |||
|
45 | commandArgs.add(((Provider<?>) arg).map(x -> x.toString())); | |||
|
46 | else | |||
|
47 | commandArgs.add(getProject().getProviders().provider(() -> arg.toString())); | |||
|
48 | } | |||
|
49 | } | |||
|
50 | ||||
|
51 | @TaskAction | |||
|
52 | public void Run() throws IOException, InterruptedException, Exception { | |||
|
53 | List<String> commandLine = new ArrayList<>(); | |||
|
54 | ||||
|
55 | commandLine.add(cliCmd.get()); | |||
|
56 | ||||
|
57 | for (Provider<String> arg : commandArgs) { | |||
|
58 | if (arg.isPresent()) | |||
|
59 | commandLine.add(arg.get()); | |||
|
60 | } | |||
|
61 | ||||
|
62 | getLogger().info("Starting: ", commandLine); | |||
|
63 | ||||
|
64 | commandOutput = Utils.execCmd(commandLine, getMercurialExtension().getOutputCharset().name()); | |||
|
65 | } | |||
|
66 | ||||
|
67 | } |
@@ -0,0 +1,13 | |||||
|
1 | /* | |||
|
2 | * This settings file was generated by the Gradle 'init' task. | |||
|
3 | * | |||
|
4 | * The settings file is used to specify which projects to include in your build. | |||
|
5 | * In a single project build this file can be empty or even removed. | |||
|
6 | * | |||
|
7 | * Detailed information about configuring a multi-project build in Gradle can be found | |||
|
8 | * in the user guide at https://docs.gradle.org/3.5/userguide/multi_project_builds.html | |||
|
9 | */ | |||
|
10 | ||||
|
11 | rootProject.name = 'plugins' | |||
|
12 | ||||
|
13 | include 'mercurial' |
General Comments 0
You need to be logged in to leave comments.
Login now