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

Allow lazier configuration of jdks #19

Merged
merged 15 commits into from
May 12, 2022
Merged
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ version gitVersion()

allprojects {
repositories {
gradlePluginPortal()
mavenCentral() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
gradlePluginPortal() { metadataSources { mavenPom(); ignoreGradleMetadataRedirection() } }
}

group 'com.palantir.gradle.jdks'
Expand Down
5 changes: 5 additions & 0 deletions changelog/@unreleased/pr-19.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type: fix
fix:
description: Allow lazy configuration of JDKs
links:
- https://github.com/palantir/gradle-jdks/pull/19
2 changes: 2 additions & 0 deletions gradle-jdks/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ dependencies {
testImplementation 'com.netflix.nebula:nebula-test'
testImplementation 'org.junit.jupiter:junit-jupiter'
testImplementation 'org.assertj:assertj-core'
testImplementation 'org.mockito:mockito-core'
testImplementation 'org.mockito:mockito-junit-jupiter'
}

gradlePlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,20 @@

package com.palantir.gradle.jdks;

import org.gradle.api.file.Directory;
import org.gradle.api.provider.Provider;
import org.gradle.jvm.toolchain.JavaInstallationMetadata;
import org.immutables.value.Value;

@Value.Immutable
abstract class GradleJdksJavaInstallationMetadata implements JavaInstallationMetadata {
protected abstract Provider<Directory> installationPathProvider();

@Override
public Directory getInstallationPath() {
return installationPathProvider().get();
}

public static final class Builder extends ImmutableGradleJdksJavaInstallationMetadata.Builder {}

public static Builder builder() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,14 @@

final class JdkDownloader {

private final Project rootProject;
private final Project project;
private final String jdkGroup;

JdkDownloader(Project rootProject, JdkDistributionName jdkDistributionName, String jdkBaseUrl) {
this.rootProject = rootProject;
JdkDownloader(Project project, JdkDistributionName jdkDistributionName, String jdkBaseUrl) {
this.project = project;
this.jdkGroup = jdkDistributionName.uiName() + "-jdk";

if (rootProject != rootProject.getRootProject()) {
throw new IllegalArgumentException("Must pass in the root project");
}

rootProject.getRepositories().ivy(ivy -> {
project.getRepositories().ivy(ivy -> {
ivy.setName(jdkGroup);
ivy.setUrl(jdkBaseUrl);
ivy.patternLayout(patternLayout -> patternLayout.artifact("[module].[ext]"));
Expand All @@ -43,20 +39,11 @@ final class JdkDownloader {
repositoryContentDescriptor.includeGroup(jdkGroup);
});
});

rootProject
.getRepositories()
.matching(repo -> !repo.getName().equals(jdkGroup))
.configureEach(artifactRepository -> {
artifactRepository.content(content -> content.excludeGroup(jdkGroup));
});
}

public Path downloadJdkPath(JdkPath jdKPath) {
Configuration configuration = rootProject
.getConfigurations()
.detachedConfiguration(rootProject
.getDependencies()
Configuration configuration = project.getConfigurations()
.detachedConfiguration(project.getDependencies()
.create(String.format("%s:%s:@%s", jdkGroup, jdKPath.filename(), jdKPath.extension())));
return configuration.resolve().iterator().next().toPath();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,36 @@
import java.util.HashMap;
import java.util.Map;
import org.gradle.api.Project;
import org.immutables.value.Value;

final class JdkDownloaders {
private final Map<JdkDistributionName, JdkDownloader> jdkDownloaders = new HashMap<>();
private final Map<JdkDownloadersCacheKey, JdkDownloader> jdkDownloaders = new HashMap<>();

private final Project rootProject;
private final JdksExtension jdksExtension;

JdkDownloaders(Project rootProject, JdksExtension jdksExtension) {
if (rootProject != rootProject.getRootProject()) {
throw new IllegalArgumentException("Must pass in the root project");
}

this.rootProject = rootProject;
JdkDownloaders(JdksExtension jdksExtension) {
this.jdksExtension = jdksExtension;
}

public JdkDownloader jdkDownloaderFor(JdkDistributionName jdkDistributionName) {
public JdkDownloader jdkDownloaderFor(Project project, JdkDistributionName jdkDistributionName) {
return jdkDownloaders.computeIfAbsent(
jdkDistributionName,
ImmutableJdkDownloadersCacheKey.builder()
.project(project)
.jdkDistributionName(jdkDistributionName)
.build(),
_ignored -> new JdkDownloader(
rootProject,
project,
jdkDistributionName,
jdksExtension
.getJdkDistributions()
.getting(jdkDistributionName)
.get()
.jdkDistributionFor(jdkDistributionName)
.getBaseUrl()
.get()));
}

@Value.Immutable
interface JdkDownloadersCacheKey {
Project project();

JdkDistributionName jdkDistributionName();
}
}
23 changes: 9 additions & 14 deletions gradle-jdks/src/main/java/com/palantir/gradle/jdks/JdkManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,17 @@
import org.gradle.process.ExecResult;

public final class JdkManager {
private final Project project;
private final Provider<Directory> storageLocation;
private final JdkDistributions jdkDistributions;
private final JdkDownloaders jdkDownloaders;

JdkManager(
Project project,
Provider<Directory> storageLocation,
JdkDistributions jdkDistributions,
JdkDownloaders jdkDownloaders) {
this.project = project;
JdkManager(Provider<Directory> storageLocation, JdkDistributions jdkDistributions, JdkDownloaders jdkDownloaders) {
this.storageLocation = storageLocation;
this.jdkDistributions = jdkDistributions;
this.jdkDownloaders = jdkDownloaders;
}

public Path jdk(JdkSpec jdkSpec) {
public Path jdk(Project project, JdkSpec jdkSpec) {
Path diskPath = storageLocation
.get()
.getAsFile()
Expand All @@ -65,21 +59,22 @@ public Path jdk(JdkSpec jdkSpec) {
}

JdkPath jdkPath = jdkDistributions.get(jdkSpec.distributionName()).path(jdkSpec.release());
Path jdkArchive =
jdkDownloaders.jdkDownloaderFor(jdkSpec.distributionName()).downloadJdkPath(jdkPath);
Path jdkArchive = jdkDownloaders
.jdkDownloaderFor(project, jdkSpec.distributionName())
.downloadJdkPath(jdkPath);

Path temporaryJdkPath = Paths.get(
diskPath + ".in-progress-" + UUID.randomUUID().toString().substring(0, 8));
try {
project.copy(copy -> {
copy.from(unpackTree(jdkPath.extension(), jdkArchive));
copy.from(unpackTree(project, jdkPath.extension(), jdkArchive));
copy.into(temporaryJdkPath);
});

Path javaHome = findJavaHome(temporaryJdkPath);

jdkSpec.caCerts().caCerts().forEach((name, caCertFile) -> {
addCaCert(javaHome, name, caCertFile);
addCaCert(project, javaHome, name, caCertFile);
});

try {
Expand All @@ -99,7 +94,7 @@ public Path jdk(JdkSpec jdkSpec) {
}
}

private FileTree unpackTree(Extension extension, Path path) {
private FileTree unpackTree(Project project, Extension extension, Path path) {
switch (extension) {
case ZIP:
return project.zipTree(path.toFile());
Expand Down Expand Up @@ -128,7 +123,7 @@ private Path findJavaHome(Path temporaryJdkPath) {
}
}

private void addCaCert(Path javaHome, String alias, String caCert) {
private void addCaCert(Project project, Path javaHome, String alias, String caCert) {
ByteArrayOutputStream output = new ByteArrayOutputStream();

ExecResult keytoolResult = project.exec(exec -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,55 +18,77 @@

import groovy.lang.Closure;
import groovy.lang.DelegatesTo;
import java.util.Optional;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.ProviderFactory;
import org.gradle.jvm.toolchain.JavaLanguageVersion;

public abstract class JdksExtension {
protected abstract MapProperty<JdkDistributionName, JdkDistributionExtension> getJdkDistributions();
private final LazilyConfiguredMapping<JdkDistributionName, JdkDistributionExtension, Void> jdkDistributions;
private final LazilyConfiguredMapping<JavaLanguageVersion, JdkExtension, Project> jdks;

protected abstract MapProperty<JavaLanguageVersion, JdkExtension> getJdks();
public JdksExtension() {
this.jdkDistributions =
new LazilyConfiguredMapping<>(() -> getObjectFactory().newInstance(JdkDistributionExtension.class));
this.jdks = new LazilyConfiguredMapping<>(() -> getObjectFactory().newInstance(JdkExtension.class));
}

public abstract MapProperty<String, String> getCaCerts();

public abstract DirectoryProperty getJdkStorageLocation();

@Inject
protected abstract ProviderFactory getProviderFactory();

@Inject
protected abstract ObjectFactory getObjectFactory();

public final void jdks(LazyJdks lazyJdks) {
jdks.put(lazyJdks::configureJdkFor);
}

public final void jdk(JavaLanguageVersion javaLanguageVersion, Action<JdkExtension> action) {
JdkExtension jdkExtension = getJdks()
.getting(javaLanguageVersion)
.orElse(getProviderFactory().provider(() -> {
JdkExtension newJdkExtension = getObjectFactory().newInstance(JdkExtension.class);
getJdks().put(javaLanguageVersion, newJdkExtension);
return newJdkExtension;
}))
.get();

action.execute(jdkExtension);
jdks.put(javaLanguageVersion, action);
}

@SuppressWarnings("RawTypes")
public final void jdk(int javaLanguageVersion, @DelegatesTo(JdkExtension.class) Closure closure) {
jdk(JavaLanguageVersion.of(javaLanguageVersion), ConfigureUtil.toAction(closure));
}

public final void jdkDistributions(LazyJdkDistributions lazyJdkDistributions) {
jdkDistributions.put((jdkDistributionName, _ignored) ->
lazyJdkDistributions.configureJdkDistributionFor(jdkDistributionName));
}

public final void jdkDistribution(
JdkDistributionName jdkDistributionName, Action<JdkDistributionExtension> action) {
action.execute(getJdkDistributions().getting(jdkDistributionName).get());
jdkDistributions.put(jdkDistributionName, action);
}

@SuppressWarnings("RawTypes")
public final void jdkDistribution(
String distributionName, @DelegatesTo(JdkDistributionExtension.class) Closure closure) {
jdkDistribution(JdkDistributionName.fromStringThrowing(distributionName), ConfigureUtil.toAction(closure));
}

public final JdkDistributionExtension jdkDistributionFor(JdkDistributionName jdkDistributionName) {
return jdkDistributions
.get(jdkDistributionName, null)
.orElseThrow(() -> new RuntimeException(
String.format("No configuration for JdkDistribution " + jdkDistributionName)));
}

public final Optional<JdkExtension> jdkFor(JavaLanguageVersion javaLanguageVersion, Project project) {
return jdks.get(javaLanguageVersion, project);
}

public interface LazyJdkDistributions {
Optional<Action<JdkDistributionExtension>> configureJdkDistributionFor(JdkDistributionName jdkDistributionName);
}

public interface LazyJdks {
Optional<Action<JdkExtension>> configureJdkFor(JavaLanguageVersion javaLanguageVersion, Project project);
}
}
Loading