Skip to content

Commit

Permalink
Polish version descriptions across the board. Set newVersion to `late…
Browse files Browse the repository at this point in the history
…st.release` where ever it makes sense
  • Loading branch information
shanman190 committed Jul 19, 2023
1 parent f343ab2 commit 76b321b
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 151 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,10 @@ public class AddDependency extends ScanningRecipe<AddDependency.Scanned> {
String artifactId;

@Option(displayName = "Version",
description = "An exact version number or node-style semver selector used to select the version number.",
description = "An exact version number or node-style semver selector used to select the version number. " +
"You can also use `latest.release` for the latest available version and `latest.patch` if " +
"the current version is a valid semantic version. For more details, you can look at the documentation " +
"page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors).",
example = "29.X",
required = false)
@Nullable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import lombok.RequiredArgsConstructor;
import org.openrewrite.Cursor;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Validated;
import org.openrewrite.gradle.internal.InsertDependencyComparator;
import org.openrewrite.gradle.marker.GradleDependencyConfiguration;
import org.openrewrite.gradle.marker.GradleProject;
Expand All @@ -36,18 +35,14 @@
import org.openrewrite.maven.internal.MavenPomDownloader;
import org.openrewrite.maven.table.MavenMetadataFailures;
import org.openrewrite.maven.tree.*;
import org.openrewrite.semver.ExactVersion;
import org.openrewrite.semver.LatestPatch;
import org.openrewrite.semver.Semver;
import org.openrewrite.semver.VersionComparator;
import org.openrewrite.semver.*;

import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Collections.*;
import static java.util.Objects.requireNonNull;

@RequiredArgsConstructor
Expand All @@ -57,12 +52,13 @@ public class AddDependencyVisitor extends GroovyIsoVisitor<ExecutionContext> {

private final String groupId;
private final String artifactId;

@Nullable
private final String version;

@Nullable
private final String versionPattern;

@Nullable
private final String configuration;

@Nullable
Expand All @@ -77,9 +73,6 @@ public class AddDependencyVisitor extends GroovyIsoVisitor<ExecutionContext> {
@Nullable
private final MavenMetadataFailures metadataFailures;

@Nullable
private VersionComparator versionComparator;

@Nullable
private String resolvedVersion;

Expand Down Expand Up @@ -117,13 +110,6 @@ public G.CompilationUnit visitCompilationUnit(G.CompilationUnit cu, ExecutionCon
dependenciesInvocation.withPrefix(Space.format("\n\n"))));
}

if (version != null) {
Validated<VersionComparator> versionValidated = Semver.validate(version, versionPattern);
if (versionValidated.isValid()) {
versionComparator = versionValidated.getValue();
}
}

g = (G.CompilationUnit) new InsertDependencyInOrder(configuration, gp)
.visitNonNull(g, ctx, requireNonNull(getCursor().getParent()));

Expand Down Expand Up @@ -237,16 +223,15 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
return m;
}

String resolvedVersion = null;
if (versionComparator != null) {
if (version != null) {
try {
resolvedVersion = findNewerVersion(groupId, artifactId, gp, ctx);
resolvedVersion = resolveDependencyVersion(groupId, artifactId, "0", version, versionPattern, gp.getMavenRepositories(), metadataFailures, ctx)
.orElse(null);
} catch (MavenDownloadingException e) {
return e.warn(m);
}
}


J.Block body = (J.Block) dependenciesBlock.getBody();

String codeTemplate;
Expand Down Expand Up @@ -326,47 +311,10 @@ public J.MethodInvocation visitMethodInvocation(J.MethodInvocation method, Execu
statements.add(addDependencyInvocation);
}
body = body.withStatements(statements);
m = m.withArguments(Collections.singletonList(dependenciesBlock.withBody(body)));
m = m.withArguments(singletonList(dependenciesBlock.withBody(body)));

return m;
}

