Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added property version migration #4330

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,22 @@ public class ChangeDependencyGroupIdAndArtifactId extends Recipe {
@Nullable
Boolean changeManagedDependency;

@Option(displayName = "Update dependency management",
description = "Also update the dependency management section. The default for this flag is `true`.",
required = false)
@Nullable
Boolean changePropertyVersionNames;

public ChangeDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, @Nullable String newGroupId, @Nullable String newArtifactId, @Nullable String newVersion, @Nullable String versionPattern) {
this(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, versionPattern, false, true);
this(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, versionPattern, false, true, false);
}

@JsonCreator
public ChangeDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, @Nullable String newGroupId, @Nullable String newArtifactId, @Nullable String newVersion, @Nullable String versionPattern, @Nullable Boolean overrideManagedVersion, @Nullable Boolean changeManagedDependency) {
this(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, versionPattern, overrideManagedVersion, changeManagedDependency, false);
}

@JsonCreator
public ChangeDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, @Nullable String newGroupId, @Nullable String newArtifactId, @Nullable String newVersion, @Nullable String versionPattern, @Nullable Boolean overrideManagedVersion, @Nullable Boolean changeManagedDependency, @Nullable Boolean changePropertyVersionNames) {
this.oldGroupId = oldGroupId;
this.oldArtifactId = oldArtifactId;
this.newGroupId = newGroupId;
Expand All @@ -108,6 +118,7 @@ public ChangeDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifac
this.versionPattern = versionPattern;
this.overrideManagedVersion = overrideManagedVersion;
this.changeManagedDependency = changeManagedDependency;
this.changePropertyVersionNames = changePropertyVersionNames;
}

