Skip to content

Commit 0f55f78

Browse files
committed
fix: Adding a managed Maven dependency throws exception if the dependency exists in same or higher version
1 parent 8c0e880 commit 0f55f78

File tree

3 files changed

+112
-6
lines changed

3 files changed

+112
-6
lines changed

applications/spring-shell/src/test/java/org/springframework/sbm/IntegrationTestBaseClass.java

+6-4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ public void beforeEach() throws IOException {
131131
testDir.resolve(this.getClass().getName());
132132
FileUtils.forceMkdir(testDir.toFile());
133133
testDir = testDir.toRealPath();
134+
this.intializeTestProject();
135+
scanProject();
134136
}
135137

136138
protected void enableGitSupport() {
@@ -178,23 +180,23 @@ protected Path getTestDir() {
178180
* @param applicableRecipes
179181
*/
180182
protected void assertApplicableRecipesContain(String... applicableRecipes) {
181-
List<String> recipeNames = getRecipeNames();
183+
List<String> recipeNames = getApplicableRecipeNames();
182184
assertThat(recipeNames).contains(applicableRecipes);
183185
}
184186

185187
@NotNull
186-
private List<String> getRecipeNames() {
188+
protected List<String> getApplicableRecipeNames() {
187189
return applicableRecipeListCommand.execute(projectContextHolder.getProjectContext()).stream()
188190
.map(r -> r.getName()).collect(Collectors.toList());
189191
}
190192

191193
protected void assertRecipeApplicable(String recipeName) {
192-
List<String> recipeNames = getRecipeNames();
194+
List<String> recipeNames = getApplicableRecipeNames();
193195
assertThat(recipeNames).contains(recipeName);
194196
}
195197

196198
protected void assertRecipeNotApplicable(String recipeName) {
197-
List<String> recipeNames = getRecipeNames();
199+
List<String> recipeNames = getApplicableRecipeNames();
198200
assertThat(recipeNames).doesNotContain(recipeName);
199201
}
200202

components/sbm-core/src/main/java/org/springframework/sbm/build/migration/actions/AddMavenDependencyManagementAction.java

+49-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515
*/
1616
package org.springframework.sbm.build.migration.actions;
1717

18-
import org.springframework.sbm.build.api.Module;
18+
import org.apache.maven.artifact.versioning.ComparableVersion;
19+
import org.jetbrains.annotations.NotNull;
1920
import org.springframework.sbm.build.api.BuildFile;
2021
import org.springframework.sbm.build.api.Dependency;
2122
import org.springframework.sbm.engine.recipe.AbstractAction;
2223
import org.springframework.sbm.engine.context.ProjectContext;
2324
import lombok.Setter;
2425

26+
import java.util.Optional;
27+
2528
@Setter
2629
public class AddMavenDependencyManagementAction extends AbstractAction {
2730

@@ -33,14 +36,58 @@ public class AddMavenDependencyManagementAction extends AbstractAction {
3336

3437
@Override
3538
public void apply(ProjectContext context) {
39+
verifyNoConflictingManagedDependencyExists(context);
40+
3641
Dependency dependency = Dependency.builder()
3742
.groupId(groupId)
3843
.artifactId(artifactId)
3944
.version(version)
4045
.scope(scope)
4146
.type(dependencyType)
4247
.build();
48+
BuildFile rootBuildFile = context.getApplicationModules().getRootModule().getBuildFile();
49+
rootBuildFile.addToDependencyManagement(dependency);
50+
}
51+
52+
@NotNull
53+
private void verifyNoConflictingManagedDependencyExists(ProjectContext context) {
54+
BuildFile rootBuildFile = context.getApplicationModules().getRootModule().getBuildFile();
55+
Optional<Dependency> managedSpringDep = rootBuildFile
56+
.getRequestedDependencyManagement()
57+
.stream()
58+
.filter(this::matchingDependencyManagementSection)
59+
.findFirst();
60+
61+
if(managedSpringDep.isPresent()) {
62+
Dependency managedDep = managedSpringDep.get();
63+
int comparisonResult = compareVersions(this.version, managedDep.getVersion());
64+
if(managedDependencyHasSameVersion(comparisonResult) || managedDependencyHasHigherVersion(comparisonResult)) {
65+
String message = String.format(
66+
"Failed to add a managed dependency %s with version %s. This managed dependency already exists in %s in version %s.",
67+
this.groupId + ":" + this.artifactId,
68+
this.version,
69+
rootBuildFile.getAbsolutePath(),
70+
managedDep.getVersion()
71+
);
72+
throw new IllegalStateException(message);
73+
}
74+
}
75+
}
76+
77+
private boolean managedDependencyHasSameVersion(int comparisonResult) {
78+
return comparisonResult == 0;
79+
}
80+
81+
private boolean managedDependencyHasHigherVersion(int comparisonResult) {
82+
return comparisonResult == -1;
83+
}
84+
85+
private int compareVersions(String newVersion, String existingVersion) {
86+
return new ComparableVersion(newVersion).compareTo(new ComparableVersion(existingVersion));
87+
}
4388

44-
context.getApplicationModules().getRootModule().getBuildFile().addToDependencyManagement(dependency);
89+
private boolean matchingDependencyManagementSection(Dependency dependency) {
90+
return dependency.getGroupId().equals(groupId) &&
91+
dependency.getArtifactId().equals(artifactId);
4592
}
4693
}

components/sbm-core/src/test/java/org/springframework/sbm/build/migration/actions/AddMavenDependencyManagementActionTest.java

+57
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.springframework.sbm.testhelper.common.utils.TestDiff;
2424

2525
import static org.assertj.core.api.Assertions.assertThat;
26+
import static org.junit.jupiter.api.Assertions.assertThrows;
2627

2728
class AddMavenDependencyManagementActionTest {
2829

@@ -205,4 +206,60 @@ void shouldAddToRootPomInSingleModuleProject() {
205206
.as(TestDiff.of(buildFile.print(), expected))
206207
.isEqualTo(expected);
207208
}
209+
210+
@Test
211+
void shouldThrowExceptionWhenSameManagedDependencyExistsWithHigherVersion() {
212+
String versionInPom = "2.7.5";
213+
String versionInRecipe = "2.7.4";
214+
testAddMavenDependencyManagementAction(versionInPom, versionInRecipe);
215+
}
216+
217+
@Test
218+
void shouldThrowExceptionWhenSameManagedDependencyExistsWithSameVersion() {
219+
String versionInPom = "2.7.5";
220+
String versionInRecipe = "2.7.5";
221+
testAddMavenDependencyManagementAction(versionInPom, versionInRecipe);
222+
}
223+
224+
private void testAddMavenDependencyManagementAction(String versionInPom, String versionInRecipe) {
225+
String pom = """
226+
<?xml version="1.0" encoding="UTF-8"?>
227+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
228+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
229+
<modelVersion>4.0.0</modelVersion>
230+
<groupId>com.example</groupId>
231+
<artifactId>demo</artifactId>
232+
<version>0.0.1-SNAPSHOT</version>
233+
<name>demo</name>
234+
<description>Demo project for Spring Boot</description>
235+
<properties>
236+
<java.version>17</java.version>
237+
</properties>
238+
<dependencyManagement>
239+
<dependencies>
240+
<dependency>
241+
<groupId>org.springframework.boot</groupId>
242+
<artifactId>spring-boot-dependencies</artifactId>
243+
<version>%s</version>
244+
<type>pom</type>
245+
<scope>import</scope>
246+
</dependency>
247+
</dependencies>
248+
</dependencyManagement>
249+
</project>
250+
""".formatted(versionInPom);
251+
252+
ProjectContext projectContext = TestProjectContext.buildProjectContext().withMavenRootBuildFileSource(pom).build();
253+
254+
AddMavenDependencyManagementAction sut = new AddMavenDependencyManagementAction();
255+
sut.setGroupId("org.springframework.boot");
256+
sut.setArtifactId("spring-boot-dependencies");
257+
258+
sut.setVersion(versionInRecipe);
259+
260+
assertThrows(IllegalStateException.class, () -> {
261+
sut.apply(projectContext);
262+
}).getMessage().equals("Failed to add a managed dependency org.springframework.boot:spring-boot-dependencies with version "+ versionInRecipe +". " +
263+
"This managed dependency already exists in " + projectContext.getApplicationModules().getRootModule().getBuildFile().getAbsolutePath().toString() + " in version "+versionInPom+".");
264+
}
208265
}

0 commit comments

Comments
 (0)