[MNG-8414] Warn when not able to downgrade consumer POM unless preserveModelVersion is forced to true (#1981)

This commit is contained in:
Guillaume Nodet 2024-12-14 00:10:59 +01:00 committed by GitHub
parent e600b09ea5
commit 5375f61a1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 158 additions and 1 deletions

View File

@ -44,6 +44,8 @@ import org.apache.maven.internal.impl.InternalSession;
import org.apache.maven.model.v4.MavenModelVersion;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystemSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Named
class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
@ -51,6 +53,8 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
public static final String POM_PACKAGING = "pom";
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultConsumerPomBuilder.class);
private final LifecycleBindingsInjector lifecycleBindingsInjector;
@Inject
@ -103,6 +107,7 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
static Model transform(Model model, MavenProject project) {
String packaging = model.getPackaging();
boolean preserveModelVersion = model.isPreserveModelVersion();
if (POM_PACKAGING.equals(packaging)) {
// raw to consumer transform
model = model.withRoot(false).withModules(null).withSubprojects(null);
@ -110,7 +115,7 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
model = model.withParent(model.getParent().withRelativePath(null));
}
if (!model.isPreserveModelVersion()) {
if (!preserveModelVersion) {
model = model.withPreserveModelVersion(false);
String modelVersion = new MavenModelVersion().getModelVersion(model);
model = model.withModelVersion(modelVersion);
@ -137,6 +142,9 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
model = builder.build();
String modelVersion = new MavenModelVersion().getModelVersion(model);
if (!ModelBuilder.MODEL_VERSION_4_0_0.equals(modelVersion) && !preserveModelVersion) {
warnNotDowngraded(project);
}
model = model.withModelVersion(modelVersion);
} else {
Model.Builder builder = prune(
@ -150,11 +158,22 @@ class DefaultConsumerPomBuilder implements ConsumerPomBuilder {
model = builder.build();
String modelVersion = new MavenModelVersion().getModelVersion(model);
if (!ModelBuilder.MODEL_VERSION_4_0_0.equals(modelVersion) && !preserveModelVersion) {
warnNotDowngraded(project);
}
model = model.withModelVersion(modelVersion);
}
return model;
}
static void warnNotDowngraded(MavenProject project) {
LOGGER.warn("The consumer POM for " + project.getId() + " cannot be downgraded to 4.0.0. "
+ "If you intent your build to be consumed with Maven 3 projects, you need to remove "
+ "the features that request a newer model version. If you're fine with having the "
+ "consumer POM not consumable with Maven 3, add the `preserve.model.version='true'` "
+ "attribute on the <project> element of your POM.");
}
private static List<Profile> prune(List<Profile> profiles) {
return profiles.stream()
.map(p -> {

View File

@ -0,0 +1,103 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.it;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.maven.api.model.Model;
import org.apache.maven.model.v4.MavenStaxReader;
import org.junit.jupiter.api.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-8414">MNG-8414</a>.
*/
class MavenITmng8414ConsumerPomWithNewFeaturesTest extends AbstractMavenIntegrationTestCase {
MavenITmng8414ConsumerPomWithNewFeaturesTest() {
super("[4.0.0-rc-2,)");
}
/**
* Verify behavior of the consumer POM when using a feature that require a newer model.
*/
@Test
void testNotPreserving() throws Exception {
Path basedir =
extractResources("/mng-8414-consumer-pom-with-new-features").toPath();
Verifier verifier = newVerifier(basedir.toString(), null);
verifier.addCliArguments("package");
verifier.execute();
verifier.verifyErrorFreeLog();
verifier.verifyTextInLog(
"The consumer POM for org.apache.maven.its:mng-8414:jar:1.0.0-SNAPSHOT cannot be downgraded to 4.0.0.");
Path consumerPom = basedir.resolve(Paths.get(
"target",
"project-local-repo",
"org.apache.maven.its",
"mng-8414",
"1.0.0-SNAPSHOT",
"mng-8414-1.0.0-SNAPSHOT-consumer.pom"));
assertTrue(Files.exists(consumerPom));
Model consumerPomModel;
try (Reader r = Files.newBufferedReader(consumerPom)) {
consumerPomModel = new MavenStaxReader().read(r);
}
assertEquals("4.1.0", consumerPomModel.getModelVersion());
}
/**
* Verify behavior of the consumer POM when using a feature that require a newer model.
*/
@Test
void testPreserving() throws Exception {
Path basedir =
extractResources("/mng-8414-consumer-pom-with-new-features").toPath();
Verifier verifier = newVerifier(basedir.toString(), null);
verifier.setLogFileName("log-preserving.txt");
verifier.addCliArguments("-f", "pom-preserving.xml", "package");
verifier.execute();
verifier.verifyErrorFreeLog();
verifier.verifyTextNotInLog("cannot be downgraded to 4.0.0.");
Path consumerPom = basedir.resolve(Paths.get(
"target",
"project-local-repo",
"org.apache.maven.its",
"mng-8414-preserving",
"1.0.0-SNAPSHOT",
"mng-8414-preserving-1.0.0-SNAPSHOT-consumer.pom"));
assertTrue(Files.exists(consumerPom));
Model consumerPomModel;
try (Reader r = Files.newBufferedReader(consumerPom)) {
consumerPomModel = new MavenStaxReader().read(r);
}
assertEquals("4.1.0", consumerPomModel.getModelVersion());
}
}

View File

@ -100,6 +100,7 @@ public class TestSuiteOrdering implements ClassOrderer {
* the tests are to finishing. Newer tests are also more likely to fail, so this is
* a fail fast technique as well.
*/
suite.addTestSuite(MavenITmng8414ConsumerPomWithNewFeaturesTest.class);
suite.addTestSuite(MavenITmng8245BeforePhaseCliTest.class);
suite.addTestSuite(MavenITmng8244PhaseAllTest.class);
suite.addTestSuite(MavenITmng8421MavenEncryptionTest.class);

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd"
root="true" preserve.model.version="true">
<groupId>org.apache.maven.its</groupId>
<artifactId>mng-8414-preserving</artifactId>
<version>1.0.0-SNAPSHOT</version>
<profiles>
<profile>
<id>my-profile</id>
<activation>
<condition>true</condition>
</activation>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" root="true" xsi:schemaLocation="http://maven.apache.org/POM/4.1.0 https://maven.apache.org/xsd/maven-4.1.0.xsd">
<groupId>org.apache.maven.its</groupId>
<artifactId>mng-8414</artifactId>
<version>1.0.0-SNAPSHOT</version>
<profiles>
<profile>
<id>my-profile</id>
<activation>
<condition>true</condition>
</activation>
</profile>
</profiles>
</project>