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

Configurable java toolchains #2193

Merged
merged 31 commits into from
Apr 28, 2022
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
a96512d
An entirely plain refactor
CRogers Mar 25, 2022
533d5f7
Pass in project only
CRogers Mar 25, 2022
e56c43e
Write some code
CRogers Mar 25, 2022
40e7ad7
Add jvm versions to extensions
CRogers Apr 4, 2022
6e6d0ef
Get test working for jdk downloader
CRogers Apr 7, 2022
1aa5cfd
Extract jdk on osx
CRogers Apr 8, 2022
09c6d4f
Wire it all together
CRogers Apr 11, 2022
7e68898
Fixes
CRogers Apr 11, 2022
51b834a
Put a root plugin in so we can configure all the repos at the right time
CRogers Apr 11, 2022
1c35750
be english good
CRogers Apr 11, 2022
299e8c2
Clean up sstuff
CRogers Apr 11, 2022
d66ed8a
Fix test
CRogers Apr 12, 2022
bf928eb
Shorten paths
CRogers Apr 12, 2022
edd23d0
Merge branch 'develop' of github.com:palantir/gradle-baseline into ca…
CRogers Apr 12, 2022
edd8d6a
Add generated changelog entries
svc-changelog Apr 12, 2022
612189f
Move code to BaselineJavaVersionsExtensions
CRogers Apr 12, 2022
a747e9f
Flail around trying to understand artifact transforms
CRogers Apr 19, 2022
ad42636
Less nots
CRogers Apr 19, 2022
7330ac8
ArtifactView!!!!!!!
CRogers Apr 19, 2022
bd4efc7
Give up on copyspec madness
CRogers Apr 19, 2022
a402dc7
Use downloader only everywhere
CRogers Apr 19, 2022
8457837
Simplify to just being configured with specific jdks
CRogers Apr 21, 2022
5ef6fd4
Fix all those copyright notices
CRogers Apr 21, 2022
3c996ea
Remove jarchivelib
CRogers Apr 21, 2022
6c3df93
Tidy up diff
CRogers Apr 21, 2022
5816d1f
Add generated changelog entries
svc-changelog Apr 21, 2022
fe0bf39
Merge branch 'develop' of github.com:palantir/gradle-baseline into ca…
CRogers Apr 28, 2022
d492489
Tidy up code
CRogers Apr 28, 2022
e19d229
Write a test
CRogers Apr 28, 2022
f6d2b22
Try reenabling fork
CRogers Apr 28, 2022
1517462
Note one why fork is needed
CRogers Apr 28, 2022
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ out/
docs/node_modules/
generated_src
generated_testSrc
generated
generated_tests
1 change: 1 addition & 0 deletions gradle-baseline-java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ dependencies {
implementation 'org.ow2.asm:asm'
implementation 'com.googlecode.java-diff-utils:diffutils'
implementation 'com.diffplug.gradle:goomph'
implementation 'org.rauschig:jarchivelib'

runtimeOnly 'com.palantir.javaformat:gradle-palantir-java-format'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,13 @@

package com.palantir.baseline.extensions;

import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.jvm.toolchain.JavaLanguageVersion;

Expand All @@ -26,19 +31,33 @@
* target and runtime java versions used for a single project.
*/
public class BaselineJavaVersionExtension {
private static final Pattern ZULU_VERSION_PATTERN = Pattern.compile("ZULU_([\\d]+)_VERSION");
private static final Pattern JAVA_VERSION_PATTERN = Pattern.compile("JAVA_([\\d]+)_VERSION");

private final Property<JavaLanguageVersion> target;
private final Property<JavaLanguageVersion> runtime;
private final Property<Boolean> overrideLibraryAutoDetection;
private final MapProperty<JavaLanguageVersion, String> zuluVersions;
private final MapProperty<JavaLanguageVersion, String> javaVersions;

@Inject
public BaselineJavaVersionExtension(Project project) {
target = project.getObjects().property(JavaLanguageVersion.class);
runtime = project.getObjects().property(JavaLanguageVersion.class);
overrideLibraryAutoDetection = project.getObjects().property(Boolean.class);
target.finalizeValueOnRead();

runtime = project.getObjects().property(JavaLanguageVersion.class);
runtime.finalizeValueOnRead();

overrideLibraryAutoDetection = project.getObjects().property(Boolean.class);
overrideLibraryAutoDetection.finalizeValueOnRead();

zuluVersions = project.getObjects().mapProperty(JavaLanguageVersion.class, String.class);
zuluVersions.putAll(project.provider(() -> parseOutVersions(project, ZULU_VERSION_PATTERN)));
zuluVersions.finalizeValueOnRead();

javaVersions = project.getObjects().mapProperty(JavaLanguageVersion.class, String.class);
javaVersions.putAll(project.provider(() -> parseOutVersions(project, JAVA_VERSION_PATTERN)));
javaVersions.finalizeValueOnRead();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we could define these at most once per repo instead of per-module? (possibly BaselineJavaVersionsExtension.java, which only exists on the root project)
I don't think we would want the values to differ across modules.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heh actually in the process of doing this right now. The BaselineJavaVersion vs BaselineJavaVersions difference was lost on me for a little bit.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could have named things much better 😞 Sorry!

}

/** Target {@link JavaLanguageVersion} for compilation. */
Expand Down Expand Up @@ -70,4 +89,28 @@ public final Property<Boolean> overrideLibraryAutoDetection() {
public final void library() {
overrideLibraryAutoDetection.set(true);
}

public final MapProperty<JavaLanguageVersion, String> zuluVersions() {
return zuluVersions;
}

public final MapProperty<JavaLanguageVersion, String> javaVersions() {
return javaVersions;
}

private static Map<JavaLanguageVersion, String> parseOutVersions(Project project, Pattern propertyPattern) {
Map<JavaLanguageVersion, String> ret = new HashMap<>();

project.getProperties().forEach((key, value) -> {
Matcher matcher = propertyPattern.matcher(key);

if (!matcher.matches()) {
return;
}

ret.put(JavaLanguageVersion.of(Integer.parseInt(matcher.group(1))), (String) value);
});

return ret;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
package com.palantir.baseline.plugins;

import com.palantir.baseline.extensions.BaselineJavaVersionExtension;
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersionRootPlugin;
import com.palantir.baseline.plugins.javaversions.JavaToolchains;
import com.palantir.baseline.plugins.javaversions.JdkManager;
import com.palantir.baseline.plugins.javaversions.PalantirJavaToolchain;
import javax.inject.Inject;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
Expand All @@ -37,7 +41,6 @@
import org.gradle.api.tasks.scala.ScalaDoc;
import org.gradle.api.tasks.testing.Test;
import org.gradle.jvm.toolchain.JavaLanguageVersion;
import org.gradle.jvm.toolchain.JavaToolchainService;
import org.gradle.jvm.toolchain.JavaToolchainSpec;

public final class BaselineJavaVersion implements Plugin<Project> {
Expand All @@ -48,6 +51,12 @@ public final class BaselineJavaVersion implements Plugin<Project> {
public void apply(Project project) {
BaselineJavaVersionExtension extension =
project.getExtensions().create(EXTENSION_NAME, BaselineJavaVersionExtension.class, project);

JdkManager jdkManager = project.getRootProject()
.getPlugins()
.apply(BaselineJavaVersionRootPlugin.class)
.jdkManager();

project.getPluginManager().withPlugin("java", unused -> {
JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class);

Expand All @@ -61,11 +70,13 @@ public void execute(JavaToolchainSpec javaToolchainSpec) {
}
});

JavaToolchains javaToolchains = new JavaToolchains(project, extension, jdkManager);

// Compilation tasks (using target version)
configureCompilationTasks(project, extension.target());
configureCompilationTasks(project, javaToolchains.forVersion(extension.target()));

// Execution tasks (using the runtime version)
configureExecutionTasks(project, extension.runtime());
configureExecutionTasks(project, javaToolchains.forVersion(extension.runtime()));

// Validation
project.getTasks()
Expand All @@ -80,94 +91,55 @@ public void execute(CheckJavaVersionsTask task) {
});
}

private static void configureCompilationTasks(
Project project, Provider<JavaLanguageVersion> targetVersionProvider) {
JavaToolchainService javaToolchainService = project.getExtensions().getByType(JavaToolchainService.class);

private static void configureCompilationTasks(Project project, Provider<PalantirJavaToolchain> javaToolchain) {
project.getTasks().withType(JavaCompile.class, new Action<JavaCompile>() {
@Override
public void execute(JavaCompile javaCompile) {
javaCompile.getJavaCompiler().set(javaToolchainService.compilerFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(targetVersionProvider);
}
}));
javaCompile.getJavaCompiler().set(javaToolchain.flatMap(PalantirJavaToolchain::javaCompiler));
}
});

project.getTasks().withType(Javadoc.class, new Action<Javadoc>() {
@Override
public void execute(Javadoc javadoc) {
javadoc.getJavadocTool().set(javaToolchainService.javadocToolFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(targetVersionProvider);
}
}));
javadoc.getJavadocTool().set(javaToolchain.flatMap(PalantirJavaToolchain::javadocTool));
}
});

