##// END OF EJS Templates
added preReleasePolicy, stagingBookmark, releaseBookmark to the extension, added documentation....
cin -
r1:193d6f38df6e v1.0.0 default
parent child
Show More
@@ -0,0 +1,3
1 {
2 "java.configuration.updateBuildConfiguration": "automatic"
3 } No newline at end of file
@@ -0,0 +1,2
1 group=org.implab.gradle
2 version=1.0.0 No newline at end of file
1 NO CONTENT: new file 100644, binary diff hidden
NO CONTENT: new file 100644, binary diff hidden
@@ -0,0 +1,5
1 distributionBase=GRADLE_USER_HOME
2 distributionPath=wrapper/dists
3 distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
4 zipStoreBase=GRADLE_USER_HOME
5 zipStorePath=wrapper/dists
@@ -0,0 +1,120
1 # Mercurial build integration
2
3 ## SYNOPSIS
4
5 ```groovy
6
7 plugins {
8 id 'org.implab.gradle-mercurial' version '1.0'
9 }
10
11 mercurial {
12 releaseBookmark = 'prod'
13
14 preReleasePolicy { it
15 // this is the default behaviour
16 .addPatch(1)
17 .withPreRelease('snapshot')
18 .withMeta('changeset')
19 }
20
21 // get version from repository and apply it to the project
22 applyVersioningPolicy()
23 }
24
25 ```
26
27 ## DESCRIPTION
28
29 ### `semver(versionString)`
30
31 Parses the specified version string and returns the semantic version object
32
33 ### `mercurial(Closure configure)`
34
35 The extension added by the plugin to the project. Apply this plugin to the
36 root project and use the `mercurial { ... }` section to configure the
37 versioning.
38
39 See the description below for more details about settings.
40
41 #### `hgCmd`
42
43 The command which will be executed to perform the mercurial commands.
44 The default value is `hg`.
45
46 #### `outputCharset`
47
48 The charset for the `hgCmd` output, this property defaults
49 to the default charset of the operating system.
50
51 #### `hg(...args)`
52
53 Executes the mercurial command, returns the command output as text.
54
55 #### `workspaceInfo` (read-only)
56
57 Returns the information about current workspace, see description
58 below for details.
59
60 #### `workspaceVersion`
61
62 Returns the semantic version obtained from the repository. Querying
63 this property will lead querying the workspace info.
64
65 #### `applyVersioningPolicy()`
66
67 Reads the workspace information and sets the version of the project
68 according to settings.
69
70 If the version was specified using properties, then the specified
71 version will take preceding over the calculated one.
72
73 #### `preReleasePolicy(Closure<SemVersion> config)`
74
75 The closure which is used to calculate the version of the project
76 when the current commit isn't marked with a version tag.
77
78 The default behaviour is to increment the patch version and
79 to set the pre-release suffix to `'snapshot'`.
80
81 ### `WorkspaceInfo`
82
83 This class encapsulates information about the current workspace.
84 All properties are read-only.
85
86 #### `versionTag`
87
88 The original version tag from the repository before parsing.
89
90 #### `changeSet`
91
92 The changeset id of the current workspace.
93
94 #### `versionDistance`
95
96 The distance in commits to the versionTag
97
98 #### `branch`
99
100 The name of the current sources branch.
101
102 #### `isDirty`
103
104 This flag indicates uncommited changes to the workspace. This flag is useful
105 to control some pipelines which run locally on developer machines.
106
107 ## TASKS
108
109 ### `release`
110
111 Marks this commit with current version and pre-release suffix removed and
112 moves the `release` bookmark to it.
113
114 ### `staging`
115
116 Marks this commit with current version and moves the `staging` bookmark to it.
117
118 ### `printVersion`
119
120 Prints the current version.
@@ -1,17 +1,26
1 plugins {
1 plugins {
2 id "java-gradle-plugin"
2 id "java-gradle-plugin"
3 id "com.gradle.plugin-publish" version "0.16.0"
3 }
4 }
4
5
5
6 repositories {
6 repositories {
7 mavenCentral()
7 mavenCentral()
8 }
8 }
9
9
10 gradlePlugin {
10 gradlePlugin {
11 plugins {
11 plugins {
12 containerPlugin {
12 mercurialPlugin {
13 id = 'org.implab.gradle-mercurial'
13 id = 'org.implab.gradle-mercurial'
14 implementationClass = 'org.implab.gradle.mercurial.MercurialPlugin'
14 implementationClass = 'org.implab.gradle.mercurial.MercurialPlugin'
15 displayName = "Integrates mercurial into the build script"
16 description = 'Automatically calculates version using tags. Simple wrapper around cli.'
15 }
17 }
16 }
18 }
17 }
19 }
20
21 pluginBundle {
22 website = 'https://code.implab.org/implab/gradle-mercurial-plugin'
23 vcsUrl = 'https://code.implab.org/implab/gradle-mercurial-plugin'
24
25 tags = ['hg', 'mercurial']
26 }
@@ -18,42 +18,47 import groovy.lang.Closure;
18
18
19 public final class Utils {
19 public final class Utils {
20 public static void redirectIO(final InputStream src, final Action<String> consumer) {
20 public static void redirectIO(final InputStream src, final Action<String> consumer) {
21 new Thread(() -> {
21 new Thread(() -> {
22 try (Scanner sc = new Scanner(src)) {
22 try (Scanner sc = new Scanner(src)) {
23 while (sc.hasNextLine()) {
23 while (sc.hasNextLine()) {
24 consumer.execute(sc.nextLine());
24 consumer.execute(sc.nextLine());
25 }
25 }
26 }
26 }
27 }).start();
27 }).start();
28 }
28 }
29
29
30 public static String execCmd(List<String> args, String charset) throws IOException, InterruptedException, Exception {
30 public static String execCmd(List<String> args, String charset) {
31 if (args == null || args.size() == 0)
31 if (args == null || args.size() == 0)
32 throw new IllegalArgumentException();
32 throw new IllegalArgumentException();
33
33
34 ProcessBuilder builder = new ProcessBuilder(args);
34 ProcessBuilder builder = new ProcessBuilder(args);
35
35
36 Process p = builder.start();
36 Process p;
37 try {
38 p = builder.start();
37
39
38 String output = readAll(p.getInputStream(), charset);
40 String output = readAll(p.getInputStream(), charset);
39
41
40 int code = p.waitFor();
42 int code = p.waitFor();
41 if (code != 0)
43 if (code != 0)
42 throw new Exception(String.format("The process `%s` failed with code: %s", args.get(0), code));
44 throw new RuntimeException(String.format("The process `%s` failed with code: %s", args.get(0), code));
43
45
44 return output;
46 return output;
45
47 } catch (IOException | InterruptedException e) {
48 throw new RuntimeException(String.format("Failed to execute `%s`", args.get(0)), e);
49 }
50
46 }
51 }
47
52
48 public static void redirectIO(final InputStream src, final File file) {
53 public static void redirectIO(final InputStream src, final File file) {
49 new Thread(() -> {
54 new Thread(() -> {
50 try (OutputStream out = new FileOutputStream(file)) {
55 try (OutputStream out = new FileOutputStream(file)) {
51 src.transferTo(out);
56 src.transferTo(out);
52 } catch(Exception e) {
57 } catch (Exception e) {
53 // silence!
58 // silence!
54 }
59 }
55 }).start();
60 }).start();
56 }
61 }
57
62
58 public static String readAll(final InputStream src) throws IOException {
63 public static String readAll(final InputStream src) throws IOException {
59 ByteArrayOutputStream out = new ByteArrayOutputStream();
64 ByteArrayOutputStream out = new ByteArrayOutputStream();
@@ -67,24 +72,25 public final class Utils {
67 return out.toString(charset);
72 return out.toString(charset);
68 }
73 }
69
74
70 public static JsonGenerator createDefaultJsonGenerator() {
75 public static JsonGenerator createDefaultJsonGenerator() {
71 return new JsonGenerator.Options()
76 return new JsonGenerator.Options()
72 .excludeNulls()
77 .excludeNulls()
73 .addConverter(new Converter() {
78 .addConverter(new Converter() {
74 public boolean handles(Class<?> type) {
79 public boolean handles(Class<?> type) {
75 return (File.class == type);
80 return (File.class == type);
76 }
81 }
77 public Object convert(Object value, String key) {
82
78 return ((File)value).getPath();
83 public Object convert(Object value, String key) {
79 }
84 return ((File) value).getPath();
80 })
85 }
81 .build();
86 })
87 .build();
82 }
88 }
83
89
84 public static void closeSilent(Closeable handle) {
90 public static void closeSilent(Closeable handle) {
85 try {
91 try {
86 handle.close();
92 handle.close();
87 } catch(Exception e) {
93 } catch (Exception e) {
88 // silence!
94 // silence!
89 }
95 }
90 }
96 }
@@ -6,12 +6,15 import java.util.Collections;
6 import java.util.List;
6 import java.util.List;
7 import java.util.Objects;
7 import java.util.Objects;
8 import java.util.Optional;
8 import java.util.Optional;
9 import java.util.function.Function;
9 import java.util.regex.Matcher;
10 import java.util.regex.Matcher;
10 import java.util.regex.Pattern;
11 import java.util.regex.Pattern;
11
12
12 import org.gradle.api.Project;
13 import org.gradle.api.Project;
13 import org.implab.gradle.Utils;
14 import org.implab.gradle.Utils;
14
15
16 import groovy.lang.Closure;
17
15 public class MercurialExtension {
18 public class MercurialExtension {
16 private static final String COMMIT_INFO_TEMPLATE = "{latesttag('re:^v') % '{ifeq(tag,'null','',tag)}:{distance}'}:{branch}:{node|short}";
19 private static final String COMMIT_INFO_TEMPLATE = "{latesttag('re:^v') % '{ifeq(tag,'null','',tag)}:{distance}'}:{branch}:{node|short}";
17
20
@@ -25,15 +28,21 public class MercurialExtension {
25
28
26 private String hgCmd = "hg";
29 private String hgCmd = "hg";
27
30
31 private String stagingBookmark = "staging";
32
33 private String releaseBookmark = "prod";
34
28 private SemVersion defaultWorkspaceVersion = new SemVersion(0, 0, 1, "dev", null);
35 private SemVersion defaultWorkspaceVersion = new SemVersion(0, 0, 1, "dev", null);
29
36
37 private Function<SemVersion, SemVersion> preReleasePolicy;
38
30 public MercurialExtension(Project project) {
39 public MercurialExtension(Project project) {
31 Objects.requireNonNull(project);
40 Objects.requireNonNull(project);
32
41
33 this.project = project;
42 this.project = project;
34 }
43 }
35
44
36 public String hg(String... args) throws Exception {
45 public String hg(String... args) {
37 List<String> commandLine = new ArrayList<>();
46 List<String> commandLine = new ArrayList<>();
38 commandLine.add(hgCmd);
47 commandLine.add(hgCmd);
39 Collections.addAll(commandLine, args);
48 Collections.addAll(commandLine, args);
@@ -41,6 +50,26 public class MercurialExtension {
41 return Utils.execCmd(commandLine, outputCharset.name());
50 return Utils.execCmd(commandLine, outputCharset.name());
42 }
51 }
43
52
53 public String getReleaseBookmark() {
54 return releaseBookmark;
55 }
56
57 public void setReleaseBookmark(String value) {
58 if(value == null)
59 throw new IllegalArgumentException();
60 releaseBookmark = value;
61 }
62
63 public String getStagingBookmark() {
64 return stagingBookmark;
65 }
66
67 public void setStagingBookmark(String value) {
68 if(value == null)
69 throw new IllegalArgumentException();
70 stagingBookmark = value;
71 }
72
44 public Charset getOutputCharset() {
73 public Charset getOutputCharset() {
45 return outputCharset;
74 return outputCharset;
46 }
75 }
@@ -62,42 +91,71 public class MercurialExtension {
62 this.hgCmd = hgCmd;
91 this.hgCmd = hgCmd;
63 }
92 }
64
93
65 public WorkspaceInfo getWorkspaceInfo() throws Exception {
94 public WorkspaceInfo getWorkspaceInfo() {
66 if (workspaceInfo == null)
95 if (workspaceInfo == null)
67 workspaceInfo = loadWorkspaceInfo();
96 workspaceInfo = loadWorkspaceInfo();
68 return workspaceInfo;
97 return workspaceInfo;
69 }
98 }
70
99
71 public SemVersion getWorkspaceVersion() throws Exception {
100 public SemVersion getWorkspaceVersion() {
72 return tryParseVersion(getWorkspaceInfo().getVersionTag()).orElse(defaultWorkspaceVersion);
101 return tryParseVersion(getWorkspaceInfo().getVersionTag()).orElse(defaultWorkspaceVersion);
73 }
102 }
74
103
75 public void applyVersioningPolicy() throws Exception {
104 private SemVersion defaultPreReleasePolicy(SemVersion version) {
105 String changeset = getWorkspaceInfo().getChangeset();
106 return version.addPatch(1).withPreRelease("snapshot").withMeta(changeset);
107 }
108
109 public void preReleasePolicy(Closure<SemVersion> policy) {
110 if (policy == null)
111 throw new IllegalArgumentException();
112
113 this.preReleasePolicy = x -> {
114 policy.setDelegate(getWorkspaceInfo());
115 policy.setResolveStrategy(Closure.DELEGATE_FIRST);
116 return policy.call(x);
117 };
118 }
119
120 public void preReleasePolicy(Function<SemVersion, SemVersion> policy) {
121 if (policy == null)
122 throw new IllegalArgumentException();
123 this.preReleasePolicy = policy;
124 }
125
126 public void applyVersioningPolicy() {
76 Object version = project.getVersion();
127 Object version = project.getVersion();
77 if (version == null || version.toString().isBlank() || version.toString().equalsIgnoreCase(Project.DEFAULT_VERSION)) {
128 if (version == null || version.toString().isBlank()
129 || version.toString().equalsIgnoreCase(Project.DEFAULT_VERSION)) {
130 // if the version isn't specified
78 int distance = getWorkspaceInfo().getVersionDistance();
131 int distance = getWorkspaceInfo().getVersionDistance();
79 String changeset = getWorkspaceInfo().getChangeset();
132
80 project.setVersion(
133 // the current workspace is not tagged with the version
81 distance> 0 ?
134 if (distance > 0) {
82 getWorkspaceVersion().addPatch(distance).suffix("snapshot").meta(changeset) :
135 SemVersion preReleaseVersion = Optional.ofNullable(preReleasePolicy)
83 getWorkspaceVersion()
136 .orElse(this::defaultPreReleasePolicy)
84 );
137 .apply(getWorkspaceVersion());
138
139 project.setVersion(preReleaseVersion);
140 } else {
141 project.setVersion(getWorkspaceVersion());
142 }
85 } else {
143 } else {
86 project.setVersion(SemVersion.toSemVersion(version, false));
144 project.setVersion(SemVersion.toSemVersion(version, false));
87 }
145 }
88 }
146 }
89
147
90 String[] queryLogInfo() throws Exception {
148 String[] queryLogInfo() {
91 return hg("log", "-r", ".", "--template", COMMIT_INFO_TEMPLATE).split(":");
149 return hg("log", "-r", ".", "--template", COMMIT_INFO_TEMPLATE).split(":");
92 }
150 }
93
151
94 WorkspaceInfo loadWorkspaceInfo() throws Exception {
152 WorkspaceInfo loadWorkspaceInfo() {
95 boolean isDirty = checkIsDirty();
153 boolean isDirty = checkIsDirty();
96 String[] info = queryLogInfo();
154 String[] info = queryLogInfo();
97 return new WorkspaceInfo(info[0], Integer.parseInt(info[1]), info[2], info[3], isDirty);
155 return new WorkspaceInfo(info[0], Integer.parseInt(info[1]), info[2], info[3], isDirty);
98 }
156 }
99
157
100 boolean checkIsDirty() throws Exception {
158 boolean checkIsDirty() {
101 return !hg("status", "-mard").isBlank();
159 return !hg("status", "-mard").isBlank();
102 }
160 }
103
161
@@ -111,5 +169,4 public class MercurialExtension {
111 return isMatch ? SemVersion.tryParseLax(m.group(1)) : Optional.empty();
169 return isMatch ? SemVersion.tryParseLax(m.group(1)) : Optional.empty();
112 }
170 }
113
171
114
115 }
172 }
@@ -29,6 +29,7 public class MercurialPlugin implements
29
29
30 project.getTasks().register("printVersion", t -> {
30 project.getTasks().register("printVersion", t -> {
31 t.doLast(t2 -> {
31 t.doLast(t2 -> {
32 t2.getLogger().quiet("workspace: {}", mercurialExtension.getWorkspaceInfo());
32 t2.getLogger().quiet("version: {}", project.getVersion());
33 t2.getLogger().quiet("version: {}", project.getVersion());
33 });
34 });
34 });
35 });
@@ -50,11 +51,11 public class MercurialPlugin implements
50 throw new Exception("The workspace is dirty, you need to commit changes first");
51 throw new Exception("The workspace is dirty, you need to commit changes first");
51
52
52 SemVersion version = (SemVersion) project.getVersion();
53 SemVersion version = (SemVersion) project.getVersion();
53 SemVersion nextVersion = version.release();
54 SemVersion nextVersion = version.withNoSuffix();
54
55
55 self.getLogger().quiet("release {} -> {}", version, nextVersion);
56 self.getLogger().quiet("{} {} -> {}", mercurialExtension.getReleaseBookmark(), version, nextVersion);
56
57
57 hgBookmarkTask.get().getBookmarks().add("prod");
58 hgBookmarkTask.get().getBookmarks().add(mercurialExtension.getReleaseBookmark());
58 hgTagTask.get().getTags().add("v" + nextVersion.toString());
59 hgTagTask.get().getTags().add("v" + nextVersion.toString());
59 } catch (Exception e) {
60 } catch (Exception e) {
60 throw new TaskExecutionException(self, e);
61 throw new TaskExecutionException(self, e);
@@ -70,11 +71,11 public class MercurialPlugin implements
70 throw new Exception("The workspace is dirty, you need to commit changes first");
71 throw new Exception("The workspace is dirty, you need to commit changes first");
71
72
72 SemVersion version = (SemVersion) project.getVersion();
73 SemVersion version = (SemVersion) project.getVersion();
73 SemVersion nextVersion = version.release().suffix("rc");
74 SemVersion nextVersion = version.withNoSuffix().withPreRelease("rc");
74
75
75 self.getLogger().quiet("staging {} -> {}", version, nextVersion);
76 self.getLogger().quiet("{} {} -> {}", mercurialExtension.getStagingBookmark(), version, nextVersion);
76
77
77 hgBookmarkTask.get().getBookmarks().add("staging");
78 hgBookmarkTask.get().getBookmarks().add(mercurialExtension.getStagingBookmark());
78 hgTagTask.get().getTags().add("v" + nextVersion.toString());
79 hgTagTask.get().getTags().add("v" + nextVersion.toString());
79 } catch (Exception e) {
80 } catch (Exception e) {
80 throw new TaskExecutionException(self, e);
81 throw new TaskExecutionException(self, e);
@@ -8,6 +8,14 import java.util.regex.Pattern;
8
8
9 import javax.annotation.Nonnull;
9 import javax.annotation.Nonnull;
10
10
11 /**
12 * Semantic version object.
13 *
14 * <p>
15 * This is a readonly version record which follows general rules of
16 * semantic versioning. The object is serializable and can be used as
17 * input property value for build tasks.
18 */
11 public class SemVersion implements Serializable, Comparable<SemVersion> {
19 public class SemVersion implements Serializable, Comparable<SemVersion> {
12
20
13 private static final long serialVersionUID = 1L;
21 private static final long serialVersionUID = 1L;
@@ -18,77 +26,61 public class SemVersion implements Seria
18 private static Pattern semVerLaxPattern = Pattern.compile(
26 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-]+)*))?$");
27 "^(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
28
21 private int major;
29 private final int major;
22
30
23 private int minor;
31 private final int minor;
24
32
25 private int patch;
33 private final int patch;
26
34
27 private String suffix;
35 private final String preRelease;
36
37 private final String meta;
28
38
29 private String meta;
39 /** Creates the new and empty version */
30
31 public SemVersion() {
40 public SemVersion() {
41 this(0, 0, 0, null, null);
32 }
42 }
33
43
34 public SemVersion(int major, int minor, int patch, String suffix, String meta) {
44 /** Creates the version object with the specified values */
45 public SemVersion(int major, int minor, int patch, String preRelease, String meta) {
35 this.major = major;
46 this.major = major;
36 this.minor = minor;
47 this.minor = minor;
37 this.patch = patch;
48 this.patch = patch;
38 this.suffix = suffix;
49 this.preRelease = preRelease;
39 this.meta = meta;
50 this.meta = meta;
40 }
51 }
41
52
53 /** Creates the version object with the specified values */
42 public SemVersion(int major, int minor, int patch) {
54 public SemVersion(int major, int minor, int patch) {
43 this(major, minor, patch, null, null);
55 this(major, minor, patch, null, null);
44 }
56 }
45
57
46 public SemVersion(SemVersion src) {
58 /** Returns the major part of the version */
47 this(src.major, src.minor, src.patch, src.suffix, src.meta);
48 }
49
50 public int getMajor() {
59 public int getMajor() {
51 return major;
60 return major;
52 }
61 }
53
62
54 public void setMajor(int major) {
63 /** Returns the minor part of the version */
55 this.major = major;
56 }
57
58 public int getMinor() {
64 public int getMinor() {
59 return minor;
65 return minor;
60 }
66 }
61
67
62 public void setMinor(int minor) {
68 /** Returns the patch part of the version */
63 this.minor = minor;
64 }
65
66 public int getPatch() {
69 public int getPatch() {
67 return patch;
70 return patch;
68 }
71 }
69
72
70 public void setPatch(int patch) {
73 /** Gets the optional pre-release version part */
71 this.patch = patch;
74 public Optional<String> getPreRelease() {
72 }
75 return Optional.ofNullable(preRelease);
73
74 public Optional<String> getSuffix() {
75 return Optional.ofNullable(suffix);
76 }
77
78 public void setSuffix(String suffix) {
79 this.suffix = suffix;
80 }
76 }
81
77
82 public Optional<String> getMeta() {
78 public Optional<String> getMeta() {
83 return Optional.ofNullable(meta);
79 return Optional.ofNullable(meta);
84 }
80 }
85
81
86 public void setMeta(String meta) {
87 this.meta = meta;
88 }
89
90 public boolean isRelease() {
82 public boolean isRelease() {
91 return getSuffix().isEmpty();
83 return getPreRelease().isEmpty();
92 }
84 }
93
85
94 @Override
86 @Override
@@ -96,7 +88,7 public class SemVersion implements Seria
96 StringBuilder sb = new StringBuilder();
88 StringBuilder sb = new StringBuilder();
97
89
98 sb.append(major).append(".").append(minor).append(".").append(patch);
90 sb.append(major).append(".").append(minor).append(".").append(patch);
99 getSuffix().ifPresent(s -> sb.append("-").append(s));
91 getPreRelease().ifPresent(s -> sb.append("-").append(s));
100 getMeta().ifPresent(m -> sb.append("+").append(m));
92 getMeta().ifPresent(m -> sb.append("+").append(m));
101
93
102 return sb.toString();
94 return sb.toString();
@@ -112,67 +104,92 public class SemVersion implements Seria
112 return res;
104 return res;
113 res = Integer.compare(patch, other.patch);
105 res = Integer.compare(patch, other.patch);
114
106
115 return getSuffix()
107 return getPreRelease()
116 // if we have suffix, chech another suffix, if there is no another suffix
108 // if we have suffix, check the other version suffix,
117 // then another version is bigger: 1.0.0-rc < 1.0.0
109 // if the other has no suffix then it's greater.
118 .map(s1 -> other.getSuffix().map(s2 -> s1.compareTo(s2)).orElse(-1))
110 // 1.0.0-rc < 1.0.0
111 .map(s1 -> other.getPreRelease().map(s2 -> s1.compareTo(s2)).orElse(-1))
119 // if we don't have the suffix
112 // if we don't have the suffix
120 .orElse(other.getSuffix().isPresent() ? 1 : 0);
113 .orElse(other.getPreRelease().isPresent() ? 1 : 0);
121
114
122 }
115 }
123
116
124 public SemVersion release() {
117 /** Removes the tag (pre-release and meta information) */
118 public SemVersion withNoSuffix() {
125 return new SemVersion(major, minor, patch, null, null);
119 return new SemVersion(major, minor, patch, null, null);
126 }
120 }
127
121
128 public SemVersion suffix(String suffix) {
122 /** Sets the specified suffix leaving other parts unchanged */
129 return new SemVersion(major, minor, patch, suffix, meta);
123 public SemVersion withPreRelease(String preRelease) {
124 return new SemVersion(major, minor, patch, preRelease, meta);
130 }
125 }
131
126
132 public SemVersion suffix() {
127 /** Removes pre-release information leaving other parts unchanged */
128 public SemVersion withNoPreRelease() {
133 return new SemVersion(major, minor, patch, null, meta);
129 return new SemVersion(major, minor, patch, null, meta);
134 }
130 }
135
131
136 public SemVersion meta(String meta) {
132 /** Sets the specified build metadata */
137 return new SemVersion(major, minor, patch, suffix, meta);
133 public SemVersion withMeta(String meta) {
134 return new SemVersion(major, minor, patch, preRelease, meta);
138 }
135 }
139
136
140 public SemVersion meta() {
137 /** Removes the build metadata from the version */
141 return new SemVersion(major, minor, patch, suffix, null);
138 public SemVersion withNoMeta() {
139 return new SemVersion(major, minor, patch, preRelease, null);
142 }
140 }
143
141
144 public SemVersion patch(int patch) {
142 /** Sets the specified patch version */
145 return new SemVersion(major, minor, patch, suffix, meta);
143 public SemVersion withPatch(int patch) {
144 return new SemVersion(major, minor, patch, preRelease, meta);
146 }
145 }
147
146
148 public SemVersion minor(int minor) {
147 /** Sets the specified minor version */
149 return new SemVersion(major, minor, patch, suffix, meta);
148 public SemVersion withMinor(int minor) {
149 return new SemVersion(major, minor, patch, preRelease, meta);
150 }
150 }
151
151
152 public SemVersion major(int major) {
152 /** Sets the specified major version */
153 return new SemVersion(major, minor, patch, suffix, meta);
153 public SemVersion withMajor(int major) {
154 return new SemVersion(major, minor, patch, preRelease, meta);
154 }
155 }
155
156
157 /** Adds the specified number to the patch version */
156 public SemVersion addPatch(int number) {
158 public SemVersion addPatch(int number) {
157 return new SemVersion(major, minor, patch + number, suffix, meta);
159 return new SemVersion(major, minor, patch + number, preRelease, meta);
158 }
160 }
159
161
162 /** Adds the specified number to the minor version */
160 public SemVersion addMinor(int number) {
163 public SemVersion addMinor(int number) {
161 return new SemVersion(major, minor + number, patch, suffix, meta);
164 return new SemVersion(major, minor + number, patch, preRelease, meta);
162 }
165 }
163
166
167 /** Adds the specified number to the major version */
164 public SemVersion addMajor(int number) {
168 public SemVersion addMajor(int number) {
165 return new SemVersion(major + number, minor, patch, suffix, meta);
169 return new SemVersion(major + number, minor, patch, preRelease, meta);
166 }
170 }
167
171
172 /** Generated the next minor version by incrementing the minor version,
173 * setting the patch version to 0 and removing the pre-release information.
174 * The build metadata is left unchanged.
175 *
176 * <p>Use this method to publish next minor version.
177 */
168 public SemVersion nextMinor() {
178 public SemVersion nextMinor() {
169 return new SemVersion(major, minor + 1, 0, null, meta);
179 return new SemVersion(major, minor + 1, 0, null, meta);
170 }
180 }
171
181
182 /** Generated the next minor version by incrementing the major version,
183 * setting the minor version and the patch to 0 and removing the
184 * pre-release information. The build metadata is left unchanged.
185 *
186 * <p>Use this method to publish next major version.
187 */
172 public SemVersion nextMajor() {
188 public SemVersion nextMajor() {
173 return new SemVersion(major + 1, 0, 0, null, meta);
189 return new SemVersion(major + 1, 0, 0, null, meta);
174 }
190 }
175
191
192 /** Parses the version string. */
176 public static Optional<SemVersion> tryParse(@Nonnull String str) {
193 public static Optional<SemVersion> tryParse(@Nonnull String str) {
177 Objects.requireNonNull(str);
194 Objects.requireNonNull(str);
178
195
@@ -183,6 +200,7 public class SemVersion implements Seria
183 : Optional.empty();
200 : Optional.empty();
184 }
201 }
185
202
203 /** Parses the version string. When */
186 public static Optional<SemVersion> tryParseLax(@Nonnull String str) {
204 public static Optional<SemVersion> tryParseLax(@Nonnull String str) {
187 Objects.requireNonNull(str);
205 Objects.requireNonNull(str);
188
206
@@ -198,10 +216,11 public class SemVersion implements Seria
198 if (value == null) {
216 if (value == null) {
199 return new SemVersion();
217 return new SemVersion();
200 } else if (value instanceof SemVersion) {
218 } else if (value instanceof SemVersion) {
201 return new SemVersion((SemVersion) value);
219 return (SemVersion) value;
202 } else {
220 } else {
203 Optional<SemVersion> semver = strict ? tryParse(value.toString()) : tryParseLax(value.toString());
221 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)));
222 return semver.orElseThrow(() -> new IllegalArgumentException(
223 String.format("Failed to parse semver '%s', strict=%s", value, strict)));
205 }
224 }
206 }
225 }
207
226
@@ -10,12 +10,11 import org.gradle.api.DefaultTask;
10 import org.gradle.api.model.ObjectFactory;
10 import org.gradle.api.model.ObjectFactory;
11 import org.gradle.api.provider.ListProperty;
11 import org.gradle.api.provider.ListProperty;
12 import org.gradle.api.provider.Property;
12 import org.gradle.api.provider.Property;
13 import org.gradle.api.tasks.Internal;
13 import org.gradle.api.tasks.TaskAction;
14 import org.gradle.api.tasks.TaskAction;
14 import org.implab.gradle.Utils;
15 import org.implab.gradle.Utils;
15 import org.implab.gradle.mercurial.MercurialExtension;
16 import org.implab.gradle.mercurial.MercurialExtension;
16
17
17 import groovy.transform.Internal;
18
19 public class HgBookmark extends DefaultTask {
18 public class HgBookmark extends DefaultTask {
20
19
21 private final Property<String> cliCmd;
20 private final Property<String> cliCmd;
@@ -28,6 +27,7 public class HgBookmark extends DefaultT
28
27
29 private String commandOutput;
28 private String commandOutput;
30
29
30 @Internal
31 protected MercurialExtension getMercurialExtension() {
31 protected MercurialExtension getMercurialExtension() {
32 return getProject().getExtensions().getByType(MercurialExtension.class);
32 return getProject().getExtensions().getByType(MercurialExtension.class);
33 }
33 }
@@ -10,14 +10,11 import org.gradle.api.DefaultTask;
10 import org.gradle.api.model.ObjectFactory;
10 import org.gradle.api.model.ObjectFactory;
11 import org.gradle.api.provider.ListProperty;
11 import org.gradle.api.provider.ListProperty;
12 import org.gradle.api.provider.Property;
12 import org.gradle.api.provider.Property;
13 import org.gradle.api.tasks.Input;
13 import org.gradle.api.tasks.Internal;
14 import org.gradle.api.tasks.SkipWhenEmpty;
15 import org.gradle.api.tasks.TaskAction;
14 import org.gradle.api.tasks.TaskAction;
16 import org.implab.gradle.Utils;
15 import org.implab.gradle.Utils;
17 import org.implab.gradle.mercurial.MercurialExtension;
16 import org.implab.gradle.mercurial.MercurialExtension;
18
17
19 import groovy.transform.Internal;
20
21 public class HgTag extends DefaultTask {
18 public class HgTag extends DefaultTask {
22
19
23 private final Property<String> cliCmd;
20 private final Property<String> cliCmd;
@@ -28,6 +25,7 public class HgTag extends DefaultTask {
28
25
29 private String commandOutput;
26 private String commandOutput;
30
27
28 @Internal
31 protected MercurialExtension getMercurialExtension() {
29 protected MercurialExtension getMercurialExtension() {
32 return getProject().getExtensions().getByType(MercurialExtension.class);
30 return getProject().getExtensions().getByType(MercurialExtension.class);
33 }
31 }
@@ -52,8 +50,7 public class HgTag extends DefaultTask {
52 return commandOutput;
50 return commandOutput;
53 }
51 }
54
52
55 @Input
53 @Internal
56 @SkipWhenEmpty
57 public ListProperty<String> getTags() {
54 public ListProperty<String> getTags() {
58 return tags;
55 return tags;
59 }
56 }
@@ -7,6 +7,7 import java.util.List;
7 import org.gradle.api.DefaultTask;
7 import org.gradle.api.DefaultTask;
8 import org.gradle.api.provider.Property;
8 import org.gradle.api.provider.Property;
9 import org.gradle.api.provider.Provider;
9 import org.gradle.api.provider.Provider;
10 import org.gradle.api.tasks.Internal;
10 import org.gradle.api.tasks.TaskAction;
11 import org.gradle.api.tasks.TaskAction;
11 import org.implab.gradle.Utils;
12 import org.implab.gradle.Utils;
12 import org.implab.gradle.mercurial.MercurialExtension;
13 import org.implab.gradle.mercurial.MercurialExtension;
@@ -19,6 +20,7 public class HgTask extends DefaultTask
19
20
20 private String commandOutput;
21 private String commandOutput;
21
22
23 @Internal
22 protected MercurialExtension getMercurialExtension() {
24 protected MercurialExtension getMercurialExtension() {
23 return getProject().getExtensions().getByType(MercurialExtension.class);
25 return getProject().getExtensions().getByType(MercurialExtension.class);
24 }
26 }
@@ -29,6 +31,7 public class HgTask extends DefaultTask
29
31
30 }
32 }
31
33
34 @Internal
32 public String getCommandOutput() {
35 public String getCommandOutput() {
33 return commandOutput;
36 return commandOutput;
34 }
37 }
General Comments 0
You need to be logged in to leave comments. Login now