@Nullable
private String findNewerVersion(String groupId, String artifactId, GradleProject gradleProject,
ExecutionContext ctx) throws MavenDownloadingException {
if (resolvedVersion != null) {
return resolvedVersion;
}

if (versionComparator == null || versionComparator instanceof ExactVersion) {
resolvedVersion = version;
} else {
// in the case of "latest.patch", a new version can only be derived if the
// current version is a semantic version
if (versionComparator instanceof LatestPatch && !versionComparator.isValid(version, version)) {
return null;
}

try {
MavenMetadata mavenMetadata = metadataFailures == null ?
downloadMetadata(groupId, artifactId, gradleProject, ctx) :
metadataFailures.insertRows(ctx, () -> downloadMetadata(groupId, artifactId, gradleProject, ctx));
resolvedVersion = versionComparator.upgrade(version, mavenMetadata.getVersioning().getVersions())
.orElse(version);
} catch (IllegalStateException e) {
// this can happen when we encounter exotic versions
return null;
}
}

return resolvedVersion;
}

public MavenMetadata downloadMetadata(String groupId, String artifactId, GradleProject gradleProject, ExecutionContext ctx) throws MavenDownloadingException {
return new MavenPomDownloader(emptyMap(), ctx, null, null)
.downloadMetadata(new GroupArtifact(groupId, artifactId), null,
gradleProject.getMavenRepositories());
}
}

