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

Adding gradle wrapper through distribution is now possible #4491

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -111,6 +111,9 @@ public String getDescription() {
@Override
public Validated<Object> validate() {
Validated<Object> validated = super.validate();
if (wrapperUri != null && (version != null || distribution != null)) {
return Validated.invalid("wrapperUri", wrapperUri, "WrapperUri cannot be used with other parameters");
Jenson3210 marked this conversation as resolved.
Show resolved Hide resolved
}
if (version != null) {
validated = validated.and(Semver.validate(version, null));
}
Expand All @@ -123,37 +126,21 @@ public Validated<Object> validate() {

private GradleWrapper getGradleWrapper(ExecutionContext ctx) {
if (gradleWrapper == null) {
if (wrapperUri != null) {
return gradleWrapper = GradleWrapper.create(URI.create(wrapperUri), ctx);
}
try {
gradleWrapper = GradleWrapper.create(distribution, version, null, ctx);
} catch (Exception e) {
// 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) {
// 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) {
throw new IllegalArgumentException(
"wrapperUri contains a ${version} interpolation specifier but no version parameter was specified.", e);
}
if (!version.matches("[0-9.]+")) {
throw new IllegalArgumentException(
"Version selectors like \"" + version + "\" are unavailable when services.gradle.org cannot be reached. " +
"Specify an exact, literal version number.", e);
}
// services.gradle.org is unreachable
// 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));
}
String effectiveWrapperUri = wrapperUri
.replace("${version}", version == null ? "" : version)
.replace("${distribution}", distribution == null ? "bin" : distribution);
gradleWrapper = GradleWrapper.create(URI.create(effectiveWrapperUri), ctx);
throw new IllegalArgumentException(
"Could not reach services.gradle.org. " +
"To use this recipe in environments where services.gradle.org is unavailable specify a wrapperUri or exact version.", e);
}
}
return gradleWrapper;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -614,12 +614,67 @@ void preferExistingDistributionSourceWhenServicesGradleOrgUnavailable() {
);
}

@Test
void addWrapperWithCustomDistributionUri() {
HttpSender customDistributionHost = request -> {
if (request.getUrl().toString().contains("company.com")) {
return new HttpSender.Response(200, UpdateGradleWrapperTest.class.getClassLoader().getResourceAsStream("gradle-8.10-bin.zip"), () -> {});
}
return new HttpUrlConnectionSender().send(request);
};
HttpSenderExecutionContextView ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
.setHttpSender(customDistributionHost)
.setLargeFileHttpSender(customDistributionHost);
rewriteRun(
spec -> spec
.recipe(new UpdateGradleWrapper(null, null, null, "https://company.com/repo/gradle-8.0.2-bin.zip"))
.expectedCyclesThatMakeChanges(1)
.executionContext(ctx)
.afterRecipe(run -> {
assertThat(run.getChangeset().getAllResults()).hasSize(4);

var gradleSh = result(run, PlainText.class, "gradlew");
assertThat(gradleSh.getSourcePath()).isEqualTo(WRAPPER_SCRIPT_LOCATION);
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);

var gradleWrapperProperties = result(run, Properties.File.class, "gradle-wrapper.properties");
assertThat(gradleWrapperProperties.getSourcePath()).isEqualTo(WRAPPER_PROPERTIES_LOCATION);

var gradleWrapperJar = result(run, Remote.class, "gradle-wrapper.jar");
assertThat(gradleWrapperJar.getSourcePath()).isEqualTo(WRAPPER_JAR_LOCATION);
assertThat(gradleWrapperJar.getUri()).isEqualTo(URI.create("https://company.com/repo/gradle-8.0.2-bin.zip"));
assertThat(isValidWrapperJar(gradleWrapperJar)).as("Wrapper jar is not valid").isTrue();
}),
buildGradle(
"""
plugins {
id "java"
}
"""
)
);
}

@Test
void customDistributionUri() {
HttpSender customDistributionHost = request -> {
if (request.getUrl().toString().contains("company.com")) {
return new HttpSender.Response(200, UpdateGradleWrapperTest.class.getClassLoader().getResourceAsStream("gradle-8.10-bin.zip"), () -> {});
}
return new HttpUrlConnectionSender().send(request);
};
HttpSenderExecutionContextView ctx = HttpSenderExecutionContextView.view(new InMemoryExecutionContext())
.setHttpSender(customDistributionHost)
.setLargeFileHttpSender(customDistributionHost);
rewriteRun(
spec -> spec.recipe(new UpdateGradleWrapper("8.0.x", null, null, "https://company.com/repo/gradle-${version}-${distribution}.zip"))
.expectedCyclesThatMakeChanges(2)
.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4"))),
spec -> spec.recipe(new UpdateGradleWrapper(null, null, null, "https://company.com/repo/gradle-8.10-bin.zip"))
.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4")))
.executionContext(ctx),
properties(
"""
distributionBase=GRADLE_USER_HOME
Expand All @@ -628,23 +683,14 @@ void customDistributionUri() {
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
""",
"""
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\\://company.com/repo/gradle-8.10-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
""",
spec -> spec.path("gradle/wrapper/gradle-wrapper.properties")
.after(after -> {
Matcher checksumMatcher = Pattern.compile("distributionSha256Sum=(.*)").matcher(after);
assertThat(checksumMatcher.find()).isTrue();
String checksum = checksumMatcher.group(1);
assertThat(checksum).isNotBlank();

// language=properties
return """
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\\://company.com/repo/gradle-8.0.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionSha256Sum=%s
""".formatted(checksum);
})
),
gradlew,
gradlewBat,
Expand All @@ -664,7 +710,7 @@ void servicesGradleOrgUnavailable() {
.setHttpSender(unhelpfulSender)
.setLargeFileHttpSender(unhelpfulSender);
rewriteRun(
spec -> spec.recipe(new UpdateGradleWrapper("8.6", null, null, "https://artifactory.moderne.ninja/artifactory/gradle-distributions/gradle-${version}-bin.zip"))
Jenson3210 marked this conversation as resolved.
Show resolved Hide resolved
spec -> spec.recipe(new UpdateGradleWrapper("8.6", null, null, null))
.allSources(source -> source.markers(new BuildTool(Tree.randomId(), BuildTool.Type.Gradle, "7.4")))
.executionContext(ctx),
properties(
Expand All @@ -678,7 +724,7 @@ void servicesGradleOrgUnavailable() {
"""
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\\://artifactory.moderne.ninja/artifactory/gradle-distributions/gradle-8.6-bin.zip
distributionUrl=https\\://services.gradle.org/distributions/gradle-8.6-bin.zip
timtebeek marked this conversation as resolved.
Show resolved Hide resolved
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
""",
Expand Down Expand Up @@ -743,6 +789,11 @@ void updateWrapperInSubDirectory() {
);
}

@Test
void failRecipeIfBothVersionAndDistributionUriAreProvided() {
assertThat(new UpdateGradleWrapper("7.4.2", "bin", false, "https://company.com/repo/gradle-7.4.2-bin.zip").validate().isInvalid()).isTrue();
}

private <S extends SourceFile> S result(RecipeRun run, Class<S> clazz, String endsWith) {
return run.getChangeset().getAllResults().stream()
.map(Result::getAfter)
Expand Down
Loading