Skip to content

Commit

Permalink
tycho-versions-plugin: Support ci-friendly versions
Browse files Browse the repository at this point in the history
In PomFile#getVersion(), resolve properties used in the raw version of
the project. This is necessary so that downstream manipulators
(MANIFEST.MF, feature.xml, category.xml, ...) can see the actual version
and act on it.

Fixes #3744.
  • Loading branch information
sratz committed May 31, 2024
1 parent 13489c6 commit 19c4722
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<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/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>
<artifactId>test.artifact</artifactId>
<groupId>org.tycho.its</groupId>
<packaging>eclipse-plugin</packaging>
<properties>
<revision>1.0.0-SNAPSHOT</revision>
</properties>
<version>${revision}</version>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -40,6 +38,7 @@
import org.eclipse.tycho.versions.pom.Plugin;
import org.eclipse.tycho.versions.pom.PluginManagement;
import org.eclipse.tycho.versions.pom.PomFile;
import org.eclipse.tycho.versions.pom.PomVersionsUtil;
import org.eclipse.tycho.versions.pom.Profile;
import org.eclipse.tycho.versions.pom.Property;

Expand All @@ -51,8 +50,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);
Expand Down Expand Up @@ -116,14 +113,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<String> ciFriendlyProperties = new ArrayList<String>();
while (m.find()) {
ciFriendlyProperties.add(m.group(1));
}
List<String> ciFriendlyProperties = pom.getCiFriendlyVersionPropertyNames();
if (!ciFriendlyProperties.isEmpty()) {
if (ciFriendlyProperties.size() == 1) {
//thats actually a simply property change
applyPropertyChange(pomName, pom, ciFriendlyProperties.get(0), newVersion);
Expand All @@ -148,7 +139,8 @@ public void applyChanges(ProjectMetadata project, VersionChangesDescriptor versi
}
} else {
GAV parent = pom.getParent();
if (parent != null && isGavEquals(parent, change) && !isCiFriendly(parent.getVersion())) {
if (parent != null && isGavEquals(parent, change)
&& !PomVersionsUtil.isCiFriendlyVersion(parent.getVersion())) {
logger.info(" %s//project/parent/version: %s => %s".formatted(pomName, version, newVersion));
parent.setVersion(newVersion);
}
Expand Down Expand Up @@ -180,10 +172,6 @@ public void applyChanges(ProjectMetadata project, VersionChangesDescriptor versi

}

private boolean isCiFriendly(String v) {
return v != null && v.contains("${");
}

protected void changeDependencyManagement(String pomPath, DependencyManagement dependencyManagment,
PomVersionChange change, String version, String newVersion) {
if (dependencyManagment != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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) {
Expand All @@ -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) {
this.resolvedVersion = resolveCiFriendlyVersion();
}
return this.resolvedVersion;
}

/**
* Returns the list of property names that make up the <code>&lt;version&gt;</code> of the
* project.
* <p>
* If this list is non-empty, the project uses ci-friendly versions.
*/
public List<String> getCiFriendlyVersionPropertyNames() {
if (PomVersionsUtil.isCiFriendlyVersion(version)) {
Matcher m = CI_FRIENDLY_EXPRESSION.matcher(version.trim());
List<String> ciFriendlyProperties = new ArrayList<String>();
while (m.find()) {
ciFriendlyProperties.add(m.group(1));
}
return ciFriendlyProperties;
}
return List.of();
}

public String getPackaging() {
Expand Down Expand Up @@ -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 String resolveCiFriendlyVersion() {
if (isCiFriendly(version)) {
Map<String, String> 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);
return resolvedVersionBuilder.toString();
} else {
return version;
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2024 SAP SE and others.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* SAP SE - initial API and implementation
*******************************************************************************/
package org.eclipse.tycho.versions.pom;

public class PomVersionsUtil {

/**
* Returns whether the version is ci-friendy, i.e. is made up of one or more
* <code>${properties}</code>.
*/
public static boolean isCiFriendlyVersion(String version) {
return version != null && version.contains("${");
}
}

0 comments on commit 19c4722

Please sign in to comment.