enum DependencyStyle {
Expand Down Expand Up @@ -396,4 +344,42 @@ private DependencyStyle autodetectDependencyStyle(List<Statement> statements) {

return string >= map ? DependencyStyle.String : DependencyStyle.Map;
}

public static Optional<String> resolveDependencyVersion(String groupId, String artifactId, String currentVersion, @Nullable String newVersion, @Nullable String versionPattern,
List<MavenRepository> repositories, @Nullable MavenMetadataFailures metadataFailures, ExecutionContext ctx) throws MavenDownloadingException {
VersionComparator versionComparator = StringUtils.isBlank(newVersion) ?
new LatestRelease(versionPattern) :
requireNonNull(Semver.validate(newVersion, versionPattern).getValue());

Optional<String> version;
if (versionComparator instanceof ExactVersion) {
version = Optional.of(newVersion);
} else if (versionComparator instanceof LatestPatch && !versionComparator.isValid(currentVersion, currentVersion)) {
// in the case of "latest.patch", a new version can only be derived if the
// current version is a semantic version
return Optional.empty();
} else {
version = findNewerVersion(groupId, artifactId, currentVersion, versionComparator, repositories, metadataFailures, ctx);
}
return version;
}

private static Optional<String> findNewerVersion(String groupId, String artifactId, String version, VersionComparator versionComparator,
List<MavenRepository> repositories, @Nullable MavenMetadataFailures metadataFailures, ExecutionContext ctx) throws MavenDownloadingException {
try {
MavenMetadata mavenMetadata = metadataFailures == null ?
downloadMetadata(groupId, artifactId, repositories, ctx) :
metadataFailures.insertRows(ctx, () -> downloadMetadata(groupId, artifactId, repositories, ctx));
return versionComparator.upgrade(version, mavenMetadata.getVersioning().getVersions());
} catch (IllegalStateException e) {
// this can happen when we encounter exotic versions
return Optional.empty();
}
}

private static MavenMetadata downloadMetadata(String groupId, String artifactId, List<MavenRepository> repositories, ExecutionContext ctx) throws MavenDownloadingException {
return new MavenPomDownloader(emptyMap(), ctx, null, null)
.downloadMetadata(new GroupArtifact(groupId, artifactId), null,
repositories);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,11 @@ public class UpgradeDependencyVersion extends Recipe {
description = "An exact version number or node-style semver selector used to select the version number. " +
"You can also use `latest.release` for the latest available version and `latest.patch` if " +
"the current version is a valid semantic version. For more details, you can look at the documentation " +
"page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors)",
example = "29.X")
"page of [version selectors](https://docs.openrewrite.org/reference/dependency-version-selectors). " +
"Defaults to `latest.release`.",
example = "29.X",
required = false)
@Nullable
String newVersion;

@Option(displayName = "Version pattern",
Expand All @@ -99,8 +102,8 @@ public String getDescription() {
}

@Override
public Validated validate() {
Validated validated = super.validate();
public Validated<Object> validate() {
Validated<Object> validated = super.validate();
if (newVersion != null) {
validated = validated.and(Semver.validate(newVersion, versionPattern));
}
Expand All @@ -110,8 +113,7 @@ public Validated validate() {
@Override
public TreeVisitor<?, ExecutionContext> getVisitor() {
MethodMatcher dependencyDsl = new MethodMatcher("DependencyHandlerSpec *(..)");
VersionComparator versionComparator = requireNonNull(Semver.validate(newVersion, versionPattern).getValue());
DependencyMatcher dependencyMatcher = new DependencyMatcher(groupId, artifactId, versionComparator);
DependencyMatcher dependencyMatcher = new DependencyMatcher(groupId, artifactId, null);
return Preconditions.check(new FindGradleProject(FindGradleProject.SearchCriteria.Marker), new GroovyVisitor<ExecutionContext>() {

@Override
Expand All @@ -126,7 +128,7 @@ public J postVisit(J tree, ExecutionContext ctx) {
return cu;
}

cu = (JavaSourceFile) new UpdateVariable(variableNames, versionComparator, maybeGp.get()).visitNonNull(cu, ctx);
cu = (JavaSourceFile) new UpdateVariable(variableNames, maybeGp.get()).visitNonNull(cu, ctx);
}
Set<GroupArtifactVersion> versionUpdates = getCursor().getMessage(NEW_VERSION_KEY);
if (versionUpdates != null) {
Expand Down Expand Up @@ -198,8 +200,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
String version = dep.getVersion();
try {
String newVersion = "classpath".equals(m.getSimpleName()) ?
findNewerPluginVersion(dep.getGroupId(), dep.getArtifactId(), version, versionComparator, gradleProject, ctx) :
findNewerProjectDependencyVersion(dep.getGroupId(), dep.getArtifactId(), version, versionComparator, gradleProject, ctx);
findNewerPluginVersion(dep.getGroupId(), dep.getArtifactId(), version, gradleProject, ctx) :
findNewerProjectDependencyVersion(dep.getGroupId(), dep.getArtifactId(), version, gradleProject, ctx);
if (newVersion == null || version.equals(newVersion)) {
return m;
}
Expand Down Expand Up @@ -249,8 +251,8 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
String newVersion;
try {
newVersion = "classpath".equals(m.getSimpleName()) ?
findNewerPluginVersion((String) groupLiteral.getValue(), (String) artifactLiteral.getValue(), version, versionComparator, gradleProject, ctx) :
findNewerProjectDependencyVersion((String) groupLiteral.getValue(), (String) artifactLiteral.getValue(), version, versionComparator, gradleProject, ctx);
findNewerPluginVersion((String) groupLiteral.getValue(), (String) artifactLiteral.getValue(), version, gradleProject, ctx) :
findNewerProjectDependencyVersion((String) groupLiteral.getValue(), (String) artifactLiteral.getValue(), version, gradleProject, ctx);
} catch (MavenDownloadingException e) {
return e.warn(m);
}
Expand Down Expand Up @@ -284,7 +286,6 @@ private J.MethodInvocation updateDependency(J.MethodInvocation m, ExecutionConte
@EqualsAndHashCode(callSuper = true)
private class UpdateVariable extends GroovyIsoVisitor<ExecutionContext> {
Map<String, GroupArtifact> versionVariableNames;
VersionComparator versionComparator;
GradleProject gradleProject;

@Override
Expand Down Expand Up @@ -315,9 +316,9 @@ public J.VariableDeclarations.NamedVariable visitVariable(J.VariableDeclarations
}

try {
String newVersion = findNewerProjectDependencyVersion(ga.getGroupId(), ga.getArtifactId(), version, versionComparator, gradleProject, ctx);
String newVersion = findNewerProjectDependencyVersion(ga.getGroupId(), ga.getArtifactId(), version, gradleProject, ctx);
if (newVersion == null) {
newVersion = findNewerPluginVersion(ga.getGroupId(), ga.getArtifactId(), version, versionComparator, gradleProject, ctx);
newVersion = findNewerPluginVersion(ga.getGroupId(), ga.getArtifactId(), version, gradleProject, ctx);
}
if (newVersion == null) {
return v;
Expand Down Expand Up @@ -366,9 +367,9 @@ public J.Assignment visitAssignment(J.Assignment assignment, ExecutionContext ct
}

try {
String newVersion = findNewerProjectDependencyVersion(ga.getGroupId(), ga.getArtifactId(), version, versionComparator, gradleProject, ctx);
String newVersion = findNewerProjectDependencyVersion(ga.getGroupId(), ga.getArtifactId(), version, gradleProject, ctx);
if (newVersion == null) {
newVersion = findNewerPluginVersion(ga.getGroupId(), ga.getArtifactId(), version, versionComparator, gradleProject, ctx);
newVersion = findNewerPluginVersion(ga.getGroupId(), ga.getArtifactId(), version, gradleProject, ctx);
}
if (newVersion == null) {
return a;
Expand All @@ -387,49 +388,17 @@ public J.Assignment visitAssignment(J.Assignment assignment, ExecutionContext ct
}

@Nullable
private String findNewerPluginVersion(String groupId, String artifactId, String version, VersionComparator versionComparator,
GradleProject gradleProject, ExecutionContext ctx) throws MavenDownloadingException {
return findNewerVersion(groupId, artifactId, version, versionComparator, gradleProject.getMavenPluginRepositories(), ctx);
}

@Nullable
private String findNewerProjectDependencyVersion(String groupId, String artifactId, String version, VersionComparator versionComparator,
GradleProject gradleProject, ExecutionContext ctx) throws MavenDownloadingException {
return findNewerVersion(groupId, artifactId, version, versionComparator, gradleProject.getMavenRepositories(), ctx);
private String findNewerPluginVersion(String groupId, String artifactId, String version, GradleProject gradleProject,
ExecutionContext ctx) throws MavenDownloadingException {
return AddDependencyVisitor.resolveDependencyVersion(groupId, artifactId, version, newVersion, versionPattern, gradleProject.getMavenPluginRepositories(), metadataFailures, ctx)
.orElse(null);
}

@Nullable
private String findNewerVersion(String groupId, String artifactId, String version, VersionComparator versionComparator,
List<MavenRepository> repositories, ExecutionContext ctx) throws MavenDownloadingException {
// in the case of "latest.patch", a new version can only be derived if the
// current version is a semantic version
if (versionComparator instanceof LatestPatch && !versionComparator.isValid(version, version)) {
return null;
}

if (versionComparator instanceof ExactVersion) {
return versionComparator.upgrade(version, Collections.singletonList(newVersion)).orElse(null);
}

try {
MavenMetadata mavenMetadata = metadataFailures.insertRows(ctx, () -> downloadMetadata(groupId, artifactId, repositories, ctx));
List<String> versions = new ArrayList<>();
for (String v : mavenMetadata.getVersioning().getVersions()) {
if (versionComparator.isValid(version, v)) {
versions.add(v);
}
}
return versionComparator.upgrade(version, versions).orElse(null);
} catch (IllegalStateException e) {
// this can happen when we encounter exotic versions
return null;
}
}

private MavenMetadata downloadMetadata(String groupId, String artifactId, List<MavenRepository> repositories, ExecutionContext ctx) throws MavenDownloadingException {
return new MavenPomDownloader(emptyMap(), ctx, null, null)
.downloadMetadata(new GroupArtifact(groupId, artifactId), null,
repositories);
private String findNewerProjectDependencyVersion(String groupId, String artifactId, String version, GradleProject gradleProject,
ExecutionContext ctx) throws MavenDownloadingException {
return AddDependencyVisitor.resolveDependencyVersion(groupId, artifactId, version, newVersion, versionPattern, gradleProject.getMavenRepositories(), metadataFailures, ctx)
.orElse(null);
}

static GradleProject replaceVersion(GradleProject gp, ExecutionContext ctx, GroupArtifactVersion gav) {
Expand Down
Loading

0 comments on commit 76b321b

Please sign in to comment.