Skip to content

Commit baf7482

Browse files
committed
Cleanup UpgradeExplicitSpringBootDependencies
1 parent e5589ab commit baf7482

File tree

2 files changed

+137
-105
lines changed

2 files changed

+137
-105
lines changed

src/main/java/org/openrewrite/maven/spring/UpgradeExplicitSpringBootDependencies.java

Lines changed: 118 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@
1616

1717
package org.openrewrite.maven.spring;
1818

19-
import com.fasterxml.jackson.annotation.JsonCreator;
20-
import com.fasterxml.jackson.annotation.JsonProperty;
19+
import lombok.Data;
2120
import lombok.EqualsAndHashCode;
21+
import lombok.Value;
2222
import org.openrewrite.*;
23-
import org.openrewrite.groovy.tree.G;
24-
import org.openrewrite.internal.lang.NonNull;
23+
import org.openrewrite.gradle.marker.GradleProject;
2524
import org.openrewrite.internal.lang.Nullable;
25+
import org.openrewrite.java.dependencies.UpgradeDependencyVersion;
2626
import org.openrewrite.marker.SearchResult;
2727
import org.openrewrite.maven.MavenDownloadingException;
2828
import org.openrewrite.maven.MavenIsoVisitor;
@@ -33,40 +33,48 @@
3333

3434
import java.util.*;
3535

36+
import static java.util.Collections.emptyList;
3637
import static java.util.Collections.emptyMap;
3738

