Skip to content
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
Expand Up @@ -24,6 +24,7 @@
import java.nio.file.Path;

import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.deployment.DeployRequest;
Expand All @@ -41,6 +42,6 @@ public interface PomArtifactTransformer {

void injectTransformedArtifacts(RepositorySystemSession session, MavenProject currentProject) throws IOException;

void transform(MavenProject project, RepositorySystemSession session, Path src, Path tgt)
void transform(MavenProject project, RepositorySystemSession session, ModelSource src, Path tgt)
throws ModelBuilderException, XMLStreamException, IOException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
import javax.inject.Singleton;
import javax.xml.stream.XMLStreamException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand All @@ -36,6 +38,9 @@
import org.apache.maven.api.feature.Features;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.api.services.Source;
import org.apache.maven.api.services.Sources;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.artifact.ProjectArtifact;
import org.eclipse.aether.RepositorySystemSession;
Expand Down Expand Up @@ -93,19 +98,53 @@ public void injectTransformedArtifacts(RepositorySystemSession session, MavenPro

TransformedArtifact createConsumerPomArtifact(
MavenProject project, Path consumer, RepositorySystemSession session) {
Path actual = project.getFile().toPath();
Path parent = project.getBaseDirectory();
ModelSource source = new ModelSource() {
@Override
public Path getPath() {
return actual;
}

@Override
public InputStream openStream() throws IOException {
return Files.newInputStream(actual);
}

@Override
public String getLocation() {
return actual.toString();
}

@Override
public Source resolve(String relative) {
return Sources.buildSource(actual.resolve(relative));
}

@Override
public ModelSource resolve(ModelLocator modelLocator, String relative) {
String norm = relative.replace('\\', File.separatorChar).replace('/', File.separatorChar);
Path path = parent.resolve(norm);
Path relatedPom = modelLocator.locateExistingPom(path);
if (relatedPom != null) {
return Sources.buildSource(relatedPom);
}
return null;
}
};
return new TransformedArtifact(
this,
project,
consumer,
session,
new ProjectArtifact(project),
() -> project.getFile().toPath(),
() -> source,
CONSUMER_POM_CLASSIFIER,
"pom");
}

@Override
public void transform(MavenProject project, RepositorySystemSession session, Path src, Path tgt)
public void transform(MavenProject project, RepositorySystemSession session, ModelSource src, Path tgt)
throws ModelBuilderException, XMLStreamException, IOException {
Model model = builder.build(session, project, src);
write(model, tgt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import javax.inject.Inject;
import javax.inject.Named;

import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
Expand All @@ -45,7 +44,7 @@
import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelBuilderRequest;
import org.apache.maven.api.services.ModelBuilderResult;
import org.apache.maven.api.services.Sources;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.api.services.model.LifecycleBindingsInjector;
import org.apache.maven.impl.InternalSession;
import org.apache.maven.model.v4.MavenModelVersion;
Expand All @@ -71,7 +70,8 @@ class DefaultConsumerPomBuilder implements PomBuilder {
}

@Override
public Model build(RepositorySystemSession session, MavenProject project, Path src) throws ModelBuilderException {
public Model build(RepositorySystemSession session, MavenProject project, ModelSource src)
throws ModelBuilderException {
Model model = project.getModel().getDelegate();
boolean flattenEnabled = Features.consumerPomFlatten(session.getConfigProperties());

Expand All @@ -95,27 +95,27 @@ public Model build(RepositorySystemSession session, MavenProject project, Path s
}
}

protected Model buildPom(RepositorySystemSession session, MavenProject project, Path src)
protected Model buildPom(RepositorySystemSession session, MavenProject project, ModelSource src)
throws ModelBuilderException {
ModelBuilderResult result = buildModel(session, src);
Model model = result.getRawModel();
return transformPom(model, project);
}

protected Model buildBom(RepositorySystemSession session, MavenProject project, Path src)
protected Model buildBom(RepositorySystemSession session, MavenProject project, ModelSource src)
throws ModelBuilderException {
ModelBuilderResult result = buildModel(session, src);
Model model = result.getEffectiveModel();
return transformBom(model, project);
}

protected Model buildNonPom(RepositorySystemSession session, MavenProject project, Path src)
protected Model buildNonPom(RepositorySystemSession session, MavenProject project, ModelSource src)
throws ModelBuilderException {
Model model = buildEffectiveModel(session, src);
return transformNonPom(model, project);
}

private Model buildEffectiveModel(RepositorySystemSession session, Path src) throws ModelBuilderException {
private Model buildEffectiveModel(RepositorySystemSession session, ModelSource src) throws ModelBuilderException {
InternalSession iSession = InternalSession.from(session);
ModelBuilderResult result = buildModel(session, src);
Model model = result.getEffectiveModel();
Expand Down Expand Up @@ -222,12 +222,13 @@ private static String getDependencyKey(Dependency dependency) {
+ (dependency.getClassifier() != null ? dependency.getClassifier() : "");
}

private ModelBuilderResult buildModel(RepositorySystemSession session, Path src) throws ModelBuilderException {
private ModelBuilderResult buildModel(RepositorySystemSession session, ModelSource src)
throws ModelBuilderException {
InternalSession iSession = InternalSession.from(session);
ModelBuilderRequest.ModelBuilderRequestBuilder request = ModelBuilderRequest.builder();
request.requestType(ModelBuilderRequest.RequestType.BUILD_CONSUMER);
request.session(iSession);
request.source(Sources.buildSource(src));
request.source(src);
request.locationTracking(false);
request.systemProperties(session.getSystemProperties());
request.userProperties(session.getUserProperties());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
import javax.xml.stream.XMLStreamException;

import java.io.IOException;
import java.nio.file.Path;

import org.apache.maven.api.model.Model;
import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.project.MavenProject;
import org.eclipse.aether.RepositorySystemSession;

Expand All @@ -33,6 +33,6 @@
* of {@link ConsumerPomArtifactTransformer}.
*/
interface PomBuilder {
Model build(RepositorySystemSession session, MavenProject project, Path src)
Model build(RepositorySystemSession session, MavenProject project, ModelSource src)
throws ModelBuilderException, IOException, XMLStreamException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.util.function.Supplier;

import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.artifact.DefaultArtifact;
import org.apache.maven.internal.transformation.PomArtifactTransformer;
import org.apache.maven.internal.transformation.TransformationFailedException;
Expand All @@ -48,7 +49,7 @@ class TransformedArtifact extends DefaultArtifact {
private static final int SHA1_BUFFER_SIZE = 8192;
private final PomArtifactTransformer pomArtifactTransformer;
private final MavenProject project;
private final Supplier<Path> sourcePathProvider;
private final Supplier<ModelSource> sourcePathProvider;
private final Path target;
private final RepositorySystemSession session;
private final AtomicReference<String> sourceState;
Expand All @@ -60,7 +61,7 @@ class TransformedArtifact extends DefaultArtifact {
Path target,
RepositorySystemSession session,
org.apache.maven.artifact.Artifact source,
Supplier<Path> sourcePathProvider,
Supplier<ModelSource> sourcePathProvider,
String classifier,
String extension) {
super(
Expand Down Expand Up @@ -105,20 +106,21 @@ public synchronized File getFile() {

private String mayUpdate() throws IOException, XMLStreamException, ModelBuilderException {
String result;
Path src = sourcePathProvider.get();
ModelSource src = sourcePathProvider.get();
if (src == null) {
Files.deleteIfExists(target);
result = null;
} else if (!Files.exists(src)) {
} else if (!Files.exists(src.getPath())) {
Files.deleteIfExists(target);
result = "";
} else {
String current = ChecksumAlgorithmHelper.calculate(src, List.of(new Sha1ChecksumAlgorithmFactory()))
String current = ChecksumAlgorithmHelper.calculate(
src.getPath(), List.of(new Sha1ChecksumAlgorithmFactory()))
.get(Sha1ChecksumAlgorithmFactory.NAME);
String existing = sourceState.get();
if (!Files.exists(target) || !Objects.equals(current, existing)) {
pomArtifactTransformer.transform(project, session, src, target);
Files.setLastModifiedTime(target, Files.getLastModifiedTime(src));
Files.setLastModifiedTime(target, Files.getLastModifiedTime(src.getPath()));
}
result = current;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

import org.apache.maven.api.model.Model;
import org.apache.maven.api.services.ModelBuilderException;
import org.apache.maven.api.services.ModelSource;
import org.apache.maven.internal.transformation.PomArtifactTransformer;
import org.apache.maven.model.v4.MavenStaxReader;
import org.apache.maven.model.v4.MavenStaxWriter;
Expand Down Expand Up @@ -58,7 +59,7 @@ public DeployRequest remapDeployArtifacts(RepositorySystemSession session, Deplo
public void injectTransformedArtifacts(RepositorySystemSession session, MavenProject project) throws IOException {}

@Override
public void transform(MavenProject project, RepositorySystemSession session, Path src, Path tgt)
public void transform(MavenProject project, RepositorySystemSession session, ModelSource src, Path tgt)
throws ModelBuilderException, XMLStreamException, IOException {
throw new IllegalStateException("This transformer does not use this call.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.nio.file.Path;
import java.nio.file.Paths;

import org.apache.maven.api.services.Sources;
import org.apache.maven.model.Model;
import org.apache.maven.model.v4.MavenStaxReader;
import org.apache.maven.project.MavenProject;
Expand Down Expand Up @@ -55,12 +56,12 @@ void transform() throws Exception {
MavenProject project = new MavenProject(model);
project.setOriginalModel(model);
ConsumerPomArtifactTransformer t = new ConsumerPomArtifactTransformer((s, p, f) -> {
try (InputStream is = Files.newInputStream(f)) {
try (InputStream is = f.openStream()) {
return DefaultConsumerPomBuilder.transformPom(new MavenStaxReader().read(is), project);
}
});

t.transform(project, systemSessionMock, beforePomFile, tempFile);
t.transform(project, systemSessionMock, Sources.buildSource(beforePomFile), tempFile);
}
XmlAssert.assertThat(tempFile.toFile()).and(afterPomFile.toFile()).areIdentical();
}
Expand All @@ -82,12 +83,12 @@ void transformJarConsumerPom() throws Exception {
MavenProject project = new MavenProject(model);
project.setOriginalModel(model);
ConsumerPomArtifactTransformer t = new ConsumerPomArtifactTransformer((s, p, f) -> {
try (InputStream is = Files.newInputStream(f)) {
try (InputStream is = f.openStream()) {
return DefaultConsumerPomBuilder.transformNonPom(new MavenStaxReader().read(is), project);
}
});

t.transform(project, systemSessionMock, beforePomFile, tempFile);
t.transform(project, systemSessionMock, Sources.buildSource(beforePomFile), tempFile);
}
XmlAssert.assertThat(afterPomFile.toFile()).and(tempFile.toFile()).areIdentical();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ void testTrivialConsumer() throws Exception {

MavenProject project = new MavenProject(orgModel);
project.setOriginalModel(new org.apache.maven.model.Model(orgModel));
Model model = builder.build(session, project, file);
Model model = builder.build(session, project, Sources.buildSource(file));

assertNotNull(model);
}
Expand All @@ -135,7 +135,7 @@ void testSimpleConsumer() throws Exception {
MavenProject project = new MavenProject(orgModel);
project.setOriginalModel(new org.apache.maven.model.Model(orgModel));
request.setRootDirectory(Paths.get("src/test/resources/consumer/simple"));
Model model = builder.build(session, project, file);
Model model = builder.build(session, project, Sources.buildSource(file));

assertNotNull(model);
assertTrue(model.getProfiles().isEmpty());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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.File;

import org.junit.jupiter.api.Test;

/**
* This is a test set for <a href="https://github.com/apache/maven/issues/11399">GH-11399</a>.
*
* Verifies that using flatten-maven-plugin with updatePomFile=true does not cause a false
* parent cycle detection error during install phase. The issue occurred when the plugin
* updated the POM file reference, causing the consumer POM builder to incorrectly detect
* a cycle between the project and its parent.
*
* @see <a href="https://github.com/mojohaus/flatten-maven-plugin">flatten-maven-plugin</a>
*/
public class MavenITgh11399FlattenPluginParentCycleTest extends AbstractMavenIntegrationTestCase {

public MavenITgh11399FlattenPluginParentCycleTest() {
super("(4.0.0-rc-3,)");
}

/**
* Verify that flatten-maven-plugin with updatePomFile=true and parent expansion
* does not cause a false parent cycle detection error during install.
*
* The error was:
* "The parents form a cycle: org.apache:apache:35 -> /path/to/pom.xml -> org.apache:apache:35"
*
* @throws Exception in case of failure
*/
@Test
public void testFlattenPluginWithParentExpansionDoesNotCauseCycle() throws Exception {
File testDir = extractResources("/gh-11399-flatten-plugin-parent-cycle");

Verifier verifier = newVerifier(testDir.getAbsolutePath());
verifier.setAutoclean(false);
verifier.deleteArtifacts("org.apache.maven.its.mng8750");
verifier.addCliArgument("install");
verifier.execute();
verifier.verifyErrorFreeLog();

// Verify that the flattened POM was created
verifier.verifyFilePresent("target/.flattened-pom.xml");
}
}

Loading