Skip to content

Commit e8b4c6d

Browse files
committed
Add new version-update goal - closes #269
Can be used to update version in release or support branch, optionally tagging and pushing it to the remote repository.
1 parent e30d065 commit e8b4c6d

File tree

8 files changed

+351
-0
lines changed

8 files changed

+351
-0
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>com.amashchenko.maven.plugin</groupId>
4+
<artifactId>gitflow-maven-test</artifactId>
5+
<packaging>pom</packaging>
6+
<version>0.0.4</version>
7+
</project>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build.log
2+
expected-pom.xml
3+
invoker.properties
4+
init.bsh
5+
verify.bsh

src/it/version-update-it/init.bsh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
try {
2+
new File(basedir, "gitignorefile").renameTo(new File(basedir, ".gitignore"));
3+
4+
Process p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " init");
5+
p.waitFor();
6+
7+
Process p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " config user.email '[email protected]'");
8+
p.waitFor();
9+
Process p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " config user.name 'a'");
10+
p.waitFor();
11+
12+
p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " add .");
13+
p.waitFor();
14+
15+
p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " commit -m init");
16+
p.waitFor();
17+
18+
p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " branch develop");
19+
p.waitFor();
20+
21+
p = Runtime.getRuntime().exec("git --git-dir=" + basedir + "/.git --work-tree=" + basedir + " checkout -b release/0.0.3");
22+
p.waitFor();
23+
24+
} catch (Exception e) {
25+
e.printStackTrace();
26+
return false;
27+
}
28+
return true;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:version-update -B
2+
3+
invoker.description=Non-interactive simple version-update.

src/it/version-update-it/pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<groupId>com.amashchenko.maven.plugin</groupId>
4+
<artifactId>gitflow-maven-test</artifactId>
5+
<packaging>pom</packaging>
6+
<version>0.0.3</version>
7+
</project>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.codehaus.plexus.util.FileUtils;
2+
3+
try {
4+
File gitTag = new File(basedir, ".git/refs/tags/0.0.4");
5+
if (!gitTag.exists()) {
6+
System.out.println("update-version .git/refs/tags/0.0.4 does not exist");
7+
return false;
8+
}
9+
10+
File file = new File(basedir, "pom.xml");
11+
File expectedFile = new File(basedir, "expected-pom.xml");
12+
13+
String actual = FileUtils.fileRead(file, "UTF-8");
14+
String expected = FileUtils.fileRead(expectedFile, "UTF-8");
15+
16+
actual = actual.replaceAll("\\r?\\n", "");
17+
expected = expected.replaceAll("\\r?\\n", "");
18+
19+
if (!expected.equals(actual)) {
20+
System.out.println("update-version expected: " + expected + " actual was:" + actual);
21+
return false;
22+
}
23+
} catch (Exception e) {
24+
e.printStackTrace();
25+
return false;
26+
}
27+
return true;