project.getTasks().withType(GroovyCompile.class, new Action<GroovyCompile>() {
@Override
public void execute(GroovyCompile groovyCompile) {
groovyCompile.getJavaLauncher().set(javaToolchainService.launcherFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(targetVersionProvider);
}
}));
groovyCompile.getJavaLauncher().set(javaToolchain.flatMap(PalantirJavaToolchain::javaLauncher));
}
});

project.getTasks().withType(ScalaCompile.class, new Action<ScalaCompile>() {
@Override
public void execute(ScalaCompile scalaCompile) {
scalaCompile.getJavaLauncher().set(javaToolchainService.launcherFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(targetVersionProvider);
}
}));
scalaCompile.getJavaLauncher().set(javaToolchain.flatMap(PalantirJavaToolchain::javaLauncher));
}
});

project.getTasks().withType(ScalaDoc.class, new Action<ScalaDoc>() {
@Override
public void execute(ScalaDoc scalaDoc) {
scalaDoc.getJavaLauncher().set(javaToolchainService.launcherFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(targetVersionProvider);
}
}));
scalaDoc.getJavaLauncher().set(javaToolchain.flatMap(PalantirJavaToolchain::javaLauncher));
}
});
}

private static void configureExecutionTasks(Project project, Provider<JavaLanguageVersion> runtimeVersionProvider) {
JavaToolchainService javaToolchainService = project.getExtensions().getByType(JavaToolchainService.class);
private static void configureExecutionTasks(Project project, Provider<PalantirJavaToolchain> javaToolchain) {
project.getTasks().withType(JavaExec.class, new Action<JavaExec>() {
@Override
public void execute(JavaExec javaExec) {
javaExec.getJavaLauncher().set(javaToolchainService.launcherFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(runtimeVersionProvider);
}
}));
javaExec.getJavaLauncher().set(javaToolchain.flatMap(PalantirJavaToolchain::javaLauncher));
}
});

