diff --git a/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/META-INF/MANIFEST.MF b/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..fbceba0885 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/META-INF/MANIFEST.MF @@ -0,0 +1,6 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Test Artifact +Bundle-SymbolicName: test.artifact +Bundle-Version: 1.0.0.qualifier +Bundle-RequiredExecutionEnvironment: JavaSE-17 diff --git a/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/pom.xml b/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/pom.xml new file mode 100644 index 0000000000..91ef4d25e2 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/set-version/ci_friendly/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + test.artifact + org.tycho.its + eclipse-plugin + + 1.0.0-SNAPSHOT + + ${revision} + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java index a29635d0b6..c20600c256 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java @@ -364,6 +364,26 @@ public void testUpdatePomsOfModularPom() throws Exception { } + @Test + public void testCiFriendlyVersion() throws Exception { + String expectedNewVersion = "2.0.0-SNAPSHOT"; + String expectedNewOSGiVersion = "2.0.0.qualifier"; + + Verifier verifier = getVerifier("tycho-version-plugin/set-version/ci_friendly", false); + + verifier.addCliOption("-DnewVersion=" + expectedNewVersion); + verifier.executeGoal("org.eclipse.tycho:tycho-versions-plugin:" + VERSION + ":set-version"); + + verifier.verifyErrorFreeLog(); + + MavenXpp3Reader pomReader = new MavenXpp3Reader(); + Model pomModel = pomReader.read(new FileReader(new File(verifier.getBasedir(), "pom.xml"))); + assertEquals("${revision}", pomModel.getVersion()); + assertEquals(expectedNewVersion, pomModel.getProperties().getProperty("revision")); + Manifest manifest = getManifest(verifier, "."); + assertEquals(expectedNewOSGiVersion, manifest.getMainAttributes().getValue(Constants.BUNDLE_VERSION)); + } + public static File file(Verifier verifier, String... path) { return Path.of(verifier.getBasedir(), path).toFile(); } diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/PomManipulator.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/PomManipulator.java index b77449b4f7..225039da61 100644 --- a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/PomManipulator.java +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/PomManipulator.java @@ -11,7 +11,8 @@ * Sonatype Inc. - initial API and implementation * Sebastien Arod - introduce VersionChangesDescriptor * Bachmann electronic GmbH. - #472579 - Support setting the version for pomless builds - * Christoph Läubrich - Bug 550313 - tycho-versions-plugin uses hard-coded polyglot file + * Christoph Läubrich - Bug 550313 - tycho-versions-plugin uses hard-coded polyglot file + * SAP SE - #3744 - ci-friendly version support *******************************************************************************/ package org.eclipse.tycho.versions.manipulation; @@ -20,13 +21,10 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Optional; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.codehaus.plexus.component.annotations.Component; import org.eclipse.tycho.versions.engine.MetadataManipulator; @@ -51,8 +49,6 @@ public class PomManipulator extends AbstractMetadataManipulator { public static final String HINT = POM; - private static final Pattern CI_FRIENDLY_EXPRESSION = Pattern.compile("\\$\\{(.+?)\\}"); - @Override public boolean addMoreChanges(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { PomFile pom = project.getMetadata(PomFile.class); @@ -116,14 +112,8 @@ public void applyChanges(ProjectMetadata project, VersionChangesDescriptor versi String version = Versions.toMavenVersion(change.getVersion()); String newVersion = Versions.toMavenVersion(change.getNewVersion()); if (isGavEquals(pom, change)) { - String v = pom.getVersion(); - if (isCiFriendly(v)) { - //applyPropertyChange(pom, version, newVersion); - Matcher m = CI_FRIENDLY_EXPRESSION.matcher(v.trim()); - List ciFriendlyProperties = new ArrayList(); - while (m.find()) { - ciFriendlyProperties.add(m.group(1)); - } + List ciFriendlyProperties = pom.getCiFriendlyVersionPropertyNames(); + if (!ciFriendlyProperties.isEmpty()) { if (ciFriendlyProperties.size() == 1) { //thats actually a simply property change applyPropertyChange(pomName, pom, ciFriendlyProperties.get(0), newVersion); diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/pom/PomFile.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/pom/PomFile.java index 4552718a10..f8b0ced8c7 100644 --- a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/pom/PomFile.java +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/pom/PomFile.java @@ -10,7 +10,8 @@ * Contributors: * Sonatype Inc. - initial API and implementation * Bachmann electronic GmbH. - #472579 - Support setting the version for pomless builds - * Christoph Läubrich - Bug 550313 - tycho-versions-plugin uses hard-coded polyglot file + * Christoph Läubrich - Bug 550313 - tycho-versions-plugin uses hard-coded polyglot file + * SAP SE - #3744 - ci-friendly version support *******************************************************************************/ package org.eclipse.tycho.versions.pom; @@ -28,6 +29,10 @@ import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; import de.pdark.decentxml.Document; import de.pdark.decentxml.Element; @@ -43,13 +48,17 @@ public class PomFile { public static final String POM_XML = "pom.xml"; private static final String DEFAULT_XML_ENCODING = "UTF-8"; + private static final Pattern CI_FRIENDLY_EXPRESSION = Pattern.compile("\\$\\{(.+?)\\}"); + private static XMLParser parser = new XMLParser(); private Document document; private Element project; - /** The (effective) project version */ + /** The (raw) project version */ private String version; + /** The ${property}-resolved version, in case of ci-friendly versions */ + private String resolvedVersion; private final boolean preferExplicitProjectVersion; private final boolean isMutable; @@ -142,7 +151,7 @@ private static void removeVersionElementFromXML(Element project) { /** * Sets the version in the parent POM declaration. This never affects the (effective) version of * the project itself. - * + * * @see #setVersion(String) */ public void setParentVersion(String newVersion) { @@ -158,13 +167,35 @@ public void setParentVersion(String newVersion) { */ public void setVersion(String version) { this.version = version; + this.resolvedVersion = null; } /** * Returns the (effective) version of the project. */ public String getVersion() { - return version; + if (this.resolvedVersion == null) { + resolveCiFriendlyVersion(); + } + return this.resolvedVersion; + } + + /** + * Returns the list of property names that make up the <version> of the + * project. + *

+ * If this list is non-empty, the project uses ci-friendly versions. + */ + public List getCiFriendlyVersionPropertyNames() { + if (isCiFriendly(version)) { + Matcher m = CI_FRIENDLY_EXPRESSION.matcher(version.trim()); + List ciFriendlyProperties = new ArrayList(); + while (m.find()) { + ciFriendlyProperties.add(m.group(1)); + } + return ciFriendlyProperties; + } + return List.of(); } public String getPackaging() { @@ -245,4 +276,25 @@ private String getElementValue(String name) { public boolean isMutable() { return isMutable; } + + private static boolean isCiFriendly(String v) { + return v != null && v.contains("${"); + } + + private void resolveCiFriendlyVersion() { + if (isCiFriendly(version)) { + Map properties = getProperties().stream() + .collect(Collectors.toMap(p -> p.getName(), p -> p.getValue())); + StringBuilder resolvedVersionBuilder = new StringBuilder(); + Matcher m = CI_FRIENDLY_EXPRESSION.matcher(version.trim()); + while (m.find()) { + m.appendReplacement(resolvedVersionBuilder, properties.get(m.group(1))); + } + m.appendTail(resolvedVersionBuilder); + resolvedVersion = resolvedVersionBuilder.toString(); + } else { + resolvedVersion = version; + } + } + }