From 44731f0974d0f8b0ab1b9be21c7cfaf2ec14ab12 Mon Sep 17 00:00:00 2001 From: "frederic.thomas" Date: Sun, 14 Apr 2019 16:56:47 +0100 Subject: [PATCH] Fix: Issue with the next development version logic. The next development version is computed by increment of one, for either the buildNumber when present or the patch version even when those one are set to zero. The current logic does not allow us to use the patch version for hotfixes only. For example, given a current development version 6.144.0-SNAPSHOT, if the logic is to increment the patch version, at release time, the plugin will propose 6.144.1-SNAPSHOT but I need 6.145.0-SNAPSHOT and I will have to manually update the next development version manually and that at every single release. Now, if we change the logic to increment only when it is not zero, I only need to change the next development version when a major change is required, the rest of the time the desired version part will be incremented automatically. The new logic would propose by default, given a strategy: release version ==> next development version : UNKNOWN : 6.0.0 ==> 6.0.1-SNAPSHOT UNKNOWN : 6.1.0 ==> 6.1.1-SNAPSHOT UNKNOWN : 6.0.1 ==> 6.0.2-SNAPSHOT UNKNOWN : 6.1.0-0 ==> 6.1.1-SNAPSHOT UNKNOWN : 6.1.0-22 ==> 6.1.0-23-SNAPSHOT UNKNOWN : 6.1 ==> 6.1.1-SNAPSHOT UNKNOWN : 6 ==> 6.0.1-SNAPSHOT DEFAULT : 6.0.0 ==> 6.0.1-SNAPSHOT DEFAULT : 6.1.0 ==> 6.1.1-SNAPSHOT DEFAULT : 6.0.1 ==> 6.0.2-SNAPSHOT DEFAULT : 6.1.0-0 ==> 6.1.1-SNAPSHOT DEFAULT : 6.1.0-22 ==> 6.1.0-23-SNAPSHOT DEFAULT : 6.1 ==> 6.1.1-SNAPSHOT DEFAULT : 6 ==> 6.0.1-SNAPSHOT IGNORE_ZEROS : 6.0.0 ==> 7.0.0-SNAPSHOT IGNORE_ZEROS : 6.1.0 ==> 6.2.0-SNAPSHOT IGNORE_ZEROS : 6.0.1 ==> 6.0.2-SNAPSHOT IGNORE_ZEROS : 6.1.0-0 ==> 6.2.0-SNAPSHOT IGNORE_ZEROS : 6.1.0-22 ==> 6.1.0-23-SNAPSHOT IGNORE_ZEROS : 6.1 ==> 6.2.0-SNAPSHOT IGNORE_ZEROS : 6 ==> 7.0.0-SNAPSHOT Everything works almost as before except for when the lowest version part is zero. --- pom.xml | 5 ++ server/pom.xml | 4 ++ .../project/BaseReleaseManagementTab.java | 9 +++ .../project/ReleaseManagementConfigModel.java | 59 ++++++++------- .../strategy/NextDevelopmentVersion.java | 71 +++++++++++++++++++ .../NextDevelopmentVersionStrategy.java | 7 ++ .../ReleaseManagementConfigModelTest.java | 63 ++++++++++++++++ 7 files changed, 188 insertions(+), 30 deletions(-) create mode 100644 server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersion.java create mode 100644 server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersionStrategy.java create mode 100644 server/src/test/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModelTest.java diff --git a/pom.xml b/pom.xml index 9615ddd6..4e4bb706 100644 --- a/pom.xml +++ b/pom.xml @@ -246,6 +246,11 @@ 1.3 test + + org.codehaus.mojo + build-helper-maven-plugin + 3.0.0 + diff --git a/server/pom.xml b/server/pom.xml index 97f24415..e160f7c0 100644 --- a/server/pom.xml +++ b/server/pom.xml @@ -96,5 +96,9 @@ org.apache.ivy ivy + + org.codehaus.mojo + build-helper-maven-plugin + diff --git a/server/src/main/java/org/jfrog/teamcity/server/project/BaseReleaseManagementTab.java b/server/src/main/java/org/jfrog/teamcity/server/project/BaseReleaseManagementTab.java index 60ebf906..9546040e 100644 --- a/server/src/main/java/org/jfrog/teamcity/server/project/BaseReleaseManagementTab.java +++ b/server/src/main/java/org/jfrog/teamcity/server/project/BaseReleaseManagementTab.java @@ -13,6 +13,7 @@ import org.jetbrains.annotations.Nullable; import org.jfrog.teamcity.common.RunnerParameterKeys; import org.jfrog.teamcity.server.global.DeployableArtifactoryServers; +import org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; @@ -20,6 +21,7 @@ import java.util.Map; import static org.jfrog.teamcity.common.ConstantValues.NAME; +import static org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion.StrategyEnum.valueOf; /** * @author Noam Y. Tenne @@ -78,6 +80,13 @@ public void fillModel(@NotNull Map model, @NotNull HttpServletRe // fill default values to the model ReleaseManagementConfigModel managementConfig = getReleaseManagementConfigModel(); + final Map configParameters = buildType.getConfigParameters(); + final String nextDevelopmentVersionStrategy = configParameters.get(NextDevelopmentVersion.PARAMETER_NAME); + + try { + managementConfig.setNextDevelopmentVersionStrategy(valueOf(nextDevelopmentVersionStrategy.toUpperCase())); + } catch (IllegalArgumentException ignored) {} + Map parameters = buildRunner.get(0).getParameters(); if (parameters.containsKey(RunnerParameterKeys.GIT_RELEASE_BRANCH_NAME_PREFIX)) { managementConfig.setGitReleaseBranchNamePrefix( diff --git a/server/src/main/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModel.java b/server/src/main/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModel.java index 36b2dbff..982c6088 100644 --- a/server/src/main/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModel.java +++ b/server/src/main/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModel.java @@ -19,6 +19,8 @@ import com.google.common.collect.Lists; import jetbrains.buildServer.serverSide.BranchEx; import org.apache.commons.lang.StringUtils; +import org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion.StrategyEnum; +import org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersionStrategy; import java.util.List; @@ -41,6 +43,7 @@ public abstract class ReleaseManagementConfigModel { private boolean selectedArtifactoryServerHasAddons = false; private List deployableRepoKeys = Lists.newArrayList(); private BranchEx defaultCheckoutBranch; + private NextDevelopmentVersionStrategy nextDevelopmentVersionStrategy; public void setRootArtifactId(String rootArtifactId) { this.rootArtifactId = rootArtifactId; @@ -59,33 +62,29 @@ public String getReleaseVersion() { } public String getNextDevelopmentVersion() { - String fromVersion = getReleaseVersion(); - String nextVersion; - int lastDotIndex = fromVersion.lastIndexOf('.'); - try { - if (lastDotIndex != -1) { - // probably a major minor version e.g., 2.1.1 - String minorVersionToken = fromVersion.substring(lastDotIndex + 1); - String nextMinorVersion; - int lastDashIndex = minorVersionToken.lastIndexOf('-'); - if (lastDashIndex != -1) { - // probably a minor-buildNum e.g., 2.1.1-4 (should change to 2.1.1-5) - String buildNumber = minorVersionToken.substring(lastDashIndex + 1); - int nextBuildNumber = Integer.parseInt(buildNumber) + 1; - nextMinorVersion = minorVersionToken.substring(0, lastDashIndex + 1) + nextBuildNumber; - } else { - nextMinorVersion = Integer.toString(Integer.parseInt(minorVersionToken) + 1); - } - nextVersion = fromVersion.substring(0, lastDotIndex + 1) + nextMinorVersion; - } else { - // maybe it's just a major version; try to parse as an int - int nextMajorVersion = Integer.parseInt(fromVersion) + 1; - nextVersion = Integer.toString(nextMajorVersion); - } - } catch (NumberFormatException e) { - return fromVersion; + if (nextDevelopmentVersionStrategy == null) { + nextDevelopmentVersionStrategy = StrategyEnum.DEFAULT; } - return nextVersion + "-SNAPSHOT"; + final List versionParts = nextDevelopmentVersionStrategy.apply(getReleaseVersion()); + final StringBuilder nextVersion = new StringBuilder(); + + int buildNumber = versionParts.get(0); + int patch = versionParts.get(1); + int minor = versionParts.get(2); + int major = versionParts.get(3); + + nextVersion.append( major ); + nextVersion.append(".").append(minor); + nextVersion.append(".").append(patch); + + if ( buildNumber > 0 ) + { + nextVersion.append("-").append(buildNumber); + } + + nextVersion.append( "-SNAPSHOT" ); + + return nextVersion.toString(); } public abstract String getDefaultTagUrl(); @@ -120,10 +119,6 @@ public String getTagComment() { return COMMIT_COMMENT_PREFIX + "Release version " + getReleaseVersion(); } - public String getDefaultNextDevelopmentVersionComment() { - return COMMIT_COMMENT_PREFIX + "Next development version"; - } - public boolean isGitVcs() { return gitVcs; } @@ -160,6 +155,10 @@ public void setDefaultCheckoutBranch(BranchEx defaultCheckoutBranch) { this.defaultCheckoutBranch = defaultCheckoutBranch; } + public void setNextDevelopmentVersionStrategy(NextDevelopmentVersionStrategy nextDevelopmentVersionStrategy) { + this.nextDevelopmentVersionStrategy = nextDevelopmentVersionStrategy; + } + protected String getVcsSpecificTagBaseUrlOrName() { if (StringUtils.isBlank(vcsTagBaseUrlOrName)) { return ""; diff --git a/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersion.java b/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersion.java new file mode 100644 index 00000000..003eaaaf --- /dev/null +++ b/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersion.java @@ -0,0 +1,71 @@ +package org.jfrog.teamcity.server.project.strategy; + +import org.codehaus.mojo.buildhelper.versioning.VersionInformation; +import org.jfrog.teamcity.common.ConstantValues; + +import java.util.ArrayList; +import java.util.List; +import java.util.ListIterator; + +public class NextDevelopmentVersion { + private final static String PREFIX = ConstantValues.PLUGIN_PREFIX + "releaseManagement."; + public final static String PARAMETER_NAME = PREFIX + "nextDevelopmentVersionStrategy"; + + public enum StrategyEnum implements NextDevelopmentVersionStrategy { + DEFAULT(), + IGNORE_ZEROS(); + + public List apply(String releaseVersion) { + final VersionInformation versionInformation = new VersionInformation(releaseVersion); + final List versionParts = new ArrayList(); + + versionParts.add(versionInformation.getBuildNumber()); + versionParts.add(versionInformation.getPatch()); + versionParts.add(versionInformation.getMinor()); + versionParts.add(versionInformation.getMajor()); + + ListIterator listIterator = versionParts.listIterator(); + boolean done = false; + + while (!done && listIterator.hasNext()) { + switch (this) { + + case IGNORE_ZEROS: + done = applyIgnoreZero(listIterator); + break; + + case DEFAULT: + default: + done = applyDefault(listIterator); + break; + } + } + + return versionParts; + } + } + + private static boolean applyDefault(ListIterator i) { + int versionPart = i.next(); + boolean done = false; + + if (i.previousIndex() + versionPart > 0) { + i.set(versionPart + 1); + done = true; + } + + return done; + } + + private static boolean applyIgnoreZero(ListIterator i) { + int versionPart = i.next(); + boolean done = false; + + if (versionPart > 0) { + i.set(versionPart + 1); + done = true; + } + + return done; + } +} diff --git a/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersionStrategy.java b/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersionStrategy.java new file mode 100644 index 00000000..7de6696e --- /dev/null +++ b/server/src/main/java/org/jfrog/teamcity/server/project/strategy/NextDevelopmentVersionStrategy.java @@ -0,0 +1,7 @@ +package org.jfrog.teamcity.server.project.strategy; + +import java.util.List; + +public interface NextDevelopmentVersionStrategy { + List apply(String releaseVersion); +} diff --git a/server/src/test/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModelTest.java b/server/src/test/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModelTest.java new file mode 100644 index 00000000..fc2c8419 --- /dev/null +++ b/server/src/test/java/org/jfrog/teamcity/server/project/ReleaseManagementConfigModelTest.java @@ -0,0 +1,63 @@ +package org.jfrog.teamcity.server.project; + +import org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion.StrategyEnum; +import org.testng.Assert; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import static org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion.StrategyEnum.DEFAULT; +import static org.jfrog.teamcity.server.project.strategy.NextDevelopmentVersion.StrategyEnum.IGNORE_ZEROS; + +public class ReleaseManagementConfigModelTest { + private final static StrategyEnum UNKNOWN = null; + + private ReleaseManagementConfigModel instance = new ReleaseManagementConfigModel() { + @Override + public String getDefaultTagUrl() { + return null; + } + + @Override + public String getDefaultReleaseBranch() { + return null; + } + }; + + @DataProvider(name = "data-provider") + public Object[][] dataProviderMethod() { + return new Object[][]{ + {UNKNOWN, "6.0.0", "6.0.1-SNAPSHOT"}, + {UNKNOWN, "6.1.0", "6.1.1-SNAPSHOT"}, + {UNKNOWN, "6.0.1", "6.0.2-SNAPSHOT"}, + {UNKNOWN, "6.1.0-0", "6.1.1-SNAPSHOT"}, + {UNKNOWN, "6.1.0-22", "6.1.0-23-SNAPSHOT"}, + {UNKNOWN, "6.1", "6.1.1-SNAPSHOT"}, + {UNKNOWN, "6", "6.0.1-SNAPSHOT"}, + + {DEFAULT, "6.0.0", "6.0.1-SNAPSHOT"}, + {DEFAULT, "6.1.0", "6.1.1-SNAPSHOT"}, + {DEFAULT, "6.0.1", "6.0.2-SNAPSHOT"}, + {DEFAULT, "6.1.0-0", "6.1.1-SNAPSHOT"}, + {DEFAULT, "6.1.0-22", "6.1.0-23-SNAPSHOT"}, + {DEFAULT, "6.1", "6.1.1-SNAPSHOT"}, + {DEFAULT, "6", "6.0.1-SNAPSHOT"}, + + {IGNORE_ZEROS, "6.0.0", "7.0.0-SNAPSHOT"}, + {IGNORE_ZEROS, "6.1.0", "6.2.0-SNAPSHOT"}, + {IGNORE_ZEROS, "6.0.1", "6.0.2-SNAPSHOT"}, + {IGNORE_ZEROS, "6.1.0-0", "6.2.0-SNAPSHOT"}, + {IGNORE_ZEROS, "6.1.0-22", "6.1.0-23-SNAPSHOT"}, + {IGNORE_ZEROS, "6.1", "6.2.0-SNAPSHOT"}, + {IGNORE_ZEROS, "6", "7.0.0-SNAPSHOT"}}; + } + + @Test(dataProvider = "data-provider") + public void testGetNextDevelopmentVersion(StrategyEnum strategy, String releaseVersion, String expected) { + instance.setNextDevelopmentVersionStrategy(strategy); + instance.setCurrentVersion(releaseVersion); + + final String current = instance.getNextDevelopmentVersion(); + + Assert.assertEquals(current, expected); + } +} \ No newline at end of file