diff --git a/git-changelist-maven-extension/pom.xml b/git-changelist-maven-extension/pom.xml
index 58e5b0b..c31eee5 100644
--- a/git-changelist-maven-extension/pom.xml
+++ b/git-changelist-maven-extension/pom.xml
@@ -35,5 +35,11 @@
org.eclipse.jgit
4.9.0.201710071750-r
+
+ junit
+ junit
+ 4.13.2
+ test
+
diff --git a/git-changelist-maven-extension/src/main/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/Main.java b/git-changelist-maven-extension/src/main/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/Main.java
index ccd69a3..e01b2de 100644
--- a/git-changelist-maven-extension/src/main/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/Main.java
+++ b/git-changelist-maven-extension/src/main/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/Main.java
@@ -130,7 +130,7 @@ public void afterSessionStart(MavenSession session) throws MavenExecutionExcepti
throw new MavenExecutionException("Git operations failed", x);
}
log.debug("Spent " + (System.nanoTime() - start) / 1000 / 1000 + "ms on calculations");
- String value = String.format(props.getProperty("changelist.format", "-rc%d.%s"), count, hash);
+ String value = String.format(props.getProperty("changelist.format", "-rc%d.%s"), count, sanitize(hash));
log.info("Setting: -Dchangelist=" + value + " -DscmTag=" + fullHash);
props.setProperty("changelist", value);
props.setProperty("scmTag", fullHash);
@@ -172,6 +172,10 @@ public void afterSessionStart(MavenSession session) throws MavenExecutionExcepti
}
}
+ static String sanitize(String hash) {
+ return hash.replaceAll("[ab]", "$0_");
+ }
+
private static String summarize(RevCommit c) {
return c.getId().name() + " “" + c.getShortMessage() + "” " + DateTimeFormatter.ISO_LOCAL_DATE.format(Instant.ofEpochSecond(c.getCommitTime()).atZone(ZoneId.systemDefault()));
}
diff --git a/git-changelist-maven-extension/src/test/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/MainTest.java b/git-changelist-maven-extension/src/test/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/MainTest.java
new file mode 100644
index 0000000..c3646f7
--- /dev/null
+++ b/git-changelist-maven-extension/src/test/java/io/jenkins/tools/incrementals/git_changelist_maven_extension/MainTest.java
@@ -0,0 +1,55 @@
+/*
+ * The MIT License
+ *
+ * Copyright 2021 CloudBees, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+package io.jenkins.tools.incrementals.git_changelist_maven_extension;
+
+import org.apache.maven.artifact.versioning.ComparableVersion;
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.not;
+import static org.hamcrest.MatcherAssert.assertThat;
+import org.junit.Test;
+
+public class MainTest {
+
+ // https://maven.apache.org/pom.html#Version_Order_Specification
+ private static final String[] PRERELEASE = {
+ // From ComparableVersion.StringItem.QUALIFIERS:
+ "alpha", "beta", "milestone", "rc", "snapshot",
+ // ALIASES:
+ "cr",
+ // Nonstandard ones in Dependabot? https://github.com/dependabot/dependabot-core/blob/f146743aa400c7913b5e953e1b93c8b40345aaf4/maven/lib/dependabot/maven/version.rb#L24-L25
+ "pr", "dev",
+ };
+ @Test public void alphaBeta() {
+ String hash = "852b473a2b8c";
+ String sanitized = Main.sanitize(hash);
+ assertThat(hash + " has been sanitized to the expected format", sanitized, is("852b_473a_2b_8c"));
+ String canonical = new ComparableVersion(sanitized).getCanonical();
+ for (String prerelease : PRERELEASE) {
+ assertThat(sanitized + " treated as a prerelease", canonical, not(containsString(prerelease)));
+ }
+ }
+
+}