Skip to content

Commit 74b8163

Browse files
committed
Configuration for how failures in UpgradeDependencyVersion should be handled
1 parent 0561b2c commit 74b8163

2 files changed

Lines changed: 121 additions & 78 deletions

File tree

rewrite-core/src/main/java/org/openrewrite/RecipeRunException.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ public RecipeRunException(Throwable cause) {
4141
this(cause, null);
4242
}
4343

44-
public String getSanitizedStackTrace() {
44+
public static String getSanitizedStackTrace(Throwable cause) {
4545
StringJoiner sanitized = new StringJoiner("\n");
46-
sanitized.add(getCause().getClass().getName() + ": " + getCause().getLocalizedMessage());
46+
sanitized.add(cause.getClass().getName() + ": " + cause.getLocalizedMessage());
4747

4848
int i = 0;
49-
for (StackTraceElement stackTraceElement : getCause().getStackTrace()) {
49+
for (StackTraceElement stackTraceElement : cause.getStackTrace()) {
5050
if (stackTraceElement.getClassName().equals(RecipeScheduler.class.getName())) {
5151
break;
5252
}

rewrite-maven/src/main/java/org/openrewrite/maven/UpgradeDependencyVersion.java

Lines changed: 118 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.openrewrite.*;
2121
import org.openrewrite.internal.ListUtils;
2222
import org.openrewrite.internal.lang.Nullable;
23+
import org.openrewrite.maven.internal.MavenDownloadingException;
2324
import org.openrewrite.maven.tree.*;
2425
import org.openrewrite.semver.Semver;
2526
import org.openrewrite.semver.VersionComparator;
@@ -75,6 +76,14 @@ public class UpgradeDependencyVersion extends Recipe {
7576
@Nullable
7677
Boolean overrideManagedVersion;
7778

79+
@Option(displayName = "Metadata failure mode",
80+
description = "In the event that metadata for a matching dependency cannot be determined, this option determines how to handle the failure",
81+
example = "fail",
82+
valid = {"ignore", "warn", "fail"},
83+
required = false)
84+
@Nullable
85+
String metadataFailureMode;
86+
7887
@SuppressWarnings("ConstantConditions")
7988
@Override
8089
public Validated validate() {
@@ -140,105 +149,139 @@ public Xml.Document visitDocument(Xml.Document document, ExecutionContext ctx) {
140149
@Override
141150
public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
142151
Xml.Tag t = super.visitTag(tag, ctx);
143-
if (isDependencyTag(groupId, artifactId)) {
144-
145-
ResolvedDependency d = findDependency(tag);
146-
if (d != null && d.getRepository() != null) {
147-
//If the resolved dependency exists AND it does not represent an artifact that was parsed
148-
//as a source file, attempt to find a new version.
149-
String newerVersion = findNewerVersion(d.getGroupId(), d.getArtifactId(), d.getVersion(), ctx);
150-
if (newerVersion != null) {
151-
ResolvedManagedDependency dm = findManagedDependency(t);
152-
if (dm != null) {
153-
String requestedVersion = dm.getRequested().getVersion();
154-
if (requestedVersion.startsWith("${")) {
155-
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
156-
return t;
152+
try {
153+
if (isDependencyTag(groupId, artifactId)) {
154+
155+
ResolvedDependency d = findDependency(tag);
156+
if (d != null && d.getRepository() != null) {
157+
//If the resolved dependency exists AND it does not represent an artifact that was parsed
158+
//as a source file, attempt to find a new version.
159+
String newerVersion = findNewerVersion(d.getGroupId(), d.getArtifactId(), d.getVersion(), ctx);
160+
if (newerVersion != null) {
161+
ResolvedManagedDependency dm = findManagedDependency(t);
162+
if (dm != null) {
163+
String requestedVersion = dm.getRequested().getVersion();
164+
if (requestedVersion.startsWith("${")) {
165+
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
166+
return t;
167+
}
157168
}
158-
}
159169

160-
Optional<Xml.Tag> version = t.getChild("version");
161-
if (version.isPresent()) {
162-
String requestedVersion = d.getRequested().getVersion();
163-
if (requestedVersion != null && requestedVersion.startsWith("${")) {
164-
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
165-
return t;
170+
Optional<Xml.Tag> version = t.getChild("version");
171+
if (version.isPresent()) {
172+
String requestedVersion = d.getRequested().getVersion();
173+
if (requestedVersion != null && requestedVersion.startsWith("${")) {
174+
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
175+
return t;
176+
}
177+
t = (Xml.Tag) new ChangeTagValueVisitor<>(version.get(), newerVersion).visitNonNull(t, 0, getCursor());
178+
} else if (Boolean.TRUE.equals(overrideManagedVersion)) {
179+
//If the version is not present and the override managed version is set, add a new, explicit version tag.
180+
Xml.Tag versionTag = Xml.Tag.build("<version>" + newerVersion + "</version>");
181+
//noinspection ConstantConditions
182+
t = (Xml.Tag) new AddToTagVisitor<ExecutionContext>(t, versionTag, new MavenTagInsertionComparator(t.getChildren())).visitNonNull(t, ctx, getCursor().getParent());
166183
}
167-
t = (Xml.Tag) new ChangeTagValueVisitor<Integer>(version.get(), newerVersion).visitNonNull(t, 0, getCursor());
168-
} else if (Boolean.TRUE.equals(overrideManagedVersion)) {
169-
//If the version is not present and the override managed version is set, add a new, explicit version tag.
170-
Xml.Tag versionTag = Xml.Tag.build("<version>" + newerVersion + "</version>");
171-
//noinspection ConstantConditions
172-
t = (Xml.Tag) new AddToTagVisitor<ExecutionContext>(t, versionTag, new MavenTagInsertionComparator(t.getChildren())).visitNonNull(t, ctx, getCursor().getParent());
173184
}
174185
}
175-
}
176-
} else if (isManagedDependencyTag(groupId, artifactId)) {
186+
} else if (isManagedDependencyTag(groupId, artifactId)) {
177187

178-
ResolvedManagedDependency matchedManagedDependency = findManagedDependency(t);
179-
if (matchedManagedDependency != null) {
180-
if (!projectArtifacts.contains(new GroupArtifact(matchedManagedDependency.getGroupId(), matchedManagedDependency.getArtifactId())) &&
181-
matchesGlob(matchedManagedDependency.getGroupId(), groupId) && matchesGlob(matchedManagedDependency.getArtifactId(), artifactId)) {
188+
ResolvedManagedDependency matchedManagedDependency = findManagedDependency(t);
189+
if (matchedManagedDependency != null) {
190+
if (!projectArtifacts.contains(new GroupArtifact(matchedManagedDependency.getGroupId(), matchedManagedDependency.getArtifactId())) &&
191+
matchesGlob(matchedManagedDependency.getGroupId(), groupId) && matchesGlob(matchedManagedDependency.getArtifactId(), artifactId)) {
182192

183-
String requestedVersion = matchedManagedDependency.getRequested().getVersion();
184-
assert (matchedManagedDependency.getVersion() != null);
185-
String newerVersion = findNewerVersion(matchedManagedDependency.getGroupId(), matchedManagedDependency.getArtifactId(), matchedManagedDependency.getVersion(), ctx);
186-
if (newerVersion != null) {
187-
if (requestedVersion.startsWith("${")) {
188-
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
189-
return t;
190-
}
191-
Xml.Tag childVersionTag = t.getChild("version").orElse(null);
192-
if (childVersionTag != null) {
193-
t = (Xml.Tag) new ChangeTagValueVisitor<Integer>(childVersionTag, newerVersion).visitNonNull(t, 0, getCursor());
193+
String requestedVersion = matchedManagedDependency.getRequested().getVersion();
194+
assert (matchedManagedDependency.getVersion() != null);
195+
String newerVersion = findNewerVersion(matchedManagedDependency.getGroupId(), matchedManagedDependency.getArtifactId(), matchedManagedDependency.getVersion(), ctx);
196+
if (newerVersion != null) {
197+
if (requestedVersion.startsWith("${")) {
198+
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
199+
return t;
200+
}
201+
Xml.Tag childVersionTag = t.getChild("version").orElse(null);
202+
if (childVersionTag != null) {
203+
t = (Xml.Tag) new ChangeTagValueVisitor<Integer>(childVersionTag, newerVersion).visitNonNull(t, 0, getCursor());
204+
}
194205
}
195206
}
196-
}
197-
} else {
198-
for (ResolvedManagedDependency dm : getResolutionResult().getPom().getDependencyManagement()) {
199-
if (dm.getBomGav() != null) {
200-
String tagGroup = getResolutionResult().getPom().getValue(tag.getChildValue("groupId").orElse(getResolutionResult().getPom().getGroupId()));
201-
String tagArtifactId = getResolutionResult().getPom().getValue(tag.getChildValue("artifactId").orElse(""));
202-
203-
if (!projectArtifacts.contains(new GroupArtifact(tagGroup, tagArtifactId))) {
204-
ResolvedGroupArtifactVersion bom = dm.getBomGav();
205-
206-
if (tagGroup != null && tagArtifactId != null && tagGroup.equals(bom.getGroupId()) && tagArtifactId.equals(bom.getArtifactId())) {
207-
208-
//noinspection ConstantConditions
209-
String requestedVersion = dm.getRequestedBom().getVersion();
210-
String newerVersion = findNewerVersion(bom.getGroupId(), bom.getArtifactId(), bom.getVersion(), ctx);
211-
if (newerVersion != null) {
212-
if (requestedVersion.startsWith("${")) {
213-
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
214-
return t;
215-
}
216-
Xml.Tag childVersionTag = t.getChild("version").orElse(null);
217-
if (childVersionTag != null) {
218-
t = (Xml.Tag) new ChangeTagValueVisitor<Integer>(childVersionTag, newerVersion).visitNonNull(t, 0, getCursor());
207+
} else {
208+
for (ResolvedManagedDependency dm : getResolutionResult().getPom().getDependencyManagement()) {
209+
if (dm.getBomGav() != null) {
210+
String tagGroup = getResolutionResult().getPom().getValue(tag.getChildValue("groupId").orElse(getResolutionResult().getPom().getGroupId()));
211+
String tagArtifactId = getResolutionResult().getPom().getValue(tag.getChildValue("artifactId").orElse(""));
212+
213+
if (!projectArtifacts.contains(new GroupArtifact(tagGroup, tagArtifactId))) {
214+
ResolvedGroupArtifactVersion bom = dm.getBomGav();
215+
216+
if (tagGroup != null && tagArtifactId != null && tagGroup.equals(bom.getGroupId()) && tagArtifactId.equals(bom.getArtifactId())) {
217+
218+
//noinspection ConstantConditions
219+
String requestedVersion = dm.getRequestedBom().getVersion();
220+
String newerVersion = findNewerVersion(bom.getGroupId(), bom.getArtifactId(), bom.getVersion(), ctx);
221+
if (newerVersion != null) {
222+
if (requestedVersion.startsWith("${")) {
223+
doAfterVisit(new ChangePropertyValue(requestedVersion.substring(2, requestedVersion.length() - 1), newerVersion, overrideManagedVersion, false));
224+
return t;
225+
}
226+
Xml.Tag childVersionTag = t.getChild("version").orElse(null);
227+
if (childVersionTag != null) {
228+
t = (Xml.Tag) new ChangeTagValueVisitor<Integer>(childVersionTag, newerVersion).visitNonNull(t, 0, getCursor());
229+
}
219230
}
231+
break;
220232
}
221-
break;
222233
}
223234
}
224235
}
225236
}
226237
}
238+
} catch (MavenDownloadingException exception) {
239+
FailureMode failureMode = FailureMode.getFailureMode(metadataFailureMode);
240+
if (failureMode == FailureMode.FAIL) {
241+
throw exception;
242+
} else if (failureMode == FailureMode.IGNORE) {
243+
ctx.getOnError().accept(exception);
244+
} else if (failureMode == FailureMode.WARN) {
245+
return t.withMarkers(t.getMarkers().searchResult(UncaughtVisitorException.getSanitizedStackTrace(exception)));
246+
}
227247
}
228248
return t;
229249
}
230250

231251
@Nullable
232252
private String findNewerVersion(String groupId, String artifactId, String version, ExecutionContext ctx) {
233-
234-
MavenMetadata mavenMetadata = downloadMetadata(groupId, artifactId, ctx);
235-
List<String> versions = new ArrayList<>();
236-
for (String v : mavenMetadata.getVersioning().getVersions()) {
237-
if (versionComparator.isValid(version, v)) {
238-
versions.add(v);
253+
try {
254+
MavenMetadata mavenMetadata = downloadMetadata(groupId, artifactId, ctx);
255+
List<String> versions = new ArrayList<>();
256+
for (String v : mavenMetadata.getVersioning().getVersions()) {
257+
if (versionComparator.isValid(version, v)) {
258+
versions.add(v);
259+
}
239260
}
261+
return versionComparator.upgrade(version, versions).orElse(null);
262+
} catch (IllegalStateException e) {
263+
//This can happen when we encounter exotic versions. Pass the error to the error handler and
264+
//in the spirit of "do no harm", return null.
265+
ctx.getOnError().accept(e);
266+
return null;
240267
}
241-
return versionComparator.upgrade(version, versions).orElse(null);
242268
}
243269
}
270+
271+
private enum FailureMode {
272+
IGNORE,
273+
WARN,
274+
FAIL;
275+
276+
private static FailureMode getFailureMode(@Nullable String configuration) {
277+
if ("ignore".equals(configuration)) {
278+
return FailureMode.IGNORE;
279+
} else if ("warn".equals(configuration)) {
280+
return FailureMode.WARN;
281+
} else {
282+
return FailureMode.FAIL;
283+
}
284+
}
285+
}
286+
244287
}

0 commit comments

Comments
 (0)