Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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
4 changes: 4 additions & 0 deletions rewrite-core/src/main/java/org/openrewrite/Cursor.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@
*/
package org.openrewrite;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.With;
import org.jspecify.annotations.Nullable;

import java.util.*;
Expand All @@ -30,12 +32,14 @@
* A cursor is linked path of LST elements that can be used to traverse down the tree towards the root.
*/
@EqualsAndHashCode(exclude = "messages")
@AllArgsConstructor
public class Cursor {
public static final String ROOT_VALUE = "root";

@Nullable
private final Cursor parent;

@With
private final Object value;

@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -391,15 +391,13 @@ public static String repeat(String s, int count) {
* which properly interprets '*' and '**' wildcards for file paths.
*
* @param str the input string to match against the pattern, can be null
* @param pattern the glob pattern to evaluate, can be null
* @param pattern the glob pattern to evaluate. null and "*" both match everything.
* @return true if the input string matches the glob pattern, false otherwise
* @see org.openrewrite.PathUtils#matchesGlob(Path, String)
*/
public static boolean matchesGlob(@Nullable String str, @Nullable String pattern) {
if ("*".equals(pattern)) {
if ("*".equals(pattern) || pattern == null) {
return true;
} else if (pattern == null) {
return false;
}

if (str == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,33 +15,26 @@
*/
package org.openrewrite.semver;

import lombok.Getter;
import lombok.With;
import org.jspecify.annotations.Nullable;
import org.openrewrite.Validated;
import org.openrewrite.internal.StringUtils;

import java.util.Collection;
import java.util.Optional;

@With
@Getter
public class DependencyMatcher {

public static final String STANDARD_OPTION_DESCRIPTION =
"Dependency patterns are a concise way of describing which dependencies are applicable to a recipe. " +
"Valid dependency patterns take one of these forms:\n\n" +
"* groupId:artifactId\n" +
"* groupId:artifactId:versionSelector\n" +
"* groupId:artifactId:versionSelector/versionPattern\n\n" +
"\"groupId\" and \"artifactId\" accept glob patterns.\n" +
"\"versionSelector\" accepts both literal version numbers and semver selectors.\n" +
"\"versionPattern\" is used for artifacts that encode variant/platform information in their version." +
"Guava is a common example of such a library. Guava appends \"-jre\" or \"-android\" to its version to indicate platform compatibility.";

private final String groupPattern;
private final String artifactPattern;
private final @Nullable String groupPattern;
private final @Nullable String artifactPattern;

@Nullable
private final VersionComparator versionComparator;

public DependencyMatcher(String groupPattern, String artifactPattern, @Nullable VersionComparator versionComparator) {
public DependencyMatcher(@Nullable String groupPattern, @Nullable String artifactPattern, @Nullable VersionComparator versionComparator) {
this.groupPattern = groupPattern;
this.artifactPattern = artifactPattern;
this.versionComparator = versionComparator;
Expand Down Expand Up @@ -74,13 +67,13 @@ public static Validated<DependencyMatcher> build(String pattern) {
return Validated.valid("pattern", new DependencyMatcher(patternPieces[0], patternPieces[1], validatedVersion.getValue()));
}

public boolean matches(@Nullable String groupId, String artifactId, String version) {
public boolean matches(@Nullable String groupId, @Nullable String artifactId, String version) {
return StringUtils.matchesGlob(groupId, groupPattern) &&
StringUtils.matchesGlob(artifactId, artifactPattern) &&
(versionComparator == null || versionComparator.isValid(null, version));
}

public boolean matches(@Nullable String groupId, String artifactId) {
public boolean matches(@Nullable String groupId, @Nullable String artifactId) {
return StringUtils.matchesGlob(groupId, groupPattern) && StringUtils.matchesGlob(artifactId, artifactPattern);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ void occurrenceCount() {
@Test
void globMatching() {
// exact matches
assertThat(matchesGlob("test", null)).isFalse();
assertThat(matchesGlob("test", null)).isTrue();
assertThat(matchesGlob("test", "")).isFalse();
assertThat(matchesGlob("", "")).isTrue();
assertThat(matchesGlob("test", "test")).isTrue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@
import org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.gradle.internal.ChangeStringLiteral;
import org.openrewrite.gradle.internal.Dependency;
import org.openrewrite.gradle.internal.DependencyStringNotationConverter;
import org.openrewrite.maven.tree.Dependency;
import org.openrewrite.gradle.marker.GradleDependencyConfiguration;
import org.openrewrite.gradle.marker.GradleProject;
import org.openrewrite.gradle.search.FindGradleProject;
Expand Down Expand Up @@ -176,6 +175,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
return Preconditions.check(new FindGradleProject(FindGradleProject.SearchCriteria.Marker).getVisitor(), new JavaIsoVisitor<ExecutionContext>() {
final DependencyMatcher depMatcher = requireNonNull(DependencyMatcher.build(oldGroupId + ":" + oldArtifactId).getValue());

@SuppressWarnings("NotNullFieldNotInitialized")
GradleProject gradleProject;

@Override
Expand All @@ -195,7 +195,7 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) {
gradleProject = maybeGp.get();

sourceFile = (JavaSourceFile) super.visit(sourceFile, ctx);
if (sourceFile != tree) {
if (sourceFile != null && sourceFile != tree) {
sourceFile = sourceFile.withMarkers(sourceFile.getMarkers().setByType(updateGradleModel(gradleProject)));
if (changeManagedDependency == null || changeManagedDependency) {
doAfterVisit(new ChangeManagedDependency(oldGroupId, oldArtifactId, newGroupId, newArtifactId, newVersion, versionPattern).getVisitor());
Expand Down Expand Up @@ -236,10 +236,10 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
if (depArgs.get(0) instanceof J.Literal) {
String gav = (String) ((J.Literal) depArgs.get(0)).getValue();
if (gav != null) {
Dependency original = DependencyStringNotationConverter.parse(gav);
Dependency original = Dependency.parse(gav);
if (original != null) {
Dependency updated = original;
if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) {
if (!StringUtils.isBlank(newGroupId) && !Objects.equals(updated.getGroupId(), newGroupId)) {
updated = updated.withGroupId(newGroupId);
}
if (!StringUtils.isBlank(newArtifactId) && !updated.getArtifactId().equals(newArtifactId)) {
Expand Down Expand Up @@ -270,10 +270,10 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
((J.Literal) strings.get(0)).getValue() != null) {

J.Literal literal = (J.Literal) strings.get(0);
Dependency original = DependencyStringNotationConverter.parse((String) requireNonNull(literal.getValue()));
Dependency original = Dependency.parse((String) requireNonNull(literal.getValue()));
if (original != null) {
Dependency updated = original;
if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) {
if (!StringUtils.isBlank(newGroupId) && !Objects.equals(updated.getGroupId(), newGroupId)) {
updated = updated.withGroupId(newGroupId);
}
if (!StringUtils.isBlank(newArtifactId) && !updated.getArtifactId().equals(newArtifactId)) {
Expand Down Expand Up @@ -563,10 +563,10 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
((J.Literal) strings.get(0)).getValue() != null) {

J.Literal literal = (J.Literal) strings.get(0);
Dependency original = DependencyStringNotationConverter.parse((String) requireNonNull(literal.getValue()));
Dependency original = Dependency.parse((String) requireNonNull(literal.getValue()));
if (original != null) {
Dependency updated = original;
if (!StringUtils.isBlank(newGroupId) && !updated.getGroupId().equals(newGroupId)) {
if (!StringUtils.isBlank(newGroupId) && !Objects.equals(updated.getGroupId(), newGroupId)) {
updated = updated.withGroupId(newGroupId);
}
if (!StringUtils.isBlank(newArtifactId) && !updated.getArtifactId().equals(newArtifactId)) {
Expand Down Expand Up @@ -604,7 +604,6 @@ private GradleProject updateGradleModel(GradleProject gp) {
for (GradleDependencyConfiguration gdc : nameToConfiguration.values()) {
GradleDependencyConfiguration newGdc = gdc;
newGdc = newGdc.withRequested(ListUtils.map(gdc.getRequested(), requested -> {
assert requested != null;
if (depMatcher.matches(requested.getGroupId(), requested.getArtifactId())) {
requested = updatedRequested.computeIfAbsent(requested, r -> {
GroupArtifactVersion gav = r.getGav();
Expand Down
Loading