Skip to content

Commit

Permalink
baseline-java-versions allows opting in to --enable-preview (#2322)
Browse files Browse the repository at this point in the history
Users of the `com.palantir.baseline-java-versions` plugin can now set `javaVersions { distributionTarget = '17_PREVIEW' }` to opt-in to Java's `--enable-preview` flag at compile time.
  • Loading branch information
iamdanfox authored Jul 29, 2022
1 parent 9ec44a2 commit 2edea0f
Show file tree
Hide file tree
Showing 20 changed files with 504 additions and 428 deletions.
6 changes: 3 additions & 3 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ version: 2.1
jobs:

check:
docker: [{ image: 'cimg/openjdk:11.0.10-node' }]
docker: [{ image: 'cimg/openjdk:17.0.1-node' }]
resource_class: large
environment:
CIRCLE_TEST_REPORTS: /home/circleci/junit
Expand Down Expand Up @@ -58,7 +58,7 @@ jobs:
- store_artifacts: { path: ~/artifacts }

trial-publish:
docker: [{ image: 'cimg/openjdk:11.0.10-node' }]
docker: [{ image: 'cimg/openjdk:17.0.1-node' }]
resource_class: medium
environment:
CIRCLE_TEST_REPORTS: /home/circleci/junit
Expand Down Expand Up @@ -104,7 +104,7 @@ jobs:
- store_artifacts: { path: ~/artifacts }

publish:
docker: [{ image: 'cimg/openjdk:11.0.10-node' }]
docker: [{ image: 'cimg/openjdk:17.0.1-node' }]
resource_class: medium
environment:
CIRCLE_TEST_REPORTS: /home/circleci/junit
Expand Down
2 changes: 1 addition & 1 deletion .circleci/template.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/usr/bin/env bash
export CIRCLECI_TEMPLATE=java-library-oss
export JDK=11
export JDK=17
67 changes: 33 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -416,40 +416,6 @@ This plugin adds the `-Aimmutables.gradle.incremental` compiler arg to the compi
For more details, see the Immutables incremental compilation [tracking issue](https://github.com/immutables/immutables/issues/804).
## com.palantir.baseline-enable-preview-flag (off by default)
As described in [JEP 12](https://openjdk.java.net/jeps/12), Java allows you to use shiny new syntax features if you add
the `--enable-preview` flag. However, gradle requires you to add it in multiple places. This plugin can be applied to
within an allprojects block and it will automatically ugprade any project which is already using the latest
sourceCompatibility by adding the necessary `--enable-preview` flags to all of the following task types.
_Note, this plugin should be used with **caution** because preview features may change or be removed, and it
is undesirable to deeply couple a repo to a particular Java version as it makes upgrading to a new major Java version harder._
```gradle
// root build.gradle
allprojects {
apply plugin: 'com.palantir.baseline-enable-preview-flag'
}
```

```gradle
// shorthand for the below:
tasks.withType(JavaCompile) {
options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
jvmArgs += "--enable-preview"
}
```

If you've explicitly specified a lower sourceCompatibility (e.g. for a published API jar), then this plugin is a no-op.
In fact, Java will actually error if you try to switch on the `--enable-preview` flag to get cutting edge syntax
features but set `sourceCompatibility` (or `--release`) to an older Java version.

## com.palantir.baseline-java-versions
This plugin allows consistent configuration of JDK versions via [Gradle Toolchains](https://docs.gradle.org/current/userguide/toolchains.html).
Expand Down Expand Up @@ -482,3 +448,36 @@ javaVersion {
```

The optionally configurable fields of the `javaVersion` extension are `target`, for setting the target version used for compilation and `runtime`, for setting the runtime version used for testing and distributions.

### Opting in to `--enable-preview` flag

As described in [JEP 12](https://openjdk.java.net/jeps/12), Java allows you to use incubating syntax features if you add the `--enable-preview` flag. Gradle requires you to add it in many places (including on JavaCompile, Javadoc tasks, as well as in production and on execution tasks like Test, JavaExec). The baseline-java-versions plugin provides a shorthand way of enabling this:

```gradle
// root build.gradle
apply plugin: 'com.palantir.baseline-java-versions'
javaVersions {
libraryTarget = 11
distributionTarget = '17_PREVIEW'
runtime = '17_PREVIEW'
}
// shorthand for configuring all the tasks individually, e.g.
tasks.withType(JavaCompile) {
options.compilerArgs += "--enable-preview"
}
tasks.withType(Test) {
jvmArgs += "--enable-preview"
}
tasks.withType(JavaExec) {
jvmArgs += "--enable-preview"
}
```

In the example above, the `Baseline-Enable-Preview: 17` attribute will be embedded in the resultant Jar's `META-INF/MANIFEST.MF` file. To see for yourself, run:

```
$ unzip -p /path/to/your-project-1.2.3.jar META-INF/MANIFEST.MF
```

_Note, this plugin should be used with **caution** because preview features may change or be removed, which might make upgrading to a new Java version harder._
7 changes: 7 additions & 0 deletions changelog/@unreleased/pr-2322.v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type: feature
feature:
description: Users of the `com.palantir.baseline-java-versions` plugin can now set
`javaVersions { distributionTarget = '17_PREVIEW' }` to opt-in to Java's `--enable-preview`
flag at compile time.
links:
- https://github.com/palantir/gradle-baseline/pull/2322
5 changes: 0 additions & 5 deletions gradle-baseline-java/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,6 @@ gradlePlugin {
displayName = 'Palantir Baseline Release Compatibility Plugin'
implementationClass = 'com.palantir.baseline.plugins.BaselineReleaseCompatibility'
}
baselineEnablePreviewFlag {
id = 'com.palantir.baseline-enable-preview-flag'
displayName = 'Palantir Baseline --enable-preview Flag Plugin'
implementationClass = 'com.palantir.baseline.plugins.BaselineEnablePreviewFlag'
}
baselinePreferProjectModules {
id = 'com.palantir.baseline-prefer-project-modules'
displayName = 'Palantir Baseline Prefer Project Modules Plugin'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@
package com.palantir.baseline.extensions;

import com.google.common.collect.ImmutableSet;
import java.util.Optional;
import java.util.Set;
import javax.inject.Inject;
import org.gradle.api.Project;
import org.gradle.api.provider.Provider;
import org.gradle.api.provider.SetProperty;
import org.gradle.jvm.toolchain.JavaLanguageVersion;

/**
* Extension to configure {@code --add-exports [VALUE]=ALL-UNNAMED} for the current module.
Expand All @@ -28,11 +32,13 @@ public class BaselineModuleJvmArgsExtension {

private final SetProperty<String> exports;
private final SetProperty<String> opens;
private final SetProperty<JavaLanguageVersion> enablePreview; // stores a singleton version or the empty set

@Inject
public BaselineModuleJvmArgsExtension(Project project) {
exports = project.getObjects().setProperty(String.class);
opens = project.getObjects().setProperty(String.class);
enablePreview = project.getObjects().setProperty(JavaLanguageVersion.class);
}

/**
Expand Down Expand Up @@ -71,6 +77,14 @@ public final void setOpens(String... input) {
opens.set(immutableDeduplicatedCopy);
}

public final void setEnablePreview(Provider<Optional<JavaLanguageVersion>> provider) {
enablePreview.set(provider.map(maybeValue -> maybeValue.map(Set::of).orElseGet(Set::of)));
}

public final Provider<Set<JavaLanguageVersion>> getEnablePreview() {
return enablePreview;
}

private static void validateModulePackagePair(String moduleAndPackage) {
if (moduleAndPackage.contains("=")) {
throw new IllegalArgumentException(String.format(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@ import com.google.common.collect.ImmutableMap
import com.palantir.baseline.IntellijSupport
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersionExtension
import com.palantir.baseline.plugins.javaversions.BaselineJavaVersionsExtension
import com.palantir.baseline.plugins.javaversions.ChosenJavaVersion
import com.palantir.baseline.util.GitUtils
import groovy.transform.CompileStatic
import groovy.xml.XmlUtil
import org.gradle.api.JavaVersion
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.plugins.ide.idea.model.IdeaLanguageLevel

import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
Expand All @@ -39,6 +36,7 @@ import org.gradle.api.file.FileTreeElement
import org.gradle.api.plugins.quality.CheckstyleExtension
import org.gradle.api.specs.Spec
import org.gradle.api.tasks.util.PatternFilterable
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.plugins.ide.idea.GenerateIdeaModule
import org.gradle.plugins.ide.idea.GenerateIdeaProject
import org.gradle.plugins.ide.idea.GenerateIdeaWorkspace
Expand Down Expand Up @@ -210,7 +208,7 @@ class BaselineIdea extends AbstractBaselinePlugin {
bytecodeTargetLevel.attributes().put("target", defaultBytecodeVersion.toString())
project.allprojects.forEach({ project ->
BaselineJavaVersionExtension version = project.getExtensions().findByType(BaselineJavaVersionExtension.class)
if (version != null && version.target().get().asInt() != defaultBytecodeVersion.asInt()) {
if (version != null && version.target().get().javaLanguageVersion().asInt() != defaultBytecodeVersion.asInt()) {
bytecodeTargetLevel.appendNode("module", ImmutableMap.of(
"name", project.getName(),
"target", version.target().get().toString()))
Expand All @@ -220,22 +218,21 @@ class BaselineIdea extends AbstractBaselinePlugin {

private void updateProjectRootManager(Node node, BaselineJavaVersionsExtension versions) {
Node projectRootManager = node.component.find { it.'@name' == 'ProjectRootManager' }
int featureRelease = versions.distributionTarget().get().asInt()
JavaVersion javaVersion = JavaVersion.toVersion(featureRelease)
ChosenJavaVersion chosenJavaVersion = versions.distributionTarget().get()
int featureRelease = chosenJavaVersion.javaLanguageVersion().asInt()
projectRootManager.attributes().put("project-jdk-name", featureRelease)
projectRootManager.attributes().put("languageLevel", new IdeaLanguageLevel(javaVersion).getLevel())
projectRootManager.attributes().put("languageLevel", chosenJavaVersion.asIdeaLanguageLevel())
}

private static void updateModuleLanguageVersion(IdeaModel ideaModel, Project currentProject) {
ideaModel.module.iml.withXml { XmlProvider provider ->
// Extension must be checked lazily within the transformer
BaselineJavaVersionExtension version = currentProject.extensions.findByType(BaselineJavaVersionExtension.class)
if (version != null) {
int featureRelease = version.target().get().asInt()
JavaVersion javaVersion = JavaVersion.toVersion(featureRelease)
BaselineJavaVersionExtension versionExtension = currentProject.extensions.findByType(BaselineJavaVersionExtension.class)
if (versionExtension != null) {
ChosenJavaVersion chosenJavaVersion = versionExtension.target().get()
Node node = provider.asNode()
Node newModuleRootManager = node.component.find { it.'@name' == 'NewModuleRootManager' }
newModuleRootManager.attributes().put("LANGUAGE_LEVEL", new IdeaLanguageLevel(javaVersion).getLevel())
newModuleRootManager.attributes().put("LANGUAGE_LEVEL", chosenJavaVersion.asIdeaLanguageLevel())
}
}
}
Expand Down
Loading

0 comments on commit 2edea0f

Please sign in to comment.