39+
@Value
3840
@EqualsAndHashCode(callSuper = false)
39-
public class UpgradeExplicitSpringBootDependencies extends Recipe {
41+
public class UpgradeExplicitSpringBootDependencies extends ScanningRecipe<UpgradeExplicitSpringBootDependencies.Accumulator> {
4042

4143
private static final String SPRINGBOOT_GROUP = "org.springframework.boot";
4244
private static final String SPRING_BOOT_DEPENDENCIES = "spring-boot-dependencies";
4345

44-
private transient final Map<String, String> springBootDependenciesMap = new HashMap<>();
45-
46-
@Option(displayName = "From Spring Version",
46+
@Option(displayName = "From Spring version",
4747
description = "XRage pattern for spring version used to limit which projects should be updated",
4848
example = " 2.7.+")
49-
private final String fromVersion;
49+
String fromVersion;
5050

51-
@Option(displayName = "To Spring Version",
51+
@Option(displayName = "To Spring version",
5252
description = "Upgrade version of `org.springframework.boot`",
5353
example = "3.0.0-M3")
54-
private final String toVersion;
55-
56-
@JsonCreator
57-
public UpgradeExplicitSpringBootDependencies(@JsonProperty("fromVersion") String fromVersion, @JsonProperty("toVersion") String toVersion) {
58-
this.fromVersion = fromVersion;
59-
this.toVersion = toVersion;
60-
}
54+
String toVersion;
6155

6256
@Override
6357
public String getDisplayName() {
64-
return "Upgrade un-managed spring project dependencies";
58+
return "Upgrade Spring dependencies";
6559
}
6660

6761
@Override
6862
public String getDescription() {
69-
return "Upgrades un-managed spring-boot project dependencies according to the specified spring-boot version.";
63+
return "Upgrades dependencies according to the specified version of spring boot. " +
64+
"Spring boot has many direct and transitive dependencies. When a module has an explicit dependency on " +
65+
"one of these it may also need to be upgraded to match the version used by spring boot.";
66+
}
67+
68+
@Data
69+
public static class Accumulator {
70+
UpgradeDependencyVersion.Accumulator udvAcc = new UpgradeDependencyVersion.Accumulator(
71+
new org.openrewrite.maven.UpgradeDependencyVersion.Accumulator(),
72+
new org.openrewrite.gradle.UpgradeDependencyVersion.DependencyVersionState()
73+
);
74+
List<MavenRepository> repositories = new ArrayList<>();
75+
Map<String, String> springBootDependenciesMap = new HashMap<>();
76+
@Nullable
77+
MavenDownloadingException mavenDownloadingException = null;
7078
}
7179

7280
private TreeVisitor<?, ExecutionContext> precondition() {
@@ -78,40 +86,113 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
7886
ResolvedManagedDependency managedDependency = findManagedDependency(resultTag);
7987
if (managedDependency != null && managedDependency.getGroupId().equals(SPRINGBOOT_GROUP)
8088
&& satisfiesOldVersionPattern(managedDependency.getVersion())) {
81-
return applyThisRecipe(resultTag);
89+
return SearchResult.found(resultTag);
8290
}
8391
}
8492

8593
if (isDependencyTag()) {
8694
ResolvedDependency dependency = findDependency(resultTag);
8795
if ((dependency != null) && dependency.getGroupId().equals(SPRINGBOOT_GROUP)
8896
&& satisfiesOldVersionPattern(dependency.getVersion())) {
89-
return applyThisRecipe(resultTag);
97+
return SearchResult.found(resultTag);
9098
}
9199
}
92100
return resultTag;
93101
}
94102

95-
@NonNull
96-
private Xml.Tag applyThisRecipe(Xml.Tag resultTag) {
97-
return resultTag.withMarkers(resultTag.getMarkers().addIfAbsent(new SearchResult(UUID.randomUUID(), "SpringBoot dependency")));
98-
}
99-
100103
private boolean satisfiesOldVersionPattern(@Nullable String version) {
101104
return version != null && XRange.build(fromVersion, version).isValid();
102105
}
103106
};
104107
}
105108

106109
@Override
107-
public TreeVisitor<?, ExecutionContext> getVisitor() {
110+
public Accumulator getInitialValue(ExecutionContext ctx) {
111+
return new Accumulator();
112+
}
113+
114+
@Override
115+
public TreeVisitor<?, ExecutionContext> getScanner(Accumulator acc) {
116+
//noinspection NullableProblems
117+
return new TreeVisitor<Tree, ExecutionContext>() {
118+
@Override
119+
public Tree visit(Tree tree, ExecutionContext ctx) {
120+
TreeVisitor<?, ExecutionContext> udvScanner = new UpgradeDependencyVersion("", "", "", null, null, null)
121+
.getScanner(acc.getUdvAcc());
122+
if (udvScanner.isAcceptable((SourceFile) tree, ctx)) {
123+
udvScanner.visit(tree, ctx);
124+
}
125+
126+
Optional<GradleProject> maybeGp = tree.getMarkers()
127+
.findFirst(GradleProject.class);
128+
if (maybeGp.isPresent()) {
129+
GradleProject gp = maybeGp.get();
130+
acc.repositories.addAll(gp.getMavenRepositories());
131+
}
132+
Optional<MavenResolutionResult> maybeMrr = tree.getMarkers()
133+
.findFirst(MavenResolutionResult.class);
134+
if (maybeMrr.isPresent()) {
135+
MavenResolutionResult mrr = maybeMrr.get();
136+
acc.repositories.addAll(mrr.getPom().getRepositories());
137+
}
138+
139+
return tree;
140+
}
141+
};
142+
}
143+
144+
@Override
145+
public Collection<? extends SourceFile> generate(Accumulator acc, Collection<SourceFile> generatedInThisCycle, ExecutionContext ctx) {
146+
List<MavenRepository> repositories = acc.getRepositories();
147+
repositories.add(MavenRepository.builder()
148+
.id("repository.spring.milestone")
149+
.uri("https://repo.spring.io/milestone")
150+
.releases(true)
151+
.snapshots(true)
152+
.build());
153+
repositories.add(MavenRepository.builder()
154+
.id("spring-snapshot")
155+
.uri("https://repo.spring.io/snapshot")
156+
.releases(false)
157+
.snapshots(true)
158+
.build());
159+
repositories.add(MavenRepository.builder()
160+
.id("spring-release")
161+
.uri("https://repo.spring.io/release")
162+
.releases(true)
163+
.snapshots(false)
164+
.build());
165+
166+
MavenPomDownloader downloader = new MavenPomDownloader(emptyMap(), ctx);
167+
GroupArtifactVersion gav = new GroupArtifactVersion(SPRINGBOOT_GROUP, SPRING_BOOT_DEPENDENCIES, toVersion);
168+
String relativePath = "";
169+
170+
try {
171+
Pom pom = downloader.download(gav, relativePath, null, repositories);
172+
ResolvedPom resolvedPom = pom.resolve(emptyList(), downloader, repositories, ctx);
173+
List<ResolvedManagedDependency> dependencyManagement = resolvedPom.getDependencyManagement();
174+
dependencyManagement
175+
.stream()
176+
.filter(d -> d.getVersion() != null)
177+
.forEach(d -> acc.getSpringBootDependenciesMap().put(d.getGroupId() + ":" + d.getArtifactId().toLowerCase(), d.getVersion()));
178+
} catch (MavenDownloadingException e) {
179+
acc.mavenDownloadingException = e;
180+
}
181+
return emptyList();
182+
}
183+
184+
@Override
185+
public Collection<? extends SourceFile> generate(Accumulator acc, ExecutionContext ctx) {
186+
return super.generate(acc, ctx);
187+
}
188+
189+
@Override
190+
public TreeVisitor<?, ExecutionContext> getVisitor(Accumulator acc) {
108191
return Preconditions.check(precondition(), new MavenIsoVisitor<ExecutionContext>() {
109192
@Override
110193
public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
111-
try {
112-
buildDependencyMap(ctx);
113-
} catch (MavenDownloadingException e) {
114-
return e.warn(document);
194+
if(acc.mavenDownloadingException != null) {
195+
return acc.mavenDownloadingException.warn(document);
115196
}
116197
return super.visitDocument(document, ctx);
117198
}
@@ -122,71 +203,29 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
122203
if (isManagedDependencyTag()) {
123204
ResolvedManagedDependency managedDependency = findManagedDependency(resultTag);
124205
if (managedDependency != null) {
125-
mayBeUpdateVersion(managedDependency.getGroupId(), managedDependency.getArtifactId(), resultTag);
206+
mayBeUpdateVersion(acc, managedDependency.getGroupId(), managedDependency.getArtifactId(), resultTag);
126207
}
127208
}
128209
if (isDependencyTag()) {
129210
ResolvedDependency dependency = findDependency(resultTag);
130211
if (dependency != null) {
131-
mayBeUpdateVersion(dependency.getGroupId(), dependency.getArtifactId(), resultTag);
212+
mayBeUpdateVersion(acc, dependency.getGroupId(), dependency.getArtifactId(), resultTag);
132213
}
133214
}
134215
return resultTag;
135216
}
136217

137-
private void mayBeUpdateVersion(String groupId, String artifactId, Xml.Tag tag) {
138-
String dependencyVersion = springBootDependenciesMap.get(groupId + ":" + artifactId);
218+
private void mayBeUpdateVersion(Accumulator acc, String groupId, String artifactId, Xml.Tag tag) {
219+
String dependencyVersion = acc.springBootDependenciesMap.get(groupId + ":" + artifactId);
139220
if (dependencyVersion != null) {
140221
Optional<Xml.Tag> version = tag.getChild("version");
141222
if (!version.isPresent() || !version.get().getValue().isPresent()) {
142223
return;
143224
}
144-
// TODO: we could use the org.openrewrite.java.dependencies.UpgradeDependencyVersion if we implement there a getVisitor with a similar logic than here,
145-
// but right now it's just a list of recipes, and the getVisitor is the default from Recipe and does nothing
146-
SourceFile sourceFile = getCursor().firstEnclosing(SourceFile.class);
147-
if (sourceFile instanceof Xml.Document) {
148-
doAfterVisit(new org.openrewrite.maven.UpgradeDependencyVersion(groupId, artifactId, dependencyVersion, null, null, null).getVisitor());
149-
} else if (sourceFile instanceof G.CompilationUnit) {
150-
doAfterVisit(new org.openrewrite.gradle.UpgradeDependencyVersion(groupId, artifactId, dependencyVersion, null).getVisitor());
151-
}
225+
doAfterVisit(new org.openrewrite.java.dependencies.UpgradeDependencyVersion(groupId, artifactId, dependencyVersion, null, true, null)
226+
.getVisitor(acc.getUdvAcc()));
152227
}
153228
}
154-
155-
private void buildDependencyMap(ExecutionContext ctx) throws MavenDownloadingException {
156-
if (springBootDependenciesMap.isEmpty()) {
157-
MavenPomDownloader downloader = new MavenPomDownloader(emptyMap(), ctx,
158-
getResolutionResult().getMavenSettings(), getResolutionResult().getActiveProfiles());
159-
GroupArtifactVersion gav = new GroupArtifactVersion(SPRINGBOOT_GROUP, SPRING_BOOT_DEPENDENCIES, toVersion);
160-
String relativePath = "";
161-
List<MavenRepository> repositories = new ArrayList<>();
162-
repositories.add(MavenRepository.builder()
163-
.id("repository.spring.milestone")
164-
.uri("https://repo.spring.io/milestone")
165-
.releases(true)
166-
.snapshots(true)
167-
.build());
168-
repositories.add(MavenRepository.builder()
169-
.id("spring-snapshot")
170-
.uri("https://repo.spring.io/snapshot")
171-
.releases(false)
172-
.snapshots(true)
173-
.build());
174-
repositories.add(MavenRepository.builder()
175-
.id("spring-release")
176-
.uri("https://repo.spring.io/release")
177-
.releases(true)
178-
.snapshots(false)
179-
.build());
180-
Pom pom = downloader.download(gav, relativePath, null, repositories);
181-
ResolvedPom resolvedPom = pom.resolve(Collections.emptyList(), downloader, repositories, ctx);
182-
List<ResolvedManagedDependency> dependencyManagement = resolvedPom.getDependencyManagement();
183-
dependencyManagement
184-
.stream()
185-
.filter(d -> d.getVersion() != null)
186-
.forEach(d -> springBootDependenciesMap.put(d.getGroupId() + ":" + d.getArtifactId().toLowerCase(), d.getVersion()));
187-
}
188-
}
189-
190229
});
191230
}
192231
}

0 commit comments

Comments
 (0)