Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
import org.openrewrite.internal.ListUtils;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.java.JavaVisitor;
import org.openrewrite.java.MethodMatcher;
import org.openrewrite.java.tree.Expression;
import org.openrewrite.java.tree.J;
import org.openrewrite.java.tree.JavaType;
Expand Down Expand Up @@ -56,7 +55,6 @@
@EqualsAndHashCode(callSuper = false)
public class UpgradePluginVersion extends ScanningRecipe<UpgradePluginVersion.DependencyVersionState> {
private static final String GRADLE_PROPERTIES_FILE_NAME = "gradle.properties";
private static final MethodMatcher VERSION_MATCHER = new MethodMatcher("org.gradle.plugin.use.PluginDependencySpec version(..)", true);

@EqualsAndHashCode.Exclude
transient MavenMetadataFailures metadataFailures = new MavenMetadataFailures(this);
Expand Down Expand Up @@ -110,23 +108,6 @@ public DependencyVersionState getInitialValue(ExecutionContext ctx) {
return new DependencyVersionState();
}

@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean isPluginVersion(Cursor cursor) {
if (!(cursor.getValue() instanceof J.MethodInvocation)) {
return false;
}
J.MethodInvocation maybeVersion = cursor.getValue();
if (!VERSION_MATCHER.matches(maybeVersion, true)) {
return false;
}
Cursor parent = cursor.dropParentUntil(it -> (it instanceof J.MethodInvocation) || it == Cursor.ROOT_VALUE);
if (!(parent.getValue() instanceof J.MethodInvocation)) {
return false;
}
J.MethodInvocation maybePlugins = parent.getValue();
return "plugins".equals(maybePlugins.getSimpleName());
}

@Override
public TreeVisitor<?, ExecutionContext> getScanner(DependencyVersionState acc) {

Expand Down Expand Up @@ -164,37 +145,18 @@ public J visitVariable(J.VariableDeclarations.NamedVariable variable, ExecutionC
@Override
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
if (!isPluginVersion(getCursor())) {
return m;
}
assert m.getSelect() != null;
List<Expression> pluginArgs = ((J.MethodInvocation) m.getSelect()).getArguments();
if (!(pluginArgs.get(0) instanceof J.Literal)) {
return m;
}
String pluginId;
if ("kotlin".equals(((J.MethodInvocation) m.getSelect()).getSimpleName())) {
pluginId = "kotlin";
} else {
pluginId = literalValue(pluginArgs.get(0));
}
if (pluginId == null || !StringUtils.matchesGlob(pluginId, pluginIdPattern)) {

GradlePlugin plugin = new GradlePlugin.Matcher().pluginIdPattern(pluginIdPattern).get(getCursor()).orElse(null);
if (plugin == null || plugin.getPluginId() == null) {
return m;
}

String pluginId = plugin.getPluginId();
List<Expression> versionArgs = m.getArguments();
try {
String currentVersion = literalValue(versionArgs.get(0));
if (currentVersion != null) {
String resolvedVersion;
if ("kotlin".equals(pluginId)) {
String fullPluginId = String.format("org.jetbrains.%s.%s", pluginId, literalValue(pluginArgs.get(0)));
resolvedVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifactVersion(fullPluginId, fullPluginId + ".gradle.plugin", currentVersion), "classpath", newVersion, versionPattern, ctx);
} else {
resolvedVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifactVersion(pluginId, pluginId + ".gradle.plugin", currentVersion), "classpath", newVersion, versionPattern, ctx);
}
if (plugin.getVersion() != null) {
String resolvedVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifactVersion(pluginId, pluginId + ".gradle.plugin", plugin.getVersion()), "classpath", newVersion, versionPattern, ctx);
acc.pluginIdToNewVersion.put(pluginId, resolvedVersion);
} else if (versionArgs.get(0) instanceof G.GString) {
G.GString gString = (G.GString) versionArgs.get(0);
Expand All @@ -204,31 +166,23 @@ public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx)

G.GString.Value gStringValue = (G.GString.Value) gString.getStrings().get(0);
String versionVariableName = gStringValue.getTree().toString();
String resolverPluginId = pluginId;
if ("kotlin".equals(pluginId)) {
resolverPluginId = String.format("org.jetbrains.%s.%s", pluginId, literalValue(pluginArgs.get(0)));
}
String resolvedPluginVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifact(resolverPluginId, resolverPluginId + ".gradle.plugin"), "classpath", newVersion, versionPattern, ctx);
.select(new GroupArtifact(pluginId, pluginId + ".gradle.plugin"), "classpath", newVersion, versionPattern, ctx);

acc.versionPropNameToPluginId.put(versionVariableName, pluginId);
assert resolvedPluginVersion != null;
acc.pluginIdToNewVersion.put(pluginId, resolvedPluginVersion);
} else if (versionArgs.get(0) instanceof J.Identifier) {
J.Identifier identifier = (J.Identifier) versionArgs.get(0);
String versionVariableName = identifier.getSimpleName();
String resolverPluginId = pluginId;
if ("kotlin".equals(pluginId)) {
resolverPluginId = String.format("org.jetbrains.%s.%s", pluginId, literalValue(pluginArgs.get(0)));
}
String localCurrentVersion = localVariableValues.get(versionVariableName);
String resolvedPluginVersion;
if (localCurrentVersion != null) {
resolvedPluginVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifactVersion(resolverPluginId, resolverPluginId + ".gradle.plugin", localCurrentVersion), "classpath", newVersion, versionPattern, ctx);
.select(new GroupArtifactVersion(pluginId, pluginId + ".gradle.plugin", localCurrentVersion), "classpath", newVersion, versionPattern, ctx);
} else {
resolvedPluginVersion = new DependencyVersionSelector(metadataFailures, gradleProject, gradleSettings)
.select(new GroupArtifact(resolverPluginId, resolverPluginId + ".gradle.plugin"), "classpath", newVersion, versionPattern, ctx);
.select(new GroupArtifact(pluginId, pluginId + ".gradle.plugin"), "classpath", newVersion, versionPattern, ctx);
}

acc.versionPropNameToPluginId.put(versionVariableName, pluginId);
Expand Down Expand Up @@ -338,31 +292,21 @@ public Properties visitEntry(Properties.Entry entry, ExecutionContext ctx) {

@Override
public J visitMethodInvocation(J.MethodInvocation method, ExecutionContext ctx) {
// Match the trait before super to ensure the cursor is unmodified
GradlePlugin plugin = new GradlePlugin.Matcher().pluginIdPattern(pluginIdPattern).get(getCursor()).orElse(null);

J.MethodInvocation m = (J.MethodInvocation) super.visitMethodInvocation(method, ctx);
if (!isPluginVersion(getCursor())) {
return m;
}
assert m.getSelect() != null;
List<Expression> pluginArgs = ((J.MethodInvocation) m.getSelect()).getArguments();
String pluginId;
if ("kotlin".equals(((J.MethodInvocation) m.getSelect()).getSimpleName())) {
pluginId = "kotlin";
} else {
pluginId = literalValue(pluginArgs.get(0));
}
if (pluginId == null || !StringUtils.matchesGlob(pluginId, pluginIdPattern)) {
return m;
}

List<Expression> versionArgs = m.getArguments();
String currentVersion = literalValue(m.getArguments().get(0));
if (currentVersion == null) {
if (plugin == null || plugin.getPluginId() == null || plugin.getVersion() == null ||
!"version".equals(m.getSimpleName())) {
return m;
}
String resolvedVersion = acc.pluginIdToNewVersion.get(pluginId);

String resolvedVersion = acc.pluginIdToNewVersion.get(plugin.getPluginId());
if (resolvedVersion == null) {
return m;
}
List<Expression> versionArgs = m.getArguments();
return m.withArguments(ListUtils.map(versionArgs, v -> ChangeStringLiteral.withStringValue(v, resolvedVersion)));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,35 +141,38 @@ public J visitMethodInvocation(J.MethodInvocation method, P p) {

return maybeGradlePlugin(cursor, null, null, null, true);
} else if (APPLY_DSL_MATCHER.matches(m, true)) {
if (!(m.getArguments().get(0) instanceof J.Literal) || !(m.getSelect() instanceof J.MethodInvocation)) {
Expression applyArg = m.getArguments().get(0).unwrap();
if (!(applyArg instanceof J.Literal) || !(m.getSelect() instanceof J.MethodInvocation)) {
return null;
}

J.MethodInvocation versionSelect = (J.MethodInvocation) m.getSelect();
Expression versionArg = versionSelect.getArguments().get(0).unwrap();
if (!PLUGIN_VERSION_DSL_MATCHER.matches(versionSelect, true) ||
!(versionSelect.getArguments().get(0) instanceof J.Literal) ||
!(versionArg instanceof J.Literal) ||
!(versionSelect.getSelect() instanceof J.MethodInvocation)) {
return null;
}

J.MethodInvocation idSelect = (J.MethodInvocation) versionSelect.getSelect();
Expression idArg = idSelect.getArguments().get(0).unwrap();
if (!(PLUGIN_ID_DSL_MATCHER.matches(idSelect, true) || KOTLIN_PLUGIN_DSL_MATCHER.matches(idSelect, true)) ||
!(idSelect.getArguments().get(0) instanceof J.Literal)) {
!(idArg instanceof J.Literal)) {
return null;
}

J.Literal idLiteral = (J.Literal) idSelect.getArguments().get(0);
J.Literal versionLiteral = (J.Literal) versionSelect.getArguments().get(0);
J.Literal applyLiteral = (J.Literal) m.getArguments().get(0);
J.Literal idLiteral = (J.Literal) idArg;
J.Literal versionLiteral = (J.Literal) versionArg;
J.Literal applyLiteral = (J.Literal) applyArg;
String pluginId = "kotlin".equals(idSelect.getSimpleName()) ? "org.jetbrains.kotlin." + idLiteral.getValue() : (String) idLiteral.getValue();
String version = (String) versionLiteral.getValue();
boolean applied = Boolean.TRUE.equals(applyLiteral.getValue());
return maybeGradlePlugin(cursor, pluginId, null, version, applied);
} else if (PLUGIN_VERSION_DSL_MATCHER.matches(m, true)) {
String version = null;
if (m.getArguments().get(0) instanceof J.Literal) {
J.Literal versionLiteral = (J.Literal) m.getArguments().get(0);
version = (String) versionLiteral.getValue();
Expression versionArg = m.getArguments().get(0).unwrap();
if (versionArg instanceof J.Literal) {
version = (String) ((J.Literal) versionArg).getValue();
}

if (!(m.getSelect() instanceof J.MethodInvocation &&
Expand All @@ -178,19 +181,21 @@ public J visitMethodInvocation(J.MethodInvocation method, P p) {
}

J.MethodInvocation select = (J.MethodInvocation) m.getSelect();
if (!(select.getArguments().get(0) instanceof J.Literal)) {
Expression idArg = select.getArguments().get(0).unwrap();
if (!(idArg instanceof J.Literal)) {
return null;
}

J.Literal idLiteral = (J.Literal) select.getArguments().get(0);
J.Literal idLiteral = (J.Literal) idArg;
String pluginId = "kotlin".equals(select.getSimpleName()) ? "org.jetbrains.kotlin." + idLiteral.getValue() : (String) idLiteral.getValue();
return maybeGradlePlugin(cursor, pluginId, null, version, !withinBlock(cursor, "pluginManagement"));
} else if (PLUGIN_ID_DSL_MATCHER.matches(m, true) || KOTLIN_PLUGIN_DSL_MATCHER.matches(m, true)) {
if (!(m.getArguments().get(0) instanceof J.Literal)) {
Expression arg = m.getArguments().get(0).unwrap();
if (!(arg instanceof J.Literal)) {
return null;
}

J.Literal literal = (J.Literal) m.getArguments().get(0);
J.Literal literal = (J.Literal) arg;
String pluginId = "kotlin".equals(m.getSimpleName()) ? "org.jetbrains.kotlin." + literal.getValue() : (String) literal.getValue();
return maybeGradlePlugin(cursor, pluginId, null, null, !withinBlock(cursor, "pluginManagement"));
}
Expand Down Expand Up @@ -240,12 +245,15 @@ public J visitMethodInvocation(J.MethodInvocation method, P p) {

private boolean withinPlugins(Cursor cursor) {
Cursor parent = cursor.dropParentUntil(value -> value instanceof J.MethodInvocation || value == Cursor.ROOT_VALUE);
if (parent.isRoot() || !"plugins".equals(((J.MethodInvocation) parent.getValue()).getSimpleName())) {
return false;
while (!parent.isRoot()) {
J.MethodInvocation parentMethod = parent.getValue();
if ("plugins".equals(parentMethod.getSimpleName())) {
parent = parent.dropParentUntil(value -> value instanceof J.MethodInvocation || value == Cursor.ROOT_VALUE);
return parent.isRoot() || "pluginManagement".equals(((J.MethodInvocation) parent.getValue()).getSimpleName());
}
parent = parent.dropParentUntil(value -> value instanceof J.MethodInvocation || value == Cursor.ROOT_VALUE);
}

parent = parent.dropParentUntil(value -> value instanceof J.MethodInvocation || value == Cursor.ROOT_VALUE);
return parent.isRoot() || "pluginManagement".equals(((J.MethodInvocation) parent.getValue()).getSimpleName());
return false;
}

private boolean isProjectReceiver(Cursor cursor) {
Expand Down
Loading