16
16
17
17
package org .openrewrite .maven .spring ;
18
18
19
- import com .fasterxml .jackson .annotation .JsonCreator ;
20
- import com .fasterxml .jackson .annotation .JsonProperty ;
19
+ import lombok .Data ;
21
20
import lombok .EqualsAndHashCode ;
21
+ import lombok .Value ;
22
22
import org .openrewrite .*;
23
- import org .openrewrite .groovy .tree .G ;
24
- import org .openrewrite .internal .lang .NonNull ;
23
+ import org .openrewrite .gradle .marker .GradleProject ;
25
24
import org .openrewrite .internal .lang .Nullable ;
25
+ import org .openrewrite .java .dependencies .UpgradeDependencyVersion ;
26
26
import org .openrewrite .marker .SearchResult ;
27
27
import org .openrewrite .maven .MavenDownloadingException ;
28
28
import org .openrewrite .maven .MavenIsoVisitor ;
33
33
34
34
import java .util .*;
35
35
36
+ import static java .util .Collections .emptyList ;
36
37
import static java .util .Collections .emptyMap ;
37
38
39
+ @ Value
38
40
@ EqualsAndHashCode (callSuper = false )
39
- public class UpgradeExplicitSpringBootDependencies extends Recipe {
41
+ public class UpgradeExplicitSpringBootDependencies extends ScanningRecipe < UpgradeExplicitSpringBootDependencies . Accumulator > {
40
42
41
43
private static final String SPRINGBOOT_GROUP = "org.springframework.boot" ;
42
44
private static final String SPRING_BOOT_DEPENDENCIES = "spring-boot-dependencies" ;
43
45
44
- private transient final Map <String , String > springBootDependenciesMap = new HashMap <>();
45
-
46
- @ Option (displayName = "From Spring Version" ,
46
+ @ Option (displayName = "From Spring version" ,
47
47
description = "XRage pattern for spring version used to limit which projects should be updated" ,
48
48
example = " 2.7.+" )
49
- private final String fromVersion ;
49
+ String fromVersion ;
50
50
51
- @ Option (displayName = "To Spring Version " ,
51
+ @ Option (displayName = "To Spring version " ,
52
52
description = "Upgrade version of `org.springframework.boot`" ,
53
53
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 ;
61
55
62
56
@ Override
63
57
public String getDisplayName () {
64
- return "Upgrade un-managed spring project dependencies" ;
58
+ return "Upgrade Spring dependencies" ;
65
59
}
66
60
67
61
@ Override
68
62
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 ;
70
78
}
71
79
72
80
private TreeVisitor <?, ExecutionContext > precondition () {
@@ -78,40 +86,113 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
78
86
ResolvedManagedDependency managedDependency = findManagedDependency (resultTag );
79
87
if (managedDependency != null && managedDependency .getGroupId ().equals (SPRINGBOOT_GROUP )
80
88
&& satisfiesOldVersionPattern (managedDependency .getVersion ())) {
81
- return applyThisRecipe (resultTag );
89
+ return SearchResult . found (resultTag );
82
90
}
83
91
}
84
92
85
93
if (isDependencyTag ()) {
86
94
ResolvedDependency dependency = findDependency (resultTag );
87
95
if ((dependency != null ) && dependency .getGroupId ().equals (SPRINGBOOT_GROUP )
88
96
&& satisfiesOldVersionPattern (dependency .getVersion ())) {
89
- return applyThisRecipe (resultTag );
97
+ return SearchResult . found (resultTag );
90
98
}
91
99
}
92
100
return resultTag ;
93
101
}
94
102
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
-
100
103
private boolean satisfiesOldVersionPattern (@ Nullable String version ) {
101
104
return version != null && XRange .build (fromVersion , version ).isValid ();
102
105
}
103
106
};
104
107
}
105
108
106
109
@ 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 ) {
108
191
return Preconditions .check (precondition (), new MavenIsoVisitor <ExecutionContext >() {
109
192
@ Override
110
193
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 );
115
196
}
116
197
return super .visitDocument (document , ctx );
117
198
}
@@ -122,71 +203,29 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
122
203
if (isManagedDependencyTag ()) {
123
204
ResolvedManagedDependency managedDependency = findManagedDependency (resultTag );
124
205
if (managedDependency != null ) {
125
- mayBeUpdateVersion (managedDependency .getGroupId (), managedDependency .getArtifactId (), resultTag );
206
+ mayBeUpdateVersion (acc , managedDependency .getGroupId (), managedDependency .getArtifactId (), resultTag );
126
207
}
127
208
}
128
209
if (isDependencyTag ()) {
129
210
ResolvedDependency dependency = findDependency (resultTag );
130
211
if (dependency != null ) {
131
- mayBeUpdateVersion (dependency .getGroupId (), dependency .getArtifactId (), resultTag );
212
+ mayBeUpdateVersion (acc , dependency .getGroupId (), dependency .getArtifactId (), resultTag );
132
213
}
133
214
}
134
215
return resultTag ;
135
216
}
136
217
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 );
139
220
if (dependencyVersion != null ) {
140
221
Optional <Xml .Tag > version = tag .getChild ("version" );
141
222
if (!version .isPresent () || !version .get ().getValue ().isPresent ()) {
142
223
return ;
143
224
}
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 ()));
152
227
}
153
228
}
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
-
190
229
});
191
230
}
192
231
}
0 commit comments