Skip to content

Commit befcb7c

Browse files
committed
Add recipe to remove image banner, closes #558
- Fixing TestProjectContext when used to create a multi-module project - Enhance PomBuilder to throw exception on API misuse - Enhance RecipeTestSupport to use with declarative rewrite recipe - Fix type check in ConditionDeserializer
1 parent e704032 commit befcb7c

File tree

8 files changed

+157
-42
lines changed

8 files changed

+157
-42
lines changed

components/recipe-test-support/src/main/java/org/springframework/sbm/test/RecipeTestSupport.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.springframework.sbm.engine.recipe.*;
2222
import org.springframework.sbm.java.impl.RewriteJavaParser;
2323
import org.springframework.sbm.java.util.BasePackageCalculator;
24+
import org.springframework.sbm.project.RewriteSourceFileWrapper;
2425
import org.springframework.sbm.project.resource.SbmApplicationProperties;
2526
import org.springframework.sbm.project.resource.ResourceHelper;
2627
import org.springframework.sbm.search.recipe.actions.OpenRewriteJavaSearchAction;
@@ -34,10 +35,7 @@
3435

3536
import javax.validation.Validator;
3637
import java.nio.file.Path;
37-
import java.util.ArrayList;
38-
import java.util.Arrays;
39-
import java.util.List;
40-
import java.util.Optional;
38+
import java.util.*;
4139
import java.util.function.Consumer;
4240
import java.util.stream.Collectors;
4341