@Override
Expand Down Expand Up @@ -156,13 +167,13 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {

@Override
public Xml visitDocument(Xml.Document document, ExecutionContext ctx) {
// Any managed dependency change is unlikely to use the same version, so only update selectively.
if ((changeManagedDependency == null || changeManagedDependency) && newVersion != null || versionPattern != null) {
// Any managed dependency change is unlikely to use the same version, so only update selectively. If the new dependency is already managed, don't change the old dependency. It will be removed at the end.
if ((changeManagedDependency == null || changeManagedDependency) && newVersion != null && !isDependencyManaged(newGroupId, newArtifactId, newVersion)) {
doAfterVisit(new ChangeManagedDependencyGroupIdAndArtifactId(
oldGroupId, oldArtifactId,
Optional.ofNullable(newGroupId).orElse(oldGroupId),
Optional.ofNullable(newArtifactId).orElse(oldArtifactId),
newVersion, versionPattern).getVisitor());
newVersion, versionPattern, changePropertyVersionNames).getVisitor());
}
return super.visitDocument(document, ctx);
}
Expand Down Expand Up @@ -203,13 +214,35 @@ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
t = (Xml.Tag) new RemoveContentVisitor<>(versionTag.get(), false).visit(t, ctx);
} else {
// Otherwise, change the version to the new value.
t = changeChildTagValue(t, "version", resolvedNewVersion, ctx);
if (Objects.requireNonNull(currentVersion).contains("$")) {
// If the version is a property value, change version in property section and rename the property if changePropertyNames is true.
String propertyVariable = currentVersion.substring(2, currentVersion.length() - 1);
String newPropertyVariable = propertyVariable;
if (Boolean.TRUE.equals(changePropertyVersionNames)){
newPropertyVariable = newArtifactId + ".version";
doAfterVisit(new RenamePropertyKey(propertyVariable, newPropertyVariable).getVisitor());
t = changeChildTagValue(t, "version", "${"+newPropertyVariable+"}", ctx);
}
doAfterVisit(new ChangePropertyValue(newPropertyVariable, resolvedNewVersion, false, false).getVisitor());
} else {
//If the version is no property value, change it right here.
t = changeChildTagValue(t, "version", resolvedNewVersion, ctx);
}

}
} else if (configuredToOverrideManageVersion || !newDependencyManaged) {
//If the version is not present, add the version if we are explicitly overriding a managed version or if no managed version exists.
Xml.Tag newVersionTag = Xml.Tag.build("<version>" + resolvedNewVersion + "</version>");
//noinspection ConstantConditions
t = (Xml.Tag) new AddToTagVisitor<ExecutionContext>(t, newVersionTag, new MavenTagInsertionComparator(t.getChildren())).visitNonNull(t, ctx, getCursor().getParent());
} else if (!(newDependencyManaged && configuredToChangeManagedDependency)) {
//If the Version not present and the new version is not managed and/or the changeManagedDependency Option is false.
List<ResolvedManagedDependency> md = getResolutionResult().getPom().getDependencyManagement();
if (configuredToOverrideManageVersion || ((!md.isEmpty() && md.get(0).getRequestedBom() != null) && !newDependencyManaged) || !configuredToChangeManagedDependency) {
//If the version is not present, add the version if we are explicitly overriding a managed version, if no managed version exists with no collection of dependencies or changeManageDependency is false.
Xml.Tag newVersionTag = Xml.Tag.build("<version>" + resolvedNewVersion + "</version>");
//noinspection ConstantConditions
t = (Xml.Tag) new AddToTagVisitor<ExecutionContext>(t, newVersionTag, new MavenTagInsertionComparator(t.getChildren())).visitNonNull(t, ctx, getCursor().getParent());
}

} else if (oldDependencyManaged){
//If the version is not present and the new and old version are managed, remove the old dependency
doAfterVisit(new RemoveManagedDependency(oldGroupId,oldArtifactId, null).getVisitor());
}
} catch (MavenDownloadingException e) {
return e.warn(tag);
Expand Down Expand Up @@ -243,6 +276,17 @@ private boolean isDependencyManaged(Scope scope, String groupId, String artifact
return false;
}

private boolean isDependencyManaged(String groupId, String artifactId, String version) {

MavenResolutionResult result = getResolutionResult();
for (ResolvedManagedDependency managedDependency : result.getPom().getDependencyManagement()) {
if (groupId.equals(managedDependency.getGroupId()) && artifactId.equals(managedDependency.getArtifactId()) && version.equals(managedDependency.getVersion())) {
return true;
}
}
return false;
}

@SuppressWarnings("ConstantConditions")
private String resolveSemverVersion(ExecutionContext ctx, String groupId, String artifactId, @Nullable String currentVersion) throws MavenDownloadingException {
if (versionComparator == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,29 +72,36 @@ public class ChangeManagedDependencyGroupIdAndArtifactId extends Recipe {

@Option(displayName = "Version pattern",
description = "Allows version selection to be extended beyond the original Node Semver semantics. So for example," +
"Setting 'version' to \"25-29\" can be paired with a metadata pattern of \"-jre\" to select Guava 29.0-jre",
"Setting 'version' to \"25-29\" can be paired with a metadata pattern of \"-jre\" to select Guava 29.0-jre",
example = "-jre",
required = false)
@Nullable
String versionPattern;

@Option(displayName = "Change property version names",
description = "Allows property version names to be changed to best practice naming convention",
example = "-jre",
required = false)
@Nullable
Boolean changePropertyVersionNames;

public ChangeManagedDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, String newGroupId, String newArtifactId, @Nullable String newVersion) {
this.oldGroupId = oldGroupId;
this.oldArtifactId = oldArtifactId;
this.newGroupId = newGroupId;
this.newArtifactId = newArtifactId;
this.newVersion = newVersion;
this.versionPattern = null;
this(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, null, false);
}

@JsonCreator
public ChangeManagedDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, String newGroupId, String newArtifactId, @Nullable String newVersion, @Nullable String versionPattern) {
this(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, versionPattern, false);
}

@JsonCreator
public ChangeManagedDependencyGroupIdAndArtifactId(String oldGroupId, String oldArtifactId, String newGroupId, String newArtifactId, @Nullable String newVersion, @Nullable String versionPattern, @Nullable Boolean changePropertyVersionNames) {
this.oldGroupId = oldGroupId;
this.oldArtifactId = oldArtifactId;
this.newGroupId = newGroupId;
this.newArtifactId = newArtifactId;
this.newVersion = newVersion;
this.versionPattern = versionPattern;
this.changePropertyVersionNames = changePropertyVersionNames;
}

@Override
Expand Down Expand Up @@ -156,8 +163,21 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
Optional<Xml.Tag> versionTag = t.getChild("version");

if (versionTag.isPresent()) {
String resolvedNewVersion = resolveSemverVersion(ctx, newGroupId, newArtifactId, versionTag.get().getValue().orElse(null));
t = (Xml.Tag) new ChangeTagValueVisitor<>(versionTag.get(), resolvedNewVersion).visitNonNull(t, 0, getCursor().getParentOrThrow());
String version = versionTag.get().getValue().orElse(null);
String resolvedNewVersion = resolveSemverVersion(ctx, newGroupId, newArtifactId, version);
if (Objects.requireNonNull(version).contains("$")) {
String propertyVariable = version.substring(2, version.length() - 1);
String newPropertyVariable = propertyVariable;
if (Boolean.TRUE.equals(changePropertyVersionNames)){
newPropertyVariable = newArtifactId + ".version";
doAfterVisit(new RenamePropertyKey(propertyVariable, newPropertyVariable).getVisitor());
t = changeChildTagValue(t, "version", "${"+newPropertyVariable+"}", ctx);
}
doAfterVisit(new ChangePropertyValue(newPropertyVariable, resolvedNewVersion, false, false).getVisitor());
} else {
t = changeChildTagValue(t, "version", resolvedNewVersion, ctx);
}

}
changed = true;
} catch(MavenDownloadingException e) {
Expand All @@ -172,8 +192,21 @@ public Xml.Tag visitTag(Xml.Tag tag, ExecutionContext ctx) {
return t;
}

private Xml.Tag changeChildTagValue(Xml.Tag tag, String childTagName, String newValue, ExecutionContext ctx) {
Optional<Xml.Tag> childTag = tag.getChild(childTagName);
if (childTag.isPresent() && !newValue.equals(childTag.get().getValue().orElse(null))) {
tag = (Xml.Tag) new ChangeTagValueVisitor<>(childTag.get(), newValue).visitNonNull(tag, ctx);
}
return tag;
}

@SuppressWarnings("ConstantConditions")
private String resolveSemverVersion(ExecutionContext ctx, String groupId, String artifactId, @Nullable String currentVersion) throws MavenDownloadingException {
if (currentVersion.contains("$")){
String propertyVariable = currentVersion.substring(2, currentVersion.length() - 1);
currentVersion = getResolutionResult().getPom().getProperties().get(propertyVariable);
}

if (versionComparator == null) {
return newVersion;
}
Expand Down
Loading
Loading