src/main/java/com/amashchenko/maven/plugin/gitflow/CommitMessages.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public class CommitMessages {
4646

4747
private String tagHotfixMessage;
4848
private String tagReleaseMessage;
49+
private String tagVersionUpdateMessage;
4950

5051
private String updateDevToAvoidConflictsMessage;
5152
private String updateDevBackPreMergeStateMessage;
@@ -58,6 +59,8 @@ public class CommitMessages {
5859

5960
private String supportStartMessage;
6061

62+
private String versionUpdateMessage;
63+
6164
public CommitMessages() {
6265
featureStartMessage = System.getProperty("commitMessages.featureStartMessage", "Update versions for feature branch");
6366
featureFinishMessage = System.getProperty("commitMessages.featureFinishMessage", "Update versions for development branch");
@@ -86,6 +89,7 @@ public CommitMessages() {
8689

8790
tagHotfixMessage = System.getProperty("commitMessages.tagHotfixMessage", "Tag hotfix");
8891
tagReleaseMessage = System.getProperty("commitMessages.tagReleaseMessage", "Tag release");
92+
tagVersionUpdateMessage = System.getProperty("commitMessages.tagVersionUpdateMessage", "Tag version update");
8993

9094
updateDevToAvoidConflictsMessage = System.getProperty("commitMessages.updateDevToAvoidConflictsMessage",
9195
"Update develop to production version to avoid merge conflicts");
@@ -103,6 +107,8 @@ public CommitMessages() {
103107
"Increment feature version");
104108

105109
supportStartMessage = System.getProperty("commitMessages.supportStartMessage", "Update versions for support branch");
110+
111+
versionUpdateMessage = System.getProperty("commitMessages.versionUpdateMessage", "Update versions");
106112
}
107113

108114
/**
@@ -463,4 +469,32 @@ public String getSupportStartMessage() {
463469
public void setSupportStartMessage(String supportStartMessage) {
464470
this.supportStartMessage = supportStartMessage;
465471
}
472+
473+
/**
474+
* @return the tagVersionUpdateMessage
475+
*/
476+
public String getTagVersionUpdateMessage() {
477+
return tagVersionUpdateMessage;
478+
}
479+
480+
/**
481+
* @param tagVersionUpdateMessage the tagVersionUpdateMessage to set
482+
*/
483+
public void setTagVersionUpdateMessage(String tagVersionUpdateMessage) {
484+
this.tagVersionUpdateMessage = tagVersionUpdateMessage;
485+
}
486+
487+
/**
488+
* @return the versionUpdateMessage
489+
*/
490+
public String getVersionUpdateMessage() {
491+
return versionUpdateMessage;
492+
}
493+
494+
/**
495+
* @param versionUpdateMessage the versionUpdateMessage to set
496+
*/
497+
public void setVersionUpdateMessage(String versionUpdateMessage) {
498+
this.versionUpdateMessage = versionUpdateMessage;
499+
}
466500
}
Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
/*
2+
* Copyright 2014-2022 Aleksandr Mashchenko.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.amashchenko.maven.plugin.gitflow;
17+
18+
import java.util.ArrayList;
19+
import java.util.HashMap;
20+
import java.util.List;
21+
import java.util.Map;
22+
23+
import org.apache.maven.plugin.MojoExecutionException;
24+
import org.apache.maven.plugin.MojoFailureException;
25+
import org.apache.maven.plugins.annotations.Mojo;
26+
import org.apache.maven.plugins.annotations.Parameter;
27+
import org.apache.maven.shared.release.versions.VersionParseException;
28+
import org.codehaus.plexus.components.interactivity.PrompterException;
29+
import org.codehaus.plexus.util.StringUtils;
30+
import org.codehaus.plexus.util.cli.CommandLineException;
31+
32+
/**
33+
* Updates version in release or support branch, optionally tagging and pushing
34+
* it to the remote repository.
35+
*
36+
*/
37+
@Mojo(name = "version-update", aggregator = true)
38+
public class GitFlowVersionUpdateMojo extends AbstractGitFlowMojo {
39+
/**
40+
* Whether to push to the remote.
41+
*
42+
*/
43+
@Parameter(property = "pushRemote", defaultValue = "false")
44+
private boolean pushRemote;
45+
46+
/**
47+
* Branch to start update in non-interactive mode. Release branch or one of the
48+
* support branches.
49+
*
50+
*/
51+
@Parameter(property = "fromBranch")
52+
private String fromBranch;
53+
54+
/**
55+
* The version to use in non-interactive mode.
56+
*
57+
*/
58+
@Parameter(property = "updateVersion")
59+
private String updateVersion;
60+
61+
/**
62+
* Which digit to increment in the next version. Starts from zero.
63+
*
64+
*/
65+
@Parameter(property = "updateVersionDigitToIncrement")
66+
private Integer updateVersionDigitToIncrement;
67+
68+
/**
69+
* Whether to skip tagging the release in Git.
70+
*
71+
*/
72+
@Parameter(property = "skipTag", defaultValue = "false")
73+
private boolean skipTag = false;
74+
75+
/**
76+
* Whether to make a GPG-signed tag.
77+
*
78+
*/
79+
@Parameter(property = "gpgSignTag", defaultValue = "false")
80+
private boolean gpgSignTag = false;
81+
82+
/** {@inheritDoc} */
83+
@Override
84+
public void execute() throws MojoExecutionException, MojoFailureException {
85+
validateConfiguration();
86+
87+
try {
88+
initGitFlowConfig();
89+
90+
checkUncommittedChanges();
91+
92+
final String releaseBranch = gitFindBranches(gitFlowConfig.getReleaseBranchPrefix(), false);
93+
94+
String branchName = releaseBranch;
95+
96+
// find support branches
97+
final String supportBranchesStr = gitFindBranches(gitFlowConfig.getSupportBranchPrefix(), false);
98+
99+
if (StringUtils.isBlank(releaseBranch) && StringUtils.isBlank(supportBranchesStr)) {
100+
throw new MojoFailureException("There is no release or support branches.");
101+
}
102+
103+
final String[] supportBranches;
104+
if (StringUtils.isNotBlank(supportBranchesStr)) {
105+
supportBranches = supportBranchesStr.split("\\r?\\n");
106+
} else {
107+
supportBranches = null;
108+
}
109+
110+
if (settings.isInteractiveMode()) {
111+
if (supportBranches != null && supportBranches.length > 0) {
112+
String[] branches = new String[supportBranches.length + 1];
113+
for (int i = 0; i < supportBranches.length; i++) {
114+
branches[i] = supportBranches[i];
115+
}
116+
if (StringUtils.isNotBlank(releaseBranch)) {
117+
// add release branch to the list
118+
branches[supportBranches.length] = releaseBranch;
119+
}
120+
121+
List<String> numberedList = new ArrayList<>();
122+
StringBuilder str = new StringBuilder("Branches:").append(LS);
123+
for (int i = 0; i < branches.length; i++) {
124+
str.append((i + 1) + ". " + branches[i] + LS);
125+
numberedList.add(String.valueOf(i + 1));
126+
}
127+
str.append("Choose branch to update");
128+
129+
String branchNumber = null;
130+
try {
131+
while (StringUtils.isBlank(branchNumber)) {
132+
branchNumber = prompter.prompt(str.toString(), numberedList);
133+
}
134+
} catch (PrompterException e) {
135+
throw new MojoFailureException("version-update", e);
136+
}
137+
138+
if (branchNumber != null) {
139+
int num = Integer.parseInt(branchNumber);
140+
branchName = branches[num - 1];
141+
}
142+
}
143+
} else if (StringUtils.isNotBlank(fromBranch)) {
144+
if (fromBranch.equals(releaseBranch) || contains(supportBranches, fromBranch)) {
145+
branchName = fromBranch;
146+
} else {
147+
throw new MojoFailureException("The fromBranch is not release or support branch.");
148+
}
149+
}
150+
if (StringUtils.isBlank(branchName)) {
151+
throw new MojoFailureException("Branch name is blank.");
152+
}
153+
154+
gitCheckout(branchName);
155+
156+
// fetch and check remote
157+
if (fetchRemote) {
158+
gitFetchRemoteAndCompare(branchName);
159+
}
160+
161+
// get current project version from pom
162+
final String currentVersion = getCurrentProjectVersion();
163+
164+
// get default next version
165+
final String defaultVersion = new GitFlowVersionInfo(currentVersion, getVersionPolicy()).hotfixVersion(tychoBuild,
166+
updateVersionDigitToIncrement);
167+
168+
if (defaultVersion == null) {
169+
throw new MojoFailureException("Cannot get default next version.");
170+
}
171+
172+
String version = null;
173+
if (settings.isInteractiveMode()) {
174+
try {
175+
while (version == null) {
176+
version = prompter.prompt("What is the update version? [" + defaultVersion + "]");
177+
178+
if (!"".equals(version) && (!GitFlowVersionInfo.isValidVersion(version) || !validBranchName(version))) {
179+
getLog().info("The version is not valid.");
180+
version = null;
181+
}
182+
}
183+
} catch (PrompterException e) {
184+
throw new MojoFailureException("version-update", e);
185+
}
186+
} else {
187+
if (StringUtils.isNotBlank(updateVersion)
188+
&& (!GitFlowVersionInfo.isValidVersion(updateVersion) || !validBranchName(updateVersion))) {
189+
throw new MojoFailureException("The update version '" + updateVersion + "' is not valid.");
190+
} else {
191+
version = updateVersion;
192+
}
193+
}
194+
195+
if (StringUtils.isBlank(version)) {
196+
getLog().info("Version is blank. Using default version.");
197+
version = defaultVersion;
198+
}
199+
200+
Map<String, String> messageProperties = new HashMap<>();
201+
202+
// execute if version changed
203+
if (!version.equals(currentVersion)) {
204+
mvnSetVersions(version);
205+
206+
messageProperties.put("version", version);
207+
208+
gitCommit(commitMessages.getVersionUpdateMessage(), messageProperties);
209+
}
210+
211+
if (!skipTag) {
212+
messageProperties.put("version", version);
213+
214+
gitTag(gitFlowConfig.getVersionTagPrefix() + version, commitMessages.getTagVersionUpdateMessage(), gpgSignTag,
215+
messageProperties);
216+
}
217+
218+
if (installProject) {
219+
mvnCleanInstall();
220+
}
221+
222+
if (pushRemote) {
223+
gitPush(branchName, !skipTag);
224+
}
225+
} catch (CommandLineException | VersionParseException e) {
226+
throw new MojoFailureException("version-update", e);
227+
}
228+
}
229+
230+
private boolean contains(String[] arr, String str) {
231+
if (arr != null && str != null) {
232+
for (String a : arr) {
233+
if (str.equals(a)) {
234+
return true;
235+
}
236+
}
237+
}
238+
return false;
239+
}
240+
}

0 commit comments

Comments
 (0)