@@ -66,6 +64,9 @@ private RecipeTestSupport() {
6664
DefaultActionDeserializer.class,
6765
RewriteJavaSearchActionDeserializer.class,
6866
RewriteRecipeLoader.class,
67+
RewriteRecipeRunner.class,
68+
RewriteMigrationResultMerger.class,
69+
RewriteSourceFileWrapper.class,
6970
SbmRecipeLoader.class,
7071
BasePackageCalculator.class,
7172
ProjectContextHolder.class
@@ -86,10 +87,6 @@ public static void testRecipe(Path recipeFile, Consumer<Recipes> consumer, Class
8687

8788
SpringBeanProvider.run(context -> {
8889
context.start();
89-
ActionDeserializerRegistry deserializerRegistry = context.getBean(ActionDeserializerRegistry.class);
90-
ObjectMapper objectMapper = context.getBean("yamlObjectMapper", ObjectMapper.class);
91-
92-
deserializerRegistry.register(OpenRewriteJavaSearchAction.class, new RewriteJavaSearchActionDeserializer(objectMapper, context.getBeanFactory()));
9390
RecipesBuilder recipesBuilder = context.getBean(RecipesBuilder.class);
9491
ResourceHelperDummy resourceHelperDummy = context.getBean(ResourceHelperDummy.class);
9592
resourceHelperDummy.setRecipe(recipeFile);

components/sbm-core/src/main/java/org/springframework/sbm/engine/recipe/ConditionDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ public Condition deserialize(JsonParser parser, DeserializationContext deseriali
5555
} catch (ClassNotFoundException e) {
5656
throw new IllegalArgumentException("Unknown class [" + clazz + "]", e);
5757
}
58-
if (!ClassUtils.getAllInterfacesForClassAsSet(conditionClass).contains(Condition.class)) {
58+
if (!Condition.class.isAssignableFrom(conditionClass)) {
5959
throw new IllegalArgumentException("Class [" + clazz + "] doesn't implement Condition interface");
6060
}
6161

components/sbm-core/src/test/java/org/springframework/sbm/build/impl/JavaSourceSetImplTest.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ void testGetBasePackageShouldReturnDistinctRootPackageIfExists() {
4343
"";
4444

4545
JavaSourceSet sut = TestProjectContext.buildProjectContext()
46-
.withDummyRootBuildFile()
4746
.withJavaSources(sourceCode1, sourceCode2)
4847
.build()
4948
.getApplicationModules().getRootModule().getMainJavaSourceSet();

components/sbm-core/src/test/java/org/springframework/sbm/build/util/PomBuilder.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,9 @@ public static PomBuilder buiildPom(String parent, String artifactId) {
4848
return pomBuilder;
4949
}
5050

51-
public PomBuilder withModules(String... modules) {
52-
this.modules = Arrays.asList(modules);
51+
public PomBuilder withModules(String... moduleArtifactNames) {
52+
this.modules = Arrays.asList(moduleArtifactNames);
53+
if(this.modules.stream().anyMatch(m -> m.contains(":"))) throw new RuntimeException("Found ':' in artifact name but artifact names of modules must not be provided as coordinate.");
5354
return this;
5455
}
5556

components/sbm-core/src/test/java/org/springframework/sbm/project/resource/TestProjectContext.java

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ public Builder withMockedBuildFile(OpenRewriteMavenBuildFile mockedBuildFile) {
423423
return this;
424424
}
425425

426+
/**
427+
* This method is obsolete to use as a default {@code pom.xml} is always added if not otherwise specified.
428+
*/
426429
public Builder withDummyRootBuildFile() {
427430
if (containsAnyPomXml() || !dependencies.isEmpty())
428431
throw new IllegalArgumentException("ProjectContext already contains pom.xml files.");
@@ -459,27 +462,26 @@ public ProjectContext serializeProjectContext(Path targetDir) {
459462
public ProjectContext build() {
460463
verifyValidBuildFileSetup();
461464

462-
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
463-
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
464-
" <modelVersion>4.0.0</modelVersion>\n" +
465-
"{{springParentPom}}" +
466-
" <groupId>com.example</groupId>\n" +
467-
" <artifactId>dummy-root</artifactId>\n" +
468-
" <version>0.1.0-SNAPSHOT</version>\n" +
469-
" <packaging>jar</packaging>\n" +
470-
"{{dependencies}}" +
471-
"</project>\n";
472-
473-
xml = xml
474-
.replace("{{dependencies}}", getDependenciesSection())
475-
.replace("{{springParentPom}}", getSpringParentPomSection());
476-
477-
resourcesWithRelativePaths.put(Path.of("pom.xml"), xml);
478-
479-
if (!containsAnyPomXml()) {
480-
withDummyRootBuildFile();
465+
if(!containsAnyPomXml()) {
466+
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
467+
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n" +
468+
" <modelVersion>4.0.0</modelVersion>\n" +
469+
"{{springParentPom}}" +
470+
" <groupId>com.example</groupId>\n" +
471+
" <artifactId>dummy-root</artifactId>\n" +
472+
" <version>0.1.0-SNAPSHOT</version>\n" +
473+
" <packaging>jar</packaging>\n" +
474+
"{{dependencies}}" +
475+
"</project>\n";
476+
477+
xml = xml
478+
.replace("{{dependencies}}", getDependenciesSection())
479+
.replace("{{springParentPom}}", getSpringParentPomSection());
480+
481+
resourcesWithRelativePaths.put(Path.of("pom.xml"), xml);
481482
}
482483

484+
483485
// create resource map with fully qualified paths
484486
Map<Path, String> resourcesWithAbsolutePaths = new LinkedHashMap<>();
485487
resourcesWithRelativePaths.entrySet().stream()
@@ -574,17 +576,22 @@ private ProjectContextInitializer createProjectContextInitializer(ProjectContext
574576
}
575577

576578
private void verifyValidBuildFileSetup() {
577-
boolean containsRootPom = resourcesWithRelativePaths.containsKey(Path.of("pom.xml"));
578579
boolean isClasspathGiven = dependencies != null && !dependencies.isEmpty();
579580
boolean isMockedBuildFileGiven = mockedBuildFile != null;
580-
581-
if (containsRootPom && isClasspathGiven) {
582-
throw new IllegalArgumentException("Found classpath entries and a root pom.xml in resources. When classpath is provided the root pom gets generated");
583-
} else if (containsRootPom && isMockedBuildFileGiven) {
584-
throw new IllegalArgumentException("Found mocked BuildFile and a root pom.xml in resources. When mocked BuildFile is provided no other pom.xml must exist");
581+
boolean hasSpringBootParent = this.springVersion.isPresent();
582+
boolean containsAnyPomXml = containsAnyPomXml();
583+
584+
if (containsAnyPomXml && isClasspathGiven) {
585+
throw new IllegalArgumentException("Found classpath entries and pom.xml in resources. When classpath is provided the root pom gets generated");
586+
} else if (containsAnyPomXml && hasSpringBootParent) {
587+
throw new IllegalArgumentException("Found spring boot version for parent pom and root pom.xml in resources. When spring boot version is provided the root pom gets generated");
588+
} else if (containsAnyPomXml && isMockedBuildFileGiven) {
589+
throw new IllegalArgumentException("Found mocked BuildFile and root pom.xml in resources. When mocked BuildFile is provided no other pom.xml must exist");
585590
}
586591
if (mockedBuildFile != null && isClasspathGiven) {
587592
throw new IllegalArgumentException("Found mocked BuildFile and classpath entries. When mocked BuildFile is provided no other pom.xml must exist");
593+
} else if(mockedBuildFile != null && hasSpringBootParent) {
594+
throw new IllegalArgumentException("Found mocked BuildFile and Spring Boot version. When mocked BuildFile is provided no other pom.xml, parent or dependencies must exist");
588595
}
589596
}
590597

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
- name: sbu30-remove-image-banner
2+
description: Spring boot 3.0 Upgrade - Remove the image banner at src/main/resources
3+
condition:
4+
type: org.springframework.sbm.common.migration.conditions.TrueCondition
5+
actions:
6+
- type: org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapter
7+
condition:
8+
type: org.springframework.sbm.boot.upgrade_27_30.report.helper.BannerSupportHelper
9+
description: Remove the image banner at src/main/resources
10+
openRewriteRecipe: |-
11+
type: specs.openrewrite.org/v1beta/recipe
12+
name: org.openrewrite.RemoveSpringBootImageBanner
13+
displayName: Remove the image banner at `src/main/resources`
14+
description: Remove the image banner at `src/main/resources`
15+
recipeList:
16+
- org.openrewrite.DeleteSourceFiles:
17+
filePattern: "{**/src,src}/main/resources/banner.{gif,png,jpg}"

components/sbm-recipes-boot-upgrade/src/main/resources/recipes/27_30/report/sbu30-report.yaml

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,13 @@
6060
<#assign coordinates>${scannedCoordinate}</#assign>
6161
[cols="1h,3"]
6262
|===
63-
| Scanned dir | `${scannedProjectRoot}`
63+
| Scanned dir | ${scannedProjectRoot}
6464
| Revision | <#if revision?has_content>`${revision}`<#else>Scanned project not under Git</#if>
6565
<#if projectName?has_content>
6666
| Project name | ${projectName}
6767
</#if>
68-
| Coordinate | `${scannedCoordinate}`
69-
| Boot version | `${bootVersion}`
68+
| Coordinate | ${scannedCoordinate}
69+
| Boot version | ${bootVersion}
7070
<#if numberOfChanges?has_content>
7171
| Changes | ${numberOfChanges}
7272
</#if>
@@ -150,11 +150,30 @@
150150
The scan found banner image files here:
151151
152152
<#list files as file>
153-
* ${file}
153+
* `${file}`
154154
</#list>
155155
remediation:
156156
description: |-
157-
remove image banners and replace it with text-banner with banner.txt file
157+
and replace it with text-banner with banner.txt file
158+
possibilities:
159+
- title: Remove image banner
160+
description: |-
161+
Remove these image banners
162+
163+
<#list files as file>
164+
* `${file}`
165+
</#list>
166+
recipe: sbu30-remove-image-banner
167+
- title: Replace image banner
168+
description: |-
169+
Replace these banners
170+
171+
<#list files as file>
172+
* `${file}`
173+
</#list>
174+
175+
with `banner.txt`
176+
158177
gitHubIssue: 150
159178
contributors:
160179
- "Sandeep Nagaraj[@sanagaraj-pivotal]"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2021 - 2022 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.sbm.boot.upgrade_27_30;
17+
18+
import org.junit.jupiter.api.Test;
19+
import org.springframework.sbm.boot.upgrade_27_30.report.SpringBootUpgradeReportActionDeserializer;
20+
import org.springframework.sbm.build.impl.MavenBuildFileUtil;
21+
import org.springframework.sbm.build.util.PomBuilder;
22+
import org.springframework.sbm.engine.context.ProjectContext;
23+
import org.springframework.sbm.engine.recipe.OpenRewriteDeclarativeRecipeAdapterTest;
24+
import org.springframework.sbm.engine.recipe.Recipe;
25+
import org.springframework.sbm.project.resource.TestProjectContext;
26+
import org.springframework.sbm.test.RecipeTestSupport;
27+
28+
import java.nio.file.FileSystems;
29+
import java.nio.file.Path;
30+
31+
import static org.assertj.core.api.Assertions.assertThat;
32+
33+
/**
34+
* @author Fabian Krüger
35+
*/
36+
public class RemoveImageBannerTest {
37+
@Test
38+
void testGlobExpression() {
39+
String pattern = "{**/src,src}/main/resources/banner.{gif,png,jpg}";
40+
assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("src/main/resources/banner.gif"))).isTrue();
41+
assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("/src/main/resources/banner.gif"))).isTrue();
42+
assertThat(FileSystems.getDefault().getPathMatcher("glob:"+pattern).matches(Path.of("some/path/above/src/main/resources/banner.gif"))).isTrue();
43+
}
44+
45+
@Test
46+
void applyRemoveImageBannerRecipeShouldRemoveAllImageBannerAtDefaultLocation() {
47+
String parentPom = PomBuilder
48+
.buiildPom("com.example:parent:1.0")
49+
.withModules("moduleA", "moduleB", "moduleC")
50+
.build();
51+
String moduleA = PomBuilder.buiildPom("com.example:parent:1.0", "moduleA").build();
52+
String moduleB = PomBuilder.buiildPom("com.example:parent:1.0", "moduleB").build();
53+
String moduleC = PomBuilder.buiildPom("com.example:parent:1.0", "moduleC").build();
54+
55+
ProjectContext context = TestProjectContext.buildProjectContext()
56+
.withMavenBuildFileSource("pom.xml", parentPom)
57+
.withMavenBuildFileSource("moduleA/pom.xml", moduleA)
58+
.addProjectResource("moduleA/src/main/resources/banner.jpg", "")
59+
.withMavenBuildFileSource("moduleB/pom.xml", moduleB)
60+
.addProjectResource("moduleB/src/main/resources/banner.png", "")
61+
.withMavenBuildFileSource("moduleC/pom.xml", moduleC)
62+
.addProjectResource("moduleC/src/main/resources/banner.gif", "")
63+
.build();
64+
65+
assertThat(context.getProjectResources().list()).hasSize(7);
66+
67+
RecipeTestSupport.testRecipe(Path.of("recipes/27_30/migration/sbu30-remove-image-banner.yaml"), recipes -> {
68+
Recipe recipe = recipes.getRecipeByName("sbu30-remove-image-banner").get();
69+
recipe.apply(context);
70+
71+
assertThat(context.getProjectResources().list()).hasSize(4); // only pom.xml left
72+
assertThat(context.getProjectResources().stream().allMatch(res -> res.getAbsolutePath().toString().endsWith("pom.xml"))).isTrue();
73+
}, SpringBootUpgradeReportActionDeserializer.class);
74+
}
75+
}

0 commit comments

Comments
 (0)