Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[tycho-4.0.x] tycho-versions-plugin: Support ci-friendly versions #3909

Merged
merged 1 commit into from
Jun 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.PomUtil;
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 = PomUtil.getContainedPropertyNames(pom.getRawVersion());
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)
&& !PomUtil.containsProperties(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 Down Expand Up @@ -48,8 +49,10 @@ public class PomFile {
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 +145,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 +161,24 @@ public void setParentVersion(String newVersion) {
*/
public void setVersion(String version) {
this.version = version;
this.resolvedVersion = null;
}

/**
* Returns the (effective) version of the project.
* Returns the (effective) version of the project with properties resolved.
*/
public String getVersion() {
return version;
if (this.resolvedVersion == null) {
this.resolvedVersion = PomUtil.expandProperties(version, getProperties());
}
return this.resolvedVersion;
}

/**
* Returns the literal version of the project without any properties resolved.
*/
public String getRawVersion() {
return this.version;
}

public String getPackaging() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*******************************************************************************
* 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;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class PomUtil {

private static final Pattern PROPERTY_PATTERN = Pattern.compile("\\$\\{(.+?)\\}");

/**
* Returns whether the string contains properties <code>${properties}</code>.
*/
public static boolean containsProperties(String str) {
return str != null && str.contains("${");
}

/**
* Expands properties in the given string.
* <p>
* If a property is not found it is left unexpanded.
*
* @param str
* the input string
* @param properties
* possible replacement properties
* @return the expanded string
*/
public static String expandProperties(String str, List<Property> properties) {
if (containsProperties(str)) {
StringBuilder resolvedVersionBuilder = new StringBuilder();
Matcher m = PROPERTY_PATTERN.matcher(str.trim());
while (m.find()) {
String unexpandedProperty = m.group();
String propertyName = m.group(1);
m.appendReplacement(resolvedVersionBuilder,
properties.stream().filter(p -> p.getName().equals(propertyName)).map(p -> p.getValue())
.findFirst().orElse(unexpandedProperty));
}
m.appendTail(resolvedVersionBuilder);
return resolvedVersionBuilder.toString();
} else {
return str;
}
}

/**
* Returns the list of property names that make up the given string.
*/
public static List<String> getContainedPropertyNames(String str) {
if (containsProperties(str)) {
Matcher m = PROPERTY_PATTERN.matcher(str.trim());
List<String> propertyNames = new ArrayList<>();
while (m.find()) {
propertyNames.add(m.group(1));
}
return Collections.unmodifiableList(propertyNames);
}
return List.of();
}
}
Loading