diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java index fb05a94e5..43dc45893 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/build/impl/OpenRewriteMavenBuildFile.java @@ -263,35 +263,45 @@ public List getDeclaredDependencies(Scope... scopes) { @Override public List getRequestedDependencies() { List requestedDependencies = getPom().getPom().getRequestedDependencies(); + // FIXME: #7 use getPom().getDependencies() instead ? List declaredDependenciesWithEffectiveVersions = requestedDependencies.stream() .map(d -> mapDependency(d)) .map(d -> { if(d.getType() == null || d.getClassifier() == null || d.getVersion() == null) { - String groupId = evaluate(d.getGroupId()); - String artifactId = evaluate(d.getArtifactId()); - String version = evaluate(d.getVersion()); + // resolve values for properties like ${my.artifactId} or ${dep.version} + String resolvedGroupId = resolve(d.getGroupId()); + String resolvedArtifactId = resolve(d.getArtifactId()); + String resolvedVersion = resolve(d.getVersion()); List dependencies = getPom().findDependencies( - groupId, - artifactId, + resolvedGroupId, + resolvedArtifactId, d.getScope() != null ? Scope.fromName(d.getScope()) : null ); if (dependencies.isEmpty()) { // requested dependency from another module in this multi-module project won't be resolvable - return d; + d.setGroupId(resolvedGroupId); + d.setArtifactId(resolvedArtifactId); + d.setVersion(resolvedVersion); + } + else { + ResolvedDependency resolvedDependency = dependencies.get(0); + d.setGroupId(resolvedGroupId); + d.setArtifactId(resolvedArtifactId); + d.setVersion(resolvedDependency.getVersion()); + d.setClassifier(resolvedDependency.getClassifier()); + d.setType(resolvedDependency.getType()); } - ResolvedDependency resolvedDependency = dependencies.get(0); - d.setVersion(resolvedDependency.getVersion()); - d.setClassifier(resolvedDependency.getClassifier()); - d.setType(resolvedDependency.getType()); - d.setArtifactId(artifactId); - d.setGroupId(groupId); + if(d.getScope() == null ) { - String s = resolveScope(groupId, artifactId, d.getType(), d.getClassifier()); - d.setScope(s); + String s = resolveScope(resolvedGroupId, resolvedArtifactId, d.getType(), d.getClassifier()); + if(s == null) { + s = "compile"; + } + d.setScope(s.toLowerCase()); } } return d; @@ -302,8 +312,6 @@ public List getRequestedDependencies() { /** * {@inheritDoc} - * - * TODO: #497 Test with declared and transitive dependencies */ @Override public Set getEffectiveDependencies(Scope scope) { @@ -315,10 +323,28 @@ public Set getEffectiveDependencies(Scope scope) { @Override public Set getEffectiveDependencies() { - return getPom().getDependencies().entrySet() + Set collect = getPom() + .getDependencies() + .get(Scope.Compile) .stream() - .flatMap(e -> e.getValue().stream().map(v -> mapDependency(e.getKey(), v))) + .map(d -> mapDependency(Scope.Compile, d)) .collect(Collectors.toSet()); + + getPom() + .getDependencies() + .get(Scope.Provided) + .stream() + .map(d -> mapDependency(Scope.Provided, d)) + .forEach(d -> collect.add(d)); + + getPom() + .getDependencies() + .get(Scope.Test) + .stream() + .map(d -> mapDependency(Scope.Test, d)) + .forEach(d -> collect.add(d)); + + return collect; } @Override @@ -367,7 +393,7 @@ private org.springframework.sbm.build.api.Dependency mapDependency(org.openrewri private String resolveScope(String groupId, String artifactId, @Nullable String type, @Nullable String classifier) { Scope managedScope = getPom().getPom().getManagedScope(groupId, artifactId, type, classifier); - return managedScope != null ? managedScope.name().toLowerCase() : null; + return managedScope != null ? managedScope.name().toLowerCase() : "compile"; } private org.springframework.sbm.build.api.Dependency mapDependency(Scope scope, ResolvedDependency d) { @@ -376,12 +402,15 @@ private org.springframework.sbm.build.api.Dependency mapDependency(Scope scope, d.getArtifactId(), d.getVersion(), d.getType(), - scope.name(), + scope.name().toLowerCase(), d.getClassifier(), - d.getRequested().getExclusions() - .stream() - .map(e -> Dependency.builder().groupId(e.getGroupId()).artifactId(e.getArtifactId()).build()) - .collect(Collectors.toList()) + d.getRequested().getExclusions() != null ? + d.getRequested().getExclusions() + .stream() + .map(e -> Dependency.builder().groupId(e.getGroupId()).artifactId(e.getArtifactId()).build()) + .collect(Collectors.toList()) + : + List.of() ); } @@ -623,7 +652,7 @@ public String getArtifactId() { @Override public String getVersion() { - return evaluate(getPom().getPom().getVersion()); + return resolve(getPom().getPom().getVersion()); } @Override public String getCoordinates() { @@ -802,7 +831,7 @@ public void removePlugins(String... coordinates) { } - private String evaluate(String expression) { + private String resolve(String expression) { return getPom().getPom().getValue(expression); } } diff --git a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java index 72993654e..0b9da5e3e 100644 --- a/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java +++ b/components/sbm-core/src/main/java/org/springframework/sbm/project/parser/DependencyHelper.java @@ -67,7 +67,7 @@ private static Consumer createErrorHandler() { } public Set mapCoordinatesToDependencies(List coordinates) { - Set dependencies = new HashSet<>(); + Set dependencies = new LinkedHashSet<>(); coordinates.forEach(c -> { String[] parts = c.split(":"); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/api/Module_contains_Test.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/api/Module_contains_Test.java index ab77ddacf..932c112c2 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/api/Module_contains_Test.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/api/Module_contains_Test.java @@ -73,7 +73,7 @@ void multiModuleProject() { String module1Pom = PomBuilder .buiildPom("com.example:parent:1.0", "module1") - .dependencies("com.example:module2:1.0") + .unscopedDependencies("com.example:module2:1.0") .build(); String module2Pom = PomBuilder.buiildPom("com.example:parent:1.0", "module2").build(); diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java b/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java index 1bd7f4e73..150ba1e87 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java @@ -14,105 +14,176 @@ * limitations under the License. */ -package org.springframework.sbm.build.util;import org.springframework.sbm.project.parser.DependencyHelper; +package org.springframework.sbm.build.util; -import java.util.Arrays; -import java.util.List; +import org.openrewrite.maven.tree.Scope; +import org.springframework.sbm.build.api.Dependency; +import org.springframework.sbm.project.parser.DependencyHelper; -public class PomBuilder { - private String coordinate; - private List modules; - private String type; - private String parent; - private String artifactId; - private List dependencies; - - public static PomBuilder buiildPom(String coordinate) { - PomBuilder pomBuilder = new PomBuilder(); - pomBuilder.coordinate = coordinate; - return pomBuilder; - } - - public static PomBuilder buiildPom(String parent, String artifactId) { - PomBuilder pomBuilder = new PomBuilder(); - pomBuilder.parent = parent; - pomBuilder.artifactId = artifactId; - return pomBuilder; - } +import java.util.*; - public PomBuilder withModules(String... modules) { - this.modules = Arrays.asList(modules); - return this; +public class PomBuilder { + private String coordinate; + private List modules; + private String type; + private String parent; + private String artifactId; + private List unscopedDependencies; + private List testScopeDependencies; + private Map properties = new HashMap<>(); + private Map dependencies = new LinkedHashMap(); + + private DependencyHelper dependencyHelper = new DependencyHelper(); + + public static PomBuilder buiildPom(String coordinate) { + PomBuilder pomBuilder = new PomBuilder(); + pomBuilder.coordinate = coordinate; + return pomBuilder; + } + + public static PomBuilder buiildPom(String parent, String artifactId) { + PomBuilder pomBuilder = new PomBuilder(); + pomBuilder.parent = parent; + pomBuilder.artifactId = artifactId; + return pomBuilder; + } + + public PomBuilder withModules(String... modules) { + this.modules = Arrays.asList(modules); + return this; + } + + public String build() { + StringBuilder sb = new StringBuilder(); + sb.append(""" + + + 4.0.0 + """); + + if (parent != null) { + String[] coord = parent.split(":"); + sb.append(" ").append("\n"); + sb.append(" ").append(coord[0]).append("").append("\n"); + sb.append(" ").append(coord[1]).append("").append("\n"); + sb.append(" ").append(coord[2]).append("").append("\n"); + sb.append(" ").append("\n"); + sb.append(" ").append(artifactId).append("").append("\n"); + } else { + String[] coord = coordinate.split(":"); + sb.append(" ").append(coord[0]).append("").append("\n"); + sb.append(" ").append(coord[1]).append("").append("\n"); + sb.append(" ").append(coord[2]).append("").append("\n"); } - public String build() { - StringBuilder sb = new StringBuilder(); - sb.append( - """ - - - 4.0.0 - """ + if(!properties.isEmpty()) { + sb.append(" ").append("\n"); + properties.entrySet().forEach(e -> + sb.append(" <").append(e.getKey()).append(">").append(e.getValue()).append("").append("\n") ); + sb.append(" ").append("\n"); + } - if(parent != null) { - String[] coord = parent.split(":"); - sb.append(" ").append("\n"); - sb.append(" ").append(coord[0]).append("").append("\n"); - sb.append(" ").append(coord[1]).append("").append("\n"); - sb.append(" ").append(coord[2]).append("").append("\n"); - sb.append(" ").append("\n"); - sb.append(" ").append(artifactId).append("").append("\n"); - } else { - String[] coord = coordinate.split(":"); - sb.append(" ").append(coord[0]).append("").append("\n"); - sb.append(" ").append(coord[1]).append("").append("\n"); - sb.append(" ").append(coord[2]).append("").append("\n"); - } - - - if(type != null ){ - sb.append(" ").append(type).append("").append("\n"); - } - - if(modules != null && !modules.isEmpty()) { - sb.append(" ").append("\n"); - modules.forEach(m -> sb.append(" ").append(m).append("\n")); - sb.append(" ").append("\n"); - } - - if(dependencies != null) { - String dependenciesRendered = buildDependencies(dependencies); - sb.append(dependenciesRendered); - } - sb.append(""); - return sb.toString(); + if (type != null) { + sb.append(" ").append(type).append("").append("\n"); } - String buildDependencies(List dependencyCoordinates) { - DependencyHelper dependencyHelper = new DependencyHelper(); - StringBuilder dependenciesSection = new StringBuilder(); - dependenciesSection.append(" ").append("").append("\n"); - dependencyHelper.mapCoordinatesToDependencies(dependencyCoordinates).stream().forEach(dependency -> { - dependenciesSection.append(" ").append(" ").append("").append("\n"); - dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getGroupId()).append("").append("\n"); - dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getArtifactId()).append("").append("\n"); - dependenciesSection.append(" ").append(" ").append(" ").append("").append(dependency.getVersion()).append("").append("\n"); - dependenciesSection.append(" ").append(" ").append("").append("\n"); - }); - dependenciesSection.append(" ").append("").append("\n"); - String dependenciesText = dependenciesSection.toString(); - return dependenciesText; + if (modules != null && !modules.isEmpty()) { + sb.append(" ").append("\n"); + modules.forEach(m -> sb.append(" ").append(m).append("\n")); + sb.append(" ").append("\n"); } - public PomBuilder type(String type) { - this.type = type; - return this; + if (!dependencies.isEmpty()) { + String dependenciesRendered = renderDependencies(dependencies); + sb.append(dependenciesRendered); } - public PomBuilder dependencies(String... s) { - this.dependencies = Arrays.asList(s); - return this; - } + sb.append(""); + return sb.toString(); + } + + String renderDependencies(Map dependencies) { + StringBuilder dependenciesSection = new StringBuilder(); + dependenciesSection.append(" ").append("").append("\n"); + dependencies.entrySet().forEach(e -> { + renderDependency(dependenciesSection, e.getKey(), e.getValue()); + }); + dependenciesSection.append(" ").append("").append("\n"); + String dependenciesText = dependenciesSection.toString(); + return dependenciesText; + } + + private void renderDependency(StringBuilder dependenciesSection, Scope scope, org.openrewrite.maven.tree.Dependency dependency) { + + dependenciesSection + .append(" ") + .append(" ") + .append("") + .append("\n"); + dependenciesSection + .append(" ") + .append(" ") + .append(" ") + .append("") + .append(dependency.getGroupId()) + .append("") + .append("\n"); + dependenciesSection + .append(" ") + .append(" ") + .append(" ") + .append("") + .append(dependency.getArtifactId()) + .append("") + .append("\n"); + dependenciesSection + .append(" ") + .append(" ") + .append(" ") + .append("") + .append(dependency.getVersion()) + .append("") + .append("\n"); + if(scope != Scope.None) { + dependenciesSection + .append(" ") + .append(" ") + .append(" ") + .append("") + .append(scope.name().toLowerCase()) + .append("") + .append("\n"); + } + dependenciesSection + .append(" ") + .append(" ") + .append("") + .append("\n"); + } + + public PomBuilder type(String type) { + this.type = type; + return this; + } + + public PomBuilder unscopedDependencies(String... coordinates) { + dependencyHelper.mapCoordinatesToDependencies(Arrays.asList(coordinates)) + .stream() + .forEach(c -> this.dependencies.put(Scope.None, c)); + return this; + } + + public PomBuilder testScopeDependencies(String... coordinates) { + dependencyHelper.mapCoordinatesToDependencies(Arrays.asList(coordinates)) + .stream() + .forEach(c -> this.dependencies.put(Scope.Test, c)); + return this; + } + + public PomBuilder withProperties(Map properties) { + this.properties = properties; + return this; + } } diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java index d42cdf206..d4c9d8be9 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/buildfile/OpenRewriteMavenBuildFileTest.java @@ -16,17 +16,18 @@ package org.springframework.sbm.project.buildfile; import org.intellij.lang.annotations.Language; -import org.junit.jupiter.api.Disabled; -import org.junit.jupiter.api.Nested; -import org.junit.jupiter.api.Tag; -import org.junit.jupiter.api.Test; +import org.jetbrains.annotations.NotNull; +import org.junit.jupiter.api.*; +import org.junit.jupiter.api.io.TempDir; import org.mockito.ArgumentCaptor; import org.mockito.Mockito; import org.springframework.context.ApplicationEventPublisher; import org.springframework.sbm.build.api.BuildFile; import org.springframework.sbm.build.api.DependenciesChangedEvent; import org.springframework.sbm.build.api.Dependency; +import org.springframework.sbm.build.api.Module; import org.springframework.sbm.build.api.Plugin; +import org.springframework.sbm.build.util.PomBuilder; import org.springframework.sbm.engine.context.ProjectContext; import org.springframework.sbm.engine.context.ProjectContextHolder; import org.springframework.sbm.java.api.Member; @@ -34,9 +35,7 @@ import org.springframework.sbm.project.resource.TestProjectContext; import java.nio.file.Path; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; import java.util.stream.Collectors; import static org.assertj.core.api.Assertions.assertThat; @@ -826,6 +825,255 @@ void testDeleteDependencies() { assertThat(sut.getDeclaredDependencies()).hasSize(0); } + @Nested + class GetDependenciesEarMultiModuleTest { + @Test + void getRequestedDependencies() { + ProjectContext context = TestProjectContext.buildFromDir(Path.of("./testcode/jee-ear-project/given")); + + + // ear module + BuildFile ear = getBuildFileByPackagingType(context, "ear"); + + List requestedDependenciesInEar = ear.getRequestedDependencies(); + + Dependency businessLogic = requestedDependenciesInEar.get(0); + assertThat(businessLogic.getGroupId()).isEqualTo("com.example"); + assertThat(businessLogic.getArtifactId()).isEqualTo("business-logic"); + assertThat(businessLogic.getScope()).isEqualTo("compile"); + assertThat(businessLogic.getVersion()).isEqualTo("1.0"); + assertThat(businessLogic.getType()).isEqualTo("ejb"); + + Dependency webapp = requestedDependenciesInEar.get(1); + assertThat(webapp.getGroupId()).isEqualTo("com.example"); + assertThat(webapp.getArtifactId()).isEqualTo("webapp"); + assertThat(webapp.getScope()).isEqualTo("compile"); + assertThat(webapp.getVersion()).isEqualTo("1.0"); + assertThat(webapp.getType()).isEqualTo("war"); + + // business-logic + BuildFile ejb = getBuildFileByPackagingType(context, "ejb"); + + List requestedDependenciesInEjb = ejb.getRequestedDependencies(); + + Dependency business = requestedDependenciesInEjb.get(0); + assertThat(business.getGroupId()).isEqualTo("org.apache.tomee"); + assertThat(business.getArtifactId()).isEqualTo("javaee-api"); + assertThat(business.getScope()).isEqualTo("provided"); + assertThat(business.getVersion()).isEqualTo("8.0-6"); + assertThat(business.getType()).isEqualTo("jar"); + + // webapp + BuildFile web = getBuildFileByPackagingType(context, "war"); + + List requestedDependenciesInWeb = web.getRequestedDependencies(); + + Dependency jeeApiInWebapp = requestedDependenciesInWeb.get(0); + assertThat(jeeApiInWebapp.getGroupId()).isEqualTo("org.apache.tomee"); + assertThat(jeeApiInWebapp.getArtifactId()).isEqualTo("javaee-api"); + assertThat(jeeApiInWebapp.getScope()).isEqualTo("provided"); + assertThat(jeeApiInWebapp.getVersion()).isEqualTo("7.0"); + assertThat(jeeApiInWebapp.getType()).isEqualTo("jar"); + + Dependency jstlInWebapp = requestedDependenciesInWeb.get(1); + assertThat(jstlInWebapp.getGroupId()).isEqualTo("javax.servlet"); + assertThat(jstlInWebapp.getArtifactId()).isEqualTo("jstl"); + assertThat(jstlInWebapp.getScope()).isEqualTo("provided"); + assertThat(jstlInWebapp.getVersion()).isEqualTo("1.2"); + assertThat(jstlInWebapp.getType()).isEqualTo("jar"); + + Dependency taglibsInWebapp = requestedDependenciesInWeb.get(2); + assertThat(taglibsInWebapp.getGroupId()).isEqualTo("taglibs"); + assertThat(taglibsInWebapp.getArtifactId()).isEqualTo("standard"); + assertThat(taglibsInWebapp.getScope()).isEqualTo("provided"); + assertThat(taglibsInWebapp.getVersion()).isEqualTo("1.1.2"); + assertThat(taglibsInWebapp.getType()).isEqualTo("jar"); + } + + // TODO: Add test for getEffectiveDependencies() + // TODO: Add test for getDeclaredDecpendencies() + + @NotNull + private BuildFile getBuildFileByPackagingType(ProjectContext context, String ear1) { + return context.getApplicationModules().stream().map(m -> m.getBuildFile()).filter(b -> { + return b.getPackaging().equals(ear1); + }).findFirst().get(); + } + } + + /** + * Test get[declared|requested|effective]Dependencies for pom files in multi-module project + */ + @Nested + class GetDependenciesMultiModuleTest { + String parentPom = PomBuilder + .buiildPom("com.example:parent:1.0") + .withProperties(Map.of( + "jakarta.version", "3.0.2", + "validation.groupId", "jakarta.validation", + "annotationApi.artifactId", "javax.annotation-api" + ) + ) + .withModules("module1", "module2") + .build(); + + String module1Pom = PomBuilder + .buiildPom("com.example:parent:1.0", "module1") + .unscopedDependencies("com.example:module2:${project.version}") + .testScopeDependencies("javax.annotation:${annotationApi.artifactId}:1.3.2") + .build(); + + String module2Pom = PomBuilder + .buiildPom("com.example:parent:1.0", "module2") + .unscopedDependencies("${validation.groupId}:jakarta.validation-api:${jakarta.version}") + .build(); + + ProjectContext context = TestProjectContext + .buildProjectContext() + .withMavenRootBuildFileSource(parentPom) + .withMavenBuildFileSource("module1", module1Pom) + .withMavenBuildFileSource("module2", module2Pom) + .build(); + + BuildFile module1 = context.getApplicationModules().getModule("module1").getBuildFile(); + BuildFile module2 = context.getApplicationModules().getModule("module2").getBuildFile(); + + @Test + @DisplayName("getDeclaredDependencies should return the dependencies as declared in build file") + void getDeclaredDependencies() { + // Module 1 + List dependenciesDeclaredInModule1 = module1.getDeclaredDependencies(); + + assertThat(dependenciesDeclaredInModule1).hasSize(2); + + Dependency dependency1DeclaredInModule1 = dependenciesDeclaredInModule1.get(0); + assertThat(dependency1DeclaredInModule1.getGroupId()).isEqualTo("com.example"); + assertThat(dependency1DeclaredInModule1.getArtifactId()).isEqualTo("module2"); + assertThat(dependency1DeclaredInModule1.getVersion()).isEqualTo("${project.version}"); + assertThat(dependency1DeclaredInModule1.getScope()).isNull(); + assertThat(dependency1DeclaredInModule1.getClassifier()).isNull(); + assertThat(dependency1DeclaredInModule1.getExclusions()).isEmpty(); + + Dependency dependency2DeclaredInModule1 = dependenciesDeclaredInModule1.get(1); + assertThat(dependency2DeclaredInModule1.getGroupId()).isEqualTo("javax.annotation"); + assertThat(dependency2DeclaredInModule1.getArtifactId()).isEqualTo("${annotationApi.artifactId}"); + assertThat(dependency2DeclaredInModule1.getVersion()).isEqualTo("1.3.2"); + assertThat(dependency2DeclaredInModule1.getScope()).isEqualTo("test"); + assertThat(dependency2DeclaredInModule1.getClassifier()).isNull(); + assertThat(dependency2DeclaredInModule1.getExclusions()).isEmpty(); + + // Module 2 + List dependenciesDeclaredInModule2 = module2.getDeclaredDependencies(); + + assertThat(dependenciesDeclaredInModule2).hasSize(1); + Dependency dependencyDeclaredInModule2 = dependenciesDeclaredInModule2.get(0); + + assertThat(dependencyDeclaredInModule2.getGroupId()).isEqualTo("${validation.groupId}"); + assertThat(dependencyDeclaredInModule2.getArtifactId()).isEqualTo("jakarta.validation-api"); + assertThat(dependencyDeclaredInModule2.getVersion()).isEqualTo("${jakarta.version}"); + assertThat(dependencyDeclaredInModule2.getScope()).isNull(); + assertThat(dependencyDeclaredInModule2.getClassifier()).isNull(); + assertThat(dependencyDeclaredInModule2.getExclusions()).isEmpty(); + } + + @Test + @DisplayName("getRequestedDependencies should return the declared dependencies with resolved attributes") + void getRequestedDependencies() { + // Module 1 + List dependenciesRequestedInModule1 = module1.getRequestedDependencies(); + + assertThat(dependenciesRequestedInModule1).hasSize(2); + Dependency dependency1DeclaredInModule1 = dependenciesRequestedInModule1.get(0); + + assertThat(dependency1DeclaredInModule1.getGroupId()).isEqualTo("com.example"); + assertThat(dependency1DeclaredInModule1.getArtifactId()).isEqualTo("module2"); + assertThat(dependency1DeclaredInModule1.getVersion()).isEqualTo("1.0"); + assertThat(dependency1DeclaredInModule1.getScope()).isEqualTo("compile"); + assertThat(dependency1DeclaredInModule1.getClassifier()).isNull(); + assertThat(dependency1DeclaredInModule1.getExclusions()).isEmpty(); + + Dependency dependency2DeclaredInModule1 = dependenciesRequestedInModule1.get(1); + assertThat(dependency2DeclaredInModule1.getGroupId()).isEqualTo("javax.annotation"); + assertThat(dependency2DeclaredInModule1.getArtifactId()).isEqualTo("javax.annotation-api"); + assertThat(dependency2DeclaredInModule1.getVersion()).isEqualTo("1.3.2"); + assertThat(dependency2DeclaredInModule1.getScope()).isEqualTo("test"); + assertThat(dependency2DeclaredInModule1.getClassifier()).isNull(); + assertThat(dependency2DeclaredInModule1.getExclusions()).isEmpty(); + + // Module 2 + List dependenciesRequestedInModule2 = module2.getRequestedDependencies(); + + assertThat(dependenciesRequestedInModule2).hasSize(1); + Dependency dependencyDeclaredInModule2 = dependenciesRequestedInModule2.get(0); + + assertThat(dependencyDeclaredInModule2.getGroupId()).isEqualTo("jakarta.validation"); + assertThat(dependencyDeclaredInModule2.getArtifactId()).isEqualTo("jakarta.validation-api"); + assertThat(dependencyDeclaredInModule2.getVersion()).isEqualTo("3.0.2"); + assertThat(dependencyDeclaredInModule2.getScope()).isEqualTo("compile"); + assertThat(dependencyDeclaredInModule2.getClassifier()).isNull(); + assertThat(dependencyDeclaredInModule2.getExclusions()).isEmpty(); + } + + @Test + @DisplayName("getRequestedDependencies should return any available dependency (declared or transitive) with given scope") + void getEffectiveDependencies() { + // Module 1 + List dependenciesEffectiveInModule1 = new ArrayList(module1.getEffectiveDependencies()); + + + assertThat(dependenciesEffectiveInModule1).hasSize(3); + Dependency depToModule2 = findDependencyByCoordinate(dependenciesEffectiveInModule1,"com.example:module2:1.0"); + + assertThat(depToModule2.getGroupId()).isEqualTo("com.example"); + assertThat(depToModule2.getArtifactId()).isEqualTo("module2"); + assertThat(depToModule2.getVersion()).isEqualTo("1.0"); + assertThat(depToModule2.getScope()).isEqualTo("compile"); + assertThat(depToModule2.getClassifier()).isNull(); + assertThat(depToModule2.getExclusions()).isEmpty(); + + Dependency depToAnnotationApi = findDependencyByCoordinate(dependenciesEffectiveInModule1, "javax.annotation:javax.annotation-api:1.3.2"); + + assertThat(depToAnnotationApi.getGroupId()).isEqualTo("javax.annotation"); + assertThat(depToAnnotationApi.getArtifactId()).isEqualTo("javax.annotation-api"); + assertThat(depToAnnotationApi.getVersion()).isEqualTo("1.3.2"); + assertThat(depToAnnotationApi.getScope()).isEqualTo("test"); + assertThat(depToAnnotationApi.getClassifier()).isNull(); + assertThat(depToAnnotationApi.getExclusions()).isEmpty(); + + Dependency transDepToValidationApi = findDependencyByCoordinate(dependenciesEffectiveInModule1, "jakarta.validation:jakarta.validation-api:3.0.2"); + + assertThat(transDepToValidationApi.getGroupId()).isEqualTo("jakarta.validation"); + assertThat(transDepToValidationApi.getArtifactId()).isEqualTo("jakarta.validation-api"); + assertThat(transDepToValidationApi.getVersion()).isEqualTo("3.0.2"); + assertThat(transDepToValidationApi.getScope()).isEqualTo("compile"); + assertThat(transDepToValidationApi.getClassifier()).isNull(); + assertThat(transDepToValidationApi.getExclusions()).isEmpty(); + + // Module 2 + List dependenciesEffectiveInModule2 = new ArrayList<>(module2.getEffectiveDependencies()); + + assertThat(dependenciesEffectiveInModule2).hasSize(1); + Dependency dependencyDeclaredInModule2 = findDependencyByCoordinate(dependenciesEffectiveInModule2, "jakarta.validation:jakarta.validation-api:3.0.2"); + + assertThat(dependencyDeclaredInModule2.getGroupId()).isEqualTo("jakarta.validation"); + assertThat(dependencyDeclaredInModule2.getArtifactId()).isEqualTo("jakarta.validation-api"); + assertThat(dependencyDeclaredInModule2.getVersion()).isEqualTo("3.0.2"); + assertThat(dependencyDeclaredInModule2.getScope()).isEqualTo("compile"); + assertThat(dependencyDeclaredInModule2.getClassifier()).isNull(); + assertThat(dependencyDeclaredInModule2.getExclusions()).isEmpty(); + } + + @NotNull + private Dependency findDependencyByCoordinate(List dependenciesEffectiveInModule1, String anObject) { + return dependenciesEffectiveInModule1 + .stream() + .filter(d -> d.getCoordinates().equals(anObject)) + .findFirst() + .get(); + } + } + + @Test void getRequestedDependencies() { @Language("xml") diff --git a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java index ebf2d5e89..8be66bbfa 100644 --- a/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java +++ b/components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java @@ -21,6 +21,7 @@ import org.openrewrite.maven.utilities.MavenArtifactDownloader; import org.springframework.context.ApplicationEventPublisher; import org.springframework.core.annotation.Order; +import org.springframework.core.io.DefaultResourceLoader; import org.springframework.core.io.Resource; import org.springframework.sbm.build.impl.OpenRewriteMavenBuildFile; import org.springframework.sbm.build.impl.RewriteMavenArtifactDownloader; @@ -39,19 +40,12 @@ import org.springframework.sbm.openrewrite.RewriteExecutionContext; import org.springframework.sbm.project.RewriteSourceFileWrapper; import org.springframework.sbm.project.TestDummyResource; -import org.springframework.sbm.project.parser.DependencyHelper; -import org.springframework.sbm.project.parser.JavaProvenanceMarkerFactory; -import org.springframework.sbm.project.parser.MavenProjectParser; -import org.springframework.sbm.project.parser.MavenConfigHandler; -import org.springframework.sbm.project.parser.ProjectContextInitializer; -import org.springframework.sbm.project.parser.ResourceParser; -import org.springframework.sbm.project.parser.RewriteJsonParser; -import org.springframework.sbm.project.parser.RewritePlainTextParser; -import org.springframework.sbm.project.parser.RewriteYamlParser; +import org.springframework.sbm.project.parser.*; import org.springframework.sbm.properties.parser.RewritePropertiesParser; import org.springframework.sbm.xml.parser.RewriteXmlParser; import java.io.ByteArrayInputStream; +import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.*; @@ -222,6 +216,29 @@ public static Path getDefaultProjectRoot() { public static String getDefaultPackageName() { return DEFAULT_PACKAGE_NAME; } + public static ProjectContext buildFromDir(Path of) { + final Path absoluteProjectRoot = of.toAbsolutePath().normalize(); + ResourceHelper resourceHelper = new ResourceHelper(new DefaultResourceLoader()); + SbmApplicationProperties sbmApplicationProperties = new SbmApplicationProperties(); + List ignorePatterns = List.of( + "sbm.ignoredPathsPatterns=**/.git/**,**/target/**,**/build/**,**/.gradle/**,**/.idea/**,**/.mvn/**,**/mvnw/**,**/.gitignore.,**/out/**,**/lib/**,**/*.iml,**/node_modules/**".split( + "\\.")); + sbmApplicationProperties.setIgnoredPathsPatterns(ignorePatterns); + PathScanner pathScanner = new PathScanner(sbmApplicationProperties, resourceHelper); + List scan = pathScanner.scan(absoluteProjectRoot); + Builder builder = TestProjectContext.buildProjectContext(); + scan.forEach(r -> { + try { + Path relativePath = absoluteProjectRoot.relativize(r.getFile().toPath()); + String content = ResourceHelper.getResourceAsString(r); + builder.addProjectResource(relativePath, content); + } catch (IOException e) { + throw new RuntimeException(e); + } + }); + return builder.build(); + } + public static class Builder { private Path projectRoot; private List resourceWrapperList = new ArrayList<>(); diff --git a/components/sbm-core/testcode/jee-ear-project/given/business-logic/pom.xml b/components/sbm-core/testcode/jee-ear-project/given/business-logic/pom.xml new file mode 100644 index 000000000..e24af5dad --- /dev/null +++ b/components/sbm-core/testcode/jee-ear-project/given/business-logic/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + + com.example + ear-parent + 1.0 + ../pom.xml + + business-logic + ejb + + + + org.apache.tomee + javaee-api + [8.0,) + provided + + + \ No newline at end of file diff --git a/components/sbm-core/testcode/jee-ear-project/given/ear/pom.xml b/components/sbm-core/testcode/jee-ear-project/given/ear/pom.xml new file mode 100644 index 000000000..6972a4d68 --- /dev/null +++ b/components/sbm-core/testcode/jee-ear-project/given/ear/pom.xml @@ -0,0 +1,55 @@ + + 4.0.0 + + + com.example + ear-parent + 1.0 + + ear + ear + + + UTF-8 + + + + + com.example + business-logic + ${project.version} + ejb + + + com.example + webapp + war + ${project.version} + + + + + + + maven-ear-plugin + 2.10.1 + + 6 + true + lib + + + com.example + webapp + /webapp + + + com.example + business-logic + + + + + + + \ No newline at end of file diff --git a/components/sbm-core/testcode/jee-ear-project/given/pom.xml b/components/sbm-core/testcode/jee-ear-project/given/pom.xml new file mode 100644 index 000000000..6650165a5 --- /dev/null +++ b/components/sbm-core/testcode/jee-ear-project/given/pom.xml @@ -0,0 +1,36 @@ + + 4.0.0 + + com.example + ear-parent + 1.0 + pom + + + business-logic + webapp + ear + + + + UTF-8 + + + + install + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.7 + 1.7 + + + + + + + \ No newline at end of file diff --git a/components/sbm-core/testcode/jee-ear-project/given/webapp/pom.xml b/components/sbm-core/testcode/jee-ear-project/given/webapp/pom.xml new file mode 100644 index 000000000..c5dca3c80 --- /dev/null +++ b/components/sbm-core/testcode/jee-ear-project/given/webapp/pom.xml @@ -0,0 +1,33 @@ + + 4.0.0 + + + com.example + ear-parent + 1.0 + ../pom.xml + + webapp + war + + + + org.apache.tomee + javaee-api + 7.0 + provided + + + javax.servlet + jstl + 1.2 + provided + + + taglibs + standard + 1.1.2 + provided + + + \ No newline at end of file diff --git a/components/sbm-core/testcode/jee-ear-project/given/webapp/src/main/webapp/WEB-INF/web.xml b/components/sbm-core/testcode/jee-ear-project/given/webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..6bc945a17 --- /dev/null +++ b/components/sbm-core/testcode/jee-ear-project/given/webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,6 @@ + + + test-service + \ No newline at end of file diff --git a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java index a1c145b8b..b0564b864 100644 --- a/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java +++ b/components/sbm-recipes-boot-upgrade/src/main/java/org/springframework/sbm/boot/upgrade_27_30/report/SpringBootUpgradeReportAction.java @@ -157,13 +157,6 @@ private void writeReport(String renderedHeader, List sections, String re upgradeReportRenderer.writeReport(renderedTemplate, outputDir, filename); } - private String replaceRelativeLinksToWebResourcesWithAbsoluteLinks(String renderedReport) { - return renderedReport; -// .replace("\"css/site.css", "\"https://docs.spring.io/spring-framework/docs/current/reference/html/css/spring.css") -// .replace("\"js/", "\"https://docs.spring.io/spring-framework/docs/current/reference/html/js/") -// .replace("\"img/", "\"https://docs.spring.io/spring-framework/docs/current/reference/html/img/"); - } - private String renderTemplate(String key, String content, Map data) { try (StringWriter writer = new StringWriter()) {