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 @@ -611,28 +611,59 @@ public void mergeRepositories(Model model, boolean replace) {
// Infer inner reactor dependencies version
//
Model transformFileToRaw(Model model) {
if (model.getDependencies().isEmpty()) {
List<Dependency> newDeps = null;
boolean depsChanged = false;
if (!model.getDependencies().isEmpty()) {
newDeps = new ArrayList<>(model.getDependencies().size());
depsChanged = inferDependencies(model, model.getDependencies(), newDeps);
}

DependencyManagement depMgmt = model.getDependencyManagement();
List<Dependency> newManagedDeps = null;
boolean managedDepsChanged = false;
if (depMgmt != null && !depMgmt.getDependencies().isEmpty()) {
newManagedDeps = new ArrayList<>(depMgmt.getDependencies().size());
managedDepsChanged = inferDependencies(model, depMgmt.getDependencies(), newManagedDeps);
}

if (!depsChanged && !managedDepsChanged) {
return model;
}
List<Dependency> newDeps = new ArrayList<>(model.getDependencies().size());
Model.Builder builder = Model.newBuilder(model);
if (depsChanged) {
builder.dependencies(newDeps);
}
if (managedDepsChanged) {
builder.dependencyManagement(depMgmt.withDependencies(newManagedDeps));
}
return builder.build();
}

/**
* Infers the missing version or groupId of the given dependencies by looking them up in the reactor.
* Each dependency, either the original one or the inferred one, is added to {@code result}.
*
* @param model the model declaring the dependencies
* @param dependencies the dependencies to process
* @param result the list collecting the resulting dependencies
* @return whether at least one dependency has been inferred
*/
private boolean inferDependencies(Model model, List<Dependency> dependencies, List<Dependency> result) {
boolean changed = false;
for (Dependency dep : model.getDependencies()) {
for (Dependency dep : dependencies) {
Dependency newDep = null;
if (dep.getVersion() == null) {
newDep = inferDependencyVersion(model, dep);
if (newDep != null) {
changed = true;
}
} else if (dep.getGroupId() == null) {
// Handle missing groupId when version is present
newDep = inferDependencyGroupId(model, dep);
if (newDep != null) {
changed = true;
}
}
newDeps.add(newDep == null ? dep : newDep);
if (newDep != null) {
changed = true;
}
result.add(newDep == null ? dep : newDep);
}
return changed ? model.withDependencies(newDeps) : model;
return changed;
}

private Dependency inferDependencyVersion(Model model, Dependency dep) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.maven.api.RemoteRepository;
import org.apache.maven.api.Session;
import org.apache.maven.api.model.Dependency;
import org.apache.maven.api.model.DependencyManagement;
import org.apache.maven.api.model.Model;
import org.apache.maven.api.model.Repository;
import org.apache.maven.api.services.ModelBuilder;
Expand Down Expand Up @@ -444,6 +445,53 @@ public void testBuildConsumerResolvesParentProfileProperties() {
"Managed dependency version should be interpolated, not ${managed.version}");
}

/**
* Verifies that the versions of sibling reactor modules declared in {@code <dependencyManagement>}
* are inferred, just like they already are for regular dependencies (GH-11147).
* This is the typical BOM use case where a subproject lists its siblings without their versions.
*/
@Test
public void testBomDependencyManagementVersionInference() {
// Build the lib POM first: this creates the main session and registers the sibling module
ModelBuilder.ModelBuilderSession mbs = builder.newSession();
mbs.build(ModelBuilderRequest.builder()
.session(session)
.requestType(ModelBuilderRequest.RequestType.BUILD_PROJECT)
.source(Sources.buildSource(getPom("bom-dep-mgmt-lib")))
.build());

// Access the main session (package-private) to invoke the file to raw model transformation
DefaultModelBuilder.ModelBuilderSessionState mainState =
((DefaultModelBuilder.ModelBuilderSessionImpl) mbs).mainSession;

// A BOM declaring a sibling module in dependencyManagement, without a version
Model bomModel = Model.newBuilder()
.modelVersion("4.1.0")
.groupId("org.apache.maven.tests")
.artifactId("bom-dep-mgmt-bom")
.version("1.0-SNAPSHOT")
.packaging("pom")
.pomFile(getPom("bom-dep-mgmt-bom"))
.dependencyManagement(DependencyManagement.newBuilder()
.dependencies(List.of(Dependency.newBuilder()
.groupId("org.apache.maven.tests")
.artifactId("bom-dep-mgmt-lib")
.build()))
.build())
.build();

Model transformed = mainState.transformFileToRaw(bomModel);

assertNotNull(transformed.getDependencyManagement());
Dependency managedDep = transformed.getDependencyManagement().getDependencies().stream()
.filter(d -> "bom-dep-mgmt-lib".equals(d.getArtifactId()))
.findFirst()
.orElse(null);
assertNotNull(managedDep, "Managed dependency for the sibling module should be kept");
assertEquals(
"1.0-SNAPSHOT", managedDep.getVersion(), "Version should be inferred from the reactor sibling module");
}

private Path getPom(String name) {
return Paths.get("src/test/resources/poms/factory/" + name + ".xml").toAbsolutePath();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.1.0">
<parent>
<groupId>org.apache.maven.tests</groupId>
<artifactId>bom-dep-mgmt-parent</artifactId>
<relativePath>bom-dep-mgmt-parent.xml</relativePath>
</parent>
<artifactId>bom-dep-mgmt-bom</artifactId>
<packaging>pom</packaging>

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.maven.tests</groupId>
<artifactId>bom-dep-mgmt-lib</artifactId>
<!-- version intentionally omitted: should be inferred from reactor -->
</dependency>
</dependencies>
</dependencyManagement>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.1.0">
<parent>
<groupId>org.apache.maven.tests</groupId>
<artifactId>bom-dep-mgmt-parent</artifactId>
<relativePath>bom-dep-mgmt-parent.xml</relativePath>
</parent>
<artifactId>bom-dep-mgmt-lib</artifactId>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->
<project xmlns="http://maven.apache.org/POM/4.1.0">
<groupId>org.apache.maven.tests</groupId>
<artifactId>bom-dep-mgmt-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
</project>
Loading