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

Custom distributionUrl in gradle properties should be upgraded in place #4445

Merged
merged 19 commits into from
Aug 29, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.gradle.search.FindGradleProject;
import org.openrewrite.gradle.util.DistributionInfos;
import org.openrewrite.gradle.util.GradleWrapper;
import org.openrewrite.internal.ListUtils;
import org.openrewrite.internal.StringUtils;
Expand All @@ -35,6 +36,7 @@
import org.openrewrite.properties.tree.Properties;
import org.openrewrite.quark.Quark;
import org.openrewrite.remote.Remote;
import org.openrewrite.semver.ExactVersion;
import org.openrewrite.semver.Semver;
import org.openrewrite.semver.VersionComparator;
import org.openrewrite.text.PlainText;
Expand Down Expand Up @@ -127,9 +129,15 @@ private GradleWrapper getGradleWrapper(ExecutionContext ctx) {
// services.gradle.org is unreachable, possibly because of a firewall
// But if the user specified a wrapperUri to an internal repository things might still be workable
if (wrapperUri == null) {
throw new IllegalArgumentException(
"Could not reach services.gradle.org and no alternative wrapper URI is provided. " +
"To use this recipe in environments where services.gradle.org is unavailable specify a wrapperUri.", e);
// If the user didn't specify a wrapperUri, but they did provide a specific version we assume they know this version
// is available from whichever distribution url they were previously using and update the version
if (!StringUtils.isBlank(version) && Semver.validate(version, null).getValue() instanceof ExactVersion) {
return gradleWrapper = new GradleWrapper(version, new DistributionInfos("", null, null));
} else {
throw new IllegalArgumentException(
"Could not reach services.gradle.org, no alternative wrapper URI is provided and no exact version is provided. " +
"To use this recipe in environments where services.gradle.org is unavailable specify a wrapperUri or exact version.", e);
}
}
if (wrapperUri.contains("${version})")) {
if (version == null) {
Expand All @@ -154,7 +162,10 @@ private GradleWrapper getGradleWrapper(ExecutionContext ctx) {
public static class GradleWrapperState {
boolean gradleProject = false;
boolean needsWrapperUpdate = false;

@Nullable
BuildTool updatedMarker;

boolean addGradleWrapperProperties = true;
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
boolean addGradleWrapperJar = true;
boolean addGradleShellScript = true;
Expand Down Expand Up @@ -191,14 +202,14 @@ public boolean isAcceptable(SourceFile sourceFile, ExecutionContext ctx) {
return false;
}

GradleWrapper gradleWrapper = getGradleWrapper(ctx);
String gradleWrapperVersion = getGradleWrapper(ctx).getVersion();

VersionComparator versionComparator = requireNonNull(Semver.validate(isBlank(version) ? "latest.release" : version, null).getValue());
int compare = versionComparator.compare(null, buildTool.getVersion(), gradleWrapper.getVersion());
int compare = versionComparator.compare(null, buildTool.getVersion(), gradleWrapperVersion);
// maybe we want to update the distribution type or url
if (compare < 0) {
acc.needsWrapperUpdate = true;
acc.updatedMarker = buildTool.withVersion(gradleWrapper.getVersion());
acc.updatedMarker = buildTool.withVersion(gradleWrapperVersion);
return true;
} else {
return compare == 0;
Expand All @@ -211,10 +222,17 @@ public Properties visitEntry(Properties.Entry entry, ExecutionContext ctx) {
return entry;
}

GradleWrapper gradleWrapper = getGradleWrapper(ctx);

// Typical example: https://services.gradle.org/distributions/gradle-7.4-all.zip
String currentDistributionUrl = entry.getValue().getText();

GradleWrapper gradleWrpr = getGradleWrapper(ctx);
if (StringUtils.isBlank(gradleWrpr.getDistributionUrl()) &&
!StringUtils.isBlank(version) && Semver.validate(version, null).getValue() instanceof ExactVersion) {
String newDownloadUrl = currentDistributionUrl.replace("\\", "")
.replaceAll("(.*gradle-)(\\d+\\.\\d+(?:\\.\\d+)?)(.*-(?:bin|all).zip)", "$1" + gradleWrapper.getVersion() + "$3");
gradleWrapper = new GradleWrapper(version, new DistributionInfos(newDownloadUrl, null, null));
}

if (!gradleWrapper.getPropertiesFormattedUrl().equals(currentDistributionUrl)) {
acc.needsWrapperUpdate = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ public static GradleWrapper create(@Nullable String distributionTypeName, @Nulla
public static GradleWrapper create(URI fullDistributionUri, @SuppressWarnings("unused") ExecutionContext ctx) {
String version = "";
Matcher matcher = GRADLE_VERSION_PATTERN.matcher(fullDistributionUri.toString());
if(matcher.find()) {
if (matcher.find()) {
version = matcher.group(1);
}
return new GradleWrapper(version, new DistributionInfos(fullDistributionUri.toString(), null, null));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,9 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.gradle.Assertions.buildGradle;
import static org.openrewrite.gradle.toolingapi.Assertions.withToolingApi;
import static org.openrewrite.gradle.util.GradleWrapper.WRAPPER_BATCH_LOCATION;
import static org.openrewrite.gradle.util.GradleWrapper.WRAPPER_JAR_LOCATION;
import static org.openrewrite.gradle.util.GradleWrapper.WRAPPER_PROPERTIES_LOCATION;
import static org.openrewrite.gradle.util.GradleWrapper.WRAPPER_SCRIPT_LOCATION;
import static org.openrewrite.gradle.util.GradleWrapper.*;
import static org.openrewrite.properties.Assertions.properties;
import static org.openrewrite.test.SourceSpecs.dir;
import static org.openrewrite.test.SourceSpecs.other;
import static org.openrewrite.test.SourceSpecs.text;
import static org.openrewrite.test.SourceSpecs.*;

@SuppressWarnings("UnusedProperty")
class UpdateGradleWrapperTest implements RewriteTest {
Expand Down Expand Up @@ -115,22 +110,22 @@ void updateWrapper() {
rewriteRun(
spec -> spec.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4")))
.afterRecipe(run -> {
var gradleSh = result(run, PlainText.class, "gradlew");
assertThat(gradleSh.getSourcePath()).isEqualTo(WRAPPER_SCRIPT_LOCATION);
assertThat(gradleSh.getText()).isEqualTo(GRADLEW_TEXT);
assertThat(gradleSh.getFileAttributes()).isNotNull();
assertThat(gradleSh.getFileAttributes().isReadable()).isTrue();
assertThat(gradleSh.getFileAttributes().isExecutable()).isTrue();
var gradleSh = result(run, PlainText.class, "gradlew");
assertThat(gradleSh.getSourcePath()).isEqualTo(WRAPPER_SCRIPT_LOCATION);
assertThat(gradleSh.getText()).isEqualTo(GRADLEW_TEXT);
assertThat(gradleSh.getFileAttributes()).isNotNull();
assertThat(gradleSh.getFileAttributes().isReadable()).isTrue();
assertThat(gradleSh.getFileAttributes().isExecutable()).isTrue();

var gradleBat = result(run, PlainText.class, "gradlew.bat");
assertThat(gradleBat.getSourcePath()).isEqualTo(WRAPPER_BATCH_LOCATION);
assertThat(gradleBat.getText()).isEqualTo(GRADLEW_BAT_TEXT);
var gradleBat = result(run, PlainText.class, "gradlew.bat");
assertThat(gradleBat.getSourcePath()).isEqualTo(WRAPPER_BATCH_LOCATION);
assertThat(gradleBat.getText()).isEqualTo(GRADLEW_BAT_TEXT);

var gradleWrapperJar = result(run, Remote.class, "gradle-wrapper.jar");
assertThat(gradleWrapperJar.getSourcePath()).isEqualTo(WRAPPER_JAR_LOCATION);
assertThat(gradleWrapperJar.getUri()).isEqualTo(URI.create("https://services.gradle.org/distributions/gradle-7.4.2-bin.zip"));
assertThat(isValidWrapperJar(gradleWrapperJar)).as("Wrapper jar is not valid").isTrue();
}),
var gradleWrapperJar = result(run, Remote.class, "gradle-wrapper.jar");
assertThat(gradleWrapperJar.getSourcePath()).isEqualTo(WRAPPER_JAR_LOCATION);
assertThat(gradleWrapperJar.getUri()).isEqualTo(URI.create("https://services.gradle.org/distributions/gradle-7.4.2-bin.zip"));
assertThat(isValidWrapperJar(gradleWrapperJar)).as("Wrapper jar is not valid").isTrue();
}),
properties(
"""
distributionBase=GRADLE_USER_HOME
Expand Down Expand Up @@ -165,17 +160,17 @@ void updateVersionAndDistribution() {
rewriteRun(
spec -> spec.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4")))
.afterRecipe(run -> {
var gradleSh = result(run, PlainText.class, "gradlew");
assertThat(gradleSh.getText()).isNotBlank();
var gradleSh = result(run, PlainText.class, "gradlew");
assertThat(gradleSh.getText()).isNotBlank();

var gradleBat = result(run, PlainText.class, "gradlew.bat");
assertThat(gradleBat.getText()).isNotBlank();
var gradleBat = result(run, PlainText.class, "gradlew.bat");
assertThat(gradleBat.getText()).isNotBlank();

var gradleWrapperJar = result(run, Remote.class, "gradle-wrapper.jar");
assertThat(PathUtils.equalIgnoringSeparators(gradleWrapperJar.getSourcePath(), WRAPPER_JAR_LOCATION)).isTrue();
assertThat(gradleWrapperJar.getUri()).isEqualTo(URI.create("https://services.gradle.org/distributions/gradle-7.4.2-bin.zip"));
assertThat(isValidWrapperJar(gradleWrapperJar)).as("Wrapper jar is not valid").isTrue();
}),
var gradleWrapperJar = result(run, Remote.class, "gradle-wrapper.jar");
assertThat(PathUtils.equalIgnoringSeparators(gradleWrapperJar.getSourcePath(), WRAPPER_JAR_LOCATION)).isTrue();
assertThat(gradleWrapperJar.getUri()).isEqualTo(URI.create("https://services.gradle.org/distributions/gradle-7.4.2-bin.zip"));
assertThat(isValidWrapperJar(gradleWrapperJar)).as("Wrapper jar is not valid").isTrue();
}),
properties(
"""
distributionBase=GRADLE_USER_HOME
Expand Down Expand Up @@ -471,19 +466,19 @@ void defaultsToLatestRelease() {
void skipWorkIfUpdatedEarlier() {
rewriteRun(
spec -> spec.recipeFromYaml(
"""
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.gradle.MultipleWrapperUpdates
displayName: Multiple wrapper updates
description: Multiple wrapper updates.
recipeList:
- org.openrewrite.gradle.UpdateGradleWrapper:
version: 7.6.3
addIfMissing: false
- org.openrewrite.gradle.UpdateGradleWrapper:
version: 6.9.4
addIfMissing: false
""",
"""
type: specs.openrewrite.org/v1beta/recipe
name: org.openrewrite.gradle.MultipleWrapperUpdates
displayName: Multiple wrapper updates
description: Multiple wrapper updates.
recipeList:
- org.openrewrite.gradle.UpdateGradleWrapper:
version: 7.6.3
addIfMissing: false
- org.openrewrite.gradle.UpdateGradleWrapper:
version: 6.9.4
addIfMissing: false
""",
"org.openrewrite.gradle.MultipleWrapperUpdates")
.cycles(1)
.expectedCyclesThatMakeChanges(1)
Expand Down Expand Up @@ -571,6 +566,49 @@ void preferExistingDistributionSource() {
);
}

@Test
void preferExistingDistributionSourceWhenServicesGradleOrgUnavailable() {
HttpSender unhelpfulSender = request -> {
if (request.getUrl().toString().contains("services.gradle.org")) {
throw new RuntimeException("I'm sorry Dave, I'm afraid I can't do that.");
}
if (request.getUrl().toString().contains("company.com/repo")) {
InputStream zipInputStream = UpdateGradleWrapperTest.class.getClassLoader().getResourceAsStream("gradle-8.10-bin.zip");
return new HttpSender.Response(200, zipInputStream, () -> {
});
}
return new HttpUrlConnectionSender().send(request);
};
HttpSenderExecutionContextView ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
.setHttpSender(unhelpfulSender)
.setLargeFileHttpSender(unhelpfulSender);
rewriteRun(
spec -> spec.recipe(new UpdateGradleWrapper("8.10", "bin", false, null))
.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4")))
.executionContext(ctx),
properties(
"""
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\\://company.com/repo/gradle-8.8-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
""",
spec -> spec.path("gradle/wrapper/gradle-wrapper.properties")
.after(after -> {
Matcher distUrlMatcher = Pattern.compile("distributionUrl=(.*/gradle-(.*)-bin.zip)").matcher(after);
assertThat(distUrlMatcher.find()).as(after).isTrue();
assertThat(distUrlMatcher.group(1)).startsWith("https\\://company.com/repo");
assertThat(distUrlMatcher.group(2)).isEqualTo("8.10");
return after;
})
),
gradlew,
gradlewBat,
gradleWrapperJarQuark
);
}

@Test
void customDistributionUri() {
rewriteRun(
Expand Down Expand Up @@ -612,7 +650,7 @@ void customDistributionUri() {
@Test
void servicesGradleOrgUnavailable() {
HttpSender unhelpfulSender = request -> {
if(request.getUrl().toString().contains("services.gradle.org")) {
if (request.getUrl().toString().contains("services.gradle.org")) {
throw new RuntimeException("I'm sorry Dave, I'm afraid I can't do that.");
}
return new HttpUrlConnectionSender().send(request);
Expand Down
Binary file not shown.
Loading