project.getTasks().withType(Test.class, new Action<Test>() {
@Override
public void execute(Test test) {
test.getJavaLauncher().set(javaToolchainService.launcherFor(new Action<JavaToolchainSpec>() {
@Override
public void execute(JavaToolchainSpec javaToolchainSpec) {
javaToolchainSpec.getLanguageVersion().set(runtimeVersionProvider);
}
}));
test.getJavaLauncher().set(javaToolchain.flatMap(PalantirJavaToolchain::javaLauncher));
}
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License.
*/

package com.palantir.baseline.plugins.javaversions;

import org.gradle.api.provider.Provider;
import org.gradle.jvm.toolchain.JavaCompiler;
import org.gradle.jvm.toolchain.JavaLauncher;
import org.gradle.jvm.toolchain.JavadocTool;

final class AzulJavaToolchain implements PalantirJavaToolchain {
private final Provider<PalantirJavaInstallationMetadata> javaInstallationMetadata;

AzulJavaToolchain(Provider<PalantirJavaInstallationMetadata> javaInstallationMetadata) {
this.javaInstallationMetadata = javaInstallationMetadata;
}

@Override
public Provider<JavaCompiler> javaCompiler() {
return javaInstallationMetadata.map(PalantirJavaCompiler::new);
}

@Override
public Provider<JavadocTool> javadocTool() {
return javaInstallationMetadata.map(PalantirJavadocTool::new);
}

@Override
public Provider<JavaLauncher> javaLauncher() {
return javaInstallationMetadata.map(PalantirJavaLauncher::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License.
*/

package com.palantir.baseline.plugins.javaversions;

import com.google.common.collect.Iterables;
import java.nio.file.Path;
import java.util.Optional;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;

final class AzulJdkDownloader {
private static final String AZUL_JDK = "azul-jdk";

private final Project rootProject;

AzulJdkDownloader(Project rootProject) {
this.rootProject = rootProject;

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

String jdkBaseUrl = property("base-url").orElse("https://cdn.azul.com/zulu/bin/");

rootProject.getRepositories().ivy(ivy -> {
ivy.setName(AZUL_JDK);
ivy.setUrl(jdkBaseUrl);
ivy.patternLayout(patternLayout -> patternLayout.artifact("[module].[ext]"));
ivy.metadataSources(metadataSources -> metadataSources.artifact());
ivy.content(repositoryContentDescriptor -> {
repositoryContentDescriptor.includeGroup(AZUL_JDK);
});
});

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

public Path downloadJdkFor(JdkSpec jdkSpec) {
Configuration configuration = rootProject
.getConfigurations()
.detachedConfiguration(rootProject
.getDependencies()
.create(String.format(
"%s:zulu%s-ca-jdk%s-%s_%s:@zip",
AZUL_JDK, jdkSpec.zuluVersion(), jdkSpec.javaVersion(), jdkSpec.os(), jdkSpec.arch())));
return Iterables.getOnlyElement(configuration.resolve()).toPath();
}

private Optional<String> property(String name) {
return Optional.ofNullable((String) rootProject.findProperty("com.palantir.baseline-java-versions." + name));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* (c) Copyright 2022 Palantir Technologies Inc. All rights reserved.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10; http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License.
*/

package com.palantir.baseline.plugins.javaversions;

import org.gradle.api.Plugin;
import org.gradle.api.Project;

public final class BaselineJavaVersionRootPlugin implements Plugin<Project> {
private JdkManager jdkManager;

@Override
public void apply(Project rootProject) {
if (!rootProject.equals(rootProject.getRootProject())) {
throw new RuntimeException(
BaselineJavaVersionRootPlugin.class + " can only be applied on the root project");
}

jdkManager =
new JdkManager(rootProject.getBuildDir().toPath().resolve("jdks"), new AzulJdkDownloader(rootProject));
}

public JdkManager jdkManager() {
return jdkManager;
}
}
Loading