Skip to content

Commit 29a159a

Browse files
committed
Allow usage of #launcherFor without the 'java' plugin
Not all Gradle plugins are required to apply the 'java' plugin. This means that for plugins which need a Java launcher for a task and/or JavaExec(Spec), we need to be flexible to avoid locking in projects into needing that plugin. I've locked down the SharedUtil methods for getting Java launchers. #launcherFor requires Project and #launcherForStrict requires JavaToolchainService (provided by JavaExecSpec, or can be injected at project configuration). If no Java toolchain or 'java' plugin, `JavaLanguageVersion#current` will be used to compare to the required Java version to run. As a reminder, breaking changes are permitted for `gradleutils-shared` as it must only ever be shadowed by plugins that use it.
1 parent 0d2cde6 commit 29a159a

File tree

2 files changed

+104
-114
lines changed

2 files changed

+104
-114
lines changed

gradleutils-shared/src/main/java/net/minecraftforge/gradleutils/shared/EnhancedProblems.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,11 @@ protected final ProblemId id(String name, String displayName) {
116116
return ProblemId.create(name, displayName, this.getProblemGroup());
117117
}
118118

119-
/// Checks if the given property exists and equals `true`. This checks both [Gradle][ProviderFactory#gradleProperty]
120-
/// and [System][ProviderFactory#systemProperty] properties, giving the former higher priority. If for some reason a
121-
/// provider factory is not available in the current environment, [Boolean#getBoolean(String)] will be used
122-
/// instead.
119+
/// Checks if the given property exists and equals `true`.
120+
///
121+
/// This checks both [Gradle][ProviderFactory#gradleProperty] and [System][ProviderFactory#systemProperty]
122+
/// properties, giving the former higher priority. If for some reason a provider factory is not available in the
123+
/// current environment, [Boolean#getBoolean(String)] will be used instead.
123124
///
124125
/// @param property The property to test
125126
/// @return If the property exists and is `true`
@@ -132,6 +133,22 @@ public final boolean test(String property) {
132133
}
133134
}
134135

136+
/// Checks if the given property exists and equals `false`.
137+
///
138+
/// This checks both [Gradle][ProviderFactory#gradleProperty] and [System][ProviderFactory#systemProperty]
139+
/// properties, giving the former higher priority. If for some reason a provider factory is not available in the
140+
/// current environment, [Boolean#getBoolean(String)] will be used instead.
141+
///
142+
/// @param property The property to test
143+
/// @return If the property exists and is `false`
144+
public final boolean testFalse(String property) {
145+
try {
146+
return isFalse(this.getProviders(), property);
147+
} catch (Exception e) {
148+
return Boolean.getBoolean(property);
149+
}
150+
}
151+
135152

136153
/* DEFAULT PROBLEMS */
137154

gradleutils-shared/src/main/java/net/minecraftforge/gradleutils/shared/SharedUtil.java

Lines changed: 83 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import groovy.transform.stc.FirstParam;
1111
import org.gradle.api.Action;
1212
import org.gradle.api.Project;
13+
import org.gradle.api.Transformer;
1314
import org.gradle.api.artifacts.Dependency;
1415
import org.gradle.api.artifacts.FileCollectionDependency;
1516
import org.gradle.api.artifacts.ModuleVersionSelector;
@@ -21,9 +22,9 @@
2122
import org.gradle.jvm.toolchain.JavaLanguageVersion;
2223
import org.gradle.jvm.toolchain.JavaLauncher;
2324
import org.gradle.jvm.toolchain.JavaToolchainService;
24-
import org.gradle.jvm.toolchain.JavaToolchainSpec;
2525
import org.jetbrains.annotations.Contract;
2626

27+
import javax.inject.Inject;
2728
import java.io.BufferedReader;
2829
import java.io.File;
2930
import java.io.IOException;
@@ -38,96 +39,90 @@
3839
public abstract class SharedUtil {
3940
//region Java Launcher
4041

42+
/// Transformer to map a Java launcher to its executable path. Use to store in properties since [JavaLauncher]
43+
/// cannot be serialized.
44+
public static final Transformer<String, JavaLauncher> LAUNCHER_EXECUTABLE = it -> it.getExecutablePath().toString();
45+
4146
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
4247
/// given version.
4348
///
44-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
49+
/// If the currently available Java toolchain is able to compile and run the given version, it will be used instead.
50+
/// The toolchain is first queried from the project's [JavaPluginExtension#getToolchain()]. If the toolchain is not
51+
/// set or does not apply the `java` plugin, [JavaLanguageVersion#current()] will be used instead.
4552
///
46-
/// @param java The Java plugin extension of the currently-used toolchain
47-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
48-
/// @param version The version of Java required
53+
/// @param project The project to get the Java extensions from
54+
/// @param version The version of Java required
4955
/// @return A provider for the Java launcher
50-
public static Provider<JavaLauncher> launcherFor(JavaPluginExtension java, JavaToolchainService javaToolchains, int version) {
51-
return launcherFor(java, javaToolchains, JavaLanguageVersion.of(version));
56+
public static Provider<JavaLauncher> launcherFor(Project project, int version) {
57+
return launcherFor(project, JavaLanguageVersion.of(version));
5258
}
5359

5460
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
5561
/// given version.
5662
///
57-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
63+
/// If the currently available Java toolchain is able to compile and run the given version, it will be used instead.
64+
/// The toolchain is first queried from the project's [JavaPluginExtension#getToolchain()]. If the toolchain is not
65+
/// set or does not apply the `java` plugin, [JavaLanguageVersion#current()] will be used instead.
5866
///
59-
/// @param java The Java plugin extension of the currently-used toolchain
60-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
61-
/// @param version The version of Java required
67+
/// @param project The project to get the Java extensions from
68+
/// @param version The version of Java required
6269
/// @return A provider for the Java launcher
63-
public static Provider<JavaLauncher> launcherFor(JavaPluginExtension java, JavaToolchainService javaToolchains, JavaLanguageVersion version) {
64-
JavaToolchainSpec currentToolchain = java.getToolchain();
65-
return currentToolchain.getLanguageVersion().orElse(JavaLanguageVersion.current()).flatMap(languageVersion -> languageVersion.canCompileOrRun(version)
66-
? javaToolchains.launcherFor(spec -> spec.getLanguageVersion().set(languageVersion))
67-
: launcherForStrictly(javaToolchains, version));
70+
public static Provider<JavaLauncher> launcherFor(Project project, JavaLanguageVersion version) {
71+
ProviderFactory providers = project.getProviders();
72+
ExtensionContainer extensions = project.getExtensions();
73+
return launcherFor(providers.provider(() -> extensions.findByType(JavaPluginExtension.class)), getJavaToolchainService(project), version);
6874
}
6975

70-
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
71-
/// given version.
72-
///
73-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
74-
///
75-
/// @param java The Java plugin extension of the currently-used toolchain
76-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
77-
/// @param version The version of Java required
78-
/// @return A provider for the Java launcher
79-
public static Provider<JavaLauncher> launcherFor(Provider<? extends JavaPluginExtension> java, Provider<? extends JavaToolchainService> javaToolchains, int version) {
76+
private static Provider<JavaLauncher> launcherFor(Provider<? extends JavaPluginExtension> java, JavaToolchainService javaToolchains, int version) {
8077
return launcherFor(java, javaToolchains, JavaLanguageVersion.of(version));
8178
}
8279

83-
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
84-
/// given version.
85-
///
86-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
87-
///
88-
/// @param java The Java plugin extension of the currently-used toolchain
89-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
90-
/// @param version The version of Java required
91-
/// @return A provider for the Java launcher
92-
public static Provider<JavaLauncher> launcherFor(Provider<? extends JavaPluginExtension> java, Provider<? extends JavaToolchainService> javaToolchains, JavaLanguageVersion version) {
93-
return java.flatMap(j -> {
94-
JavaToolchainSpec currentToolchain = j.getToolchain();
95-
return currentToolchain.getLanguageVersion().orElse(JavaLanguageVersion.current()).flatMap(languageVersion -> languageVersion.canCompileOrRun(version)
96-
? javaToolchains.flatMap(t -> t.launcherFor(spec -> spec.getLanguageVersion().set(languageVersion)))
97-
: launcherForStrictly(javaToolchains, version));
98-
});
80+
private static Provider<JavaLauncher> launcherFor(Provider<? extends JavaPluginExtension> java, JavaToolchainService javaToolchains, JavaLanguageVersion version) {
81+
return java.flatMap(j -> launcherFor(j, javaToolchains, version)).orElse(launcherFor(javaToolchains, version));
9982
}
10083

101-
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
102-
/// given version.
103-
///
104-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
84+
private static Provider<JavaLauncher> launcherFor(JavaPluginExtension java, JavaToolchainService javaToolchains, int version) {
85+
return launcherFor(java, javaToolchains, JavaLanguageVersion.of(version));
86+
}
87+
88+
private static Provider<JavaLauncher> launcherFor(JavaPluginExtension java, JavaToolchainService javaToolchains, JavaLanguageVersion version) {
89+
return java.getToolchain().getLanguageVersion().orElse(JavaLanguageVersion.current()).flatMap(
90+
languageVersion -> languageVersion.canCompileOrRun(version)
91+
? javaToolchains.launcherFor(spec -> spec.getLanguageVersion().set(languageVersion))
92+
: launcherForStrictly(javaToolchains, version)
93+
);
94+
}
95+
96+
private static Provider<JavaLauncher> launcherFor(JavaToolchainService javaToolchains, int version) {
97+
return launcherFor(javaToolchains, JavaLanguageVersion.of(version));
98+
}
99+
100+
private static Provider<JavaLauncher> launcherFor(JavaToolchainService javaToolchains, JavaLanguageVersion version) {
101+
JavaLanguageVersion languageVersion = JavaLanguageVersion.current();
102+
return languageVersion.canCompileOrRun(version)
103+
? javaToolchains.launcherFor(spec -> spec.getLanguageVersion().set(languageVersion))
104+
: launcherForStrictly(javaToolchains, version);
105+
}
106+
107+
/// Gets the Java launcher for the given version, even if the currently running Java toolchain is higher.
105108
///
106-
/// @param project The project to get the Java extensions from
109+
/// @param project The extension-aware object to get the Java extensions from
107110
/// @param version The version of Java required
108111
/// @return A provider for the Java launcher
109-
public static Provider<JavaLauncher> launcherFor(Project project, int version) {
110-
ProviderFactory providers = project.getProviders();
111-
ExtensionContainer extensions = project.getExtensions();
112-
return launcherFor(providers.provider(() -> extensions.getByType(JavaPluginExtension.class)), providers.provider(() -> extensions.getByType(JavaToolchainService.class)), version);
112+
public static Provider<JavaLauncher> launcherForStrictly(Project project, int version) {
113+
return launcherForStrictly(getJavaToolchainService(project), version);
113114
}
114115

115-
/// Gets the Java launcher that [can compile or run][JavaLanguageVersion#canCompileOrRun(JavaLanguageVersion)] the
116-
/// given version.
117-
///
118-
/// If the currently running Java toolchain is able to compile and run the given version, it will be used instead.
116+
/// Gets the Java launcher for the given version, even if the currently running Java toolchain is higher.
119117
///
120-
/// @param project The project to get the Java extensions from
118+
/// @param project The extension-aware object to get the Java extensions from
121119
/// @param version The version of Java required
122120
/// @return A provider for the Java launcher
123-
public static Provider<JavaLauncher> launcherFor(Project project, JavaLanguageVersion version) {
124-
ProviderFactory providers = project.getProviders();
125-
ExtensionContainer extensions = project.getExtensions();
126-
return launcherFor(providers.provider(() -> extensions.getByType(JavaPluginExtension.class)), providers.provider(() -> extensions.getByType(JavaToolchainService.class)), version);
121+
public static Provider<JavaLauncher> launcherForStrictly(Project project, JavaLanguageVersion version) {
122+
return launcherForStrictly(getJavaToolchainService(project), version);
127123
}
128124

129-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
130-
/// than it.
125+
/// Gets the Java launcher for the given version, even if the currently running Java toolchain is higher.
131126
///
132127
/// @param javaToolchains The Java toolchain service to get the Java launcher from
133128
/// @param version The version of Java required
@@ -136,8 +131,7 @@ public static Provider<JavaLauncher> launcherForStrictly(JavaToolchainService ja
136131
return launcherForStrictly(javaToolchains, JavaLanguageVersion.of(version));
137132
}
138133

139-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
140-
/// than it.
134+
/// Gets the Java launcher for the given version, even if the currently running Java toolchain is higher.
141135
///
142136
/// @param javaToolchains The Java toolchain service to get the Java launcher from
143137
/// @param version The version of Java required
@@ -146,48 +140,15 @@ public static Provider<JavaLauncher> launcherForStrictly(JavaToolchainService ja
146140
return javaToolchains.launcherFor(spec -> spec.getLanguageVersion().set(version));
147141
}
148142

149-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
150-
/// than it.
151-
///
152-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
153-
/// @param version The version of Java required
154-
/// @return A provider for the Java launcher
155-
public static Provider<JavaLauncher> launcherForStrictly(Provider<? extends JavaToolchainService> javaToolchains, int version) {
156-
return launcherForStrictly(javaToolchains, JavaLanguageVersion.of(version));
143+
private static JavaToolchainService getJavaToolchainService(Project project) {
144+
return project.getObjects().newInstance(ProjectServiceWrapper.class).getJavaToolchains();
157145
}
158146

159-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
160-
/// than it.
161-
///
162-
/// @param javaToolchains The Java toolchain service to get the Java launcher from
163-
/// @param version The version of Java required
164-
/// @return A provider for the Java launcher
165-
public static Provider<JavaLauncher> launcherForStrictly(Provider<? extends JavaToolchainService> javaToolchains, JavaLanguageVersion version) {
166-
return javaToolchains.flatMap(t -> t.launcherFor(spec -> spec.getLanguageVersion().set(version)));
167-
}
147+
static abstract class ProjectServiceWrapper {
148+
protected abstract @Inject JavaToolchainService getJavaToolchains();
168149

169-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
170-
/// than it.
171-
///
172-
/// @param project The extension-aware object to get the Java extensions from
173-
/// @param version The version of Java required
174-
/// @return A provider for the Java launcher
175-
public static Provider<JavaLauncher> launcherForStrictly(Project project, int version) {
176-
ProviderFactory providers = project.getProviders();
177-
ExtensionContainer extensions = project.getExtensions();
178-
return launcherForStrictly(providers.provider(() -> extensions.getByType(JavaToolchainService.class)), version);
179-
}
180-
181-
/// Gets the Java launcher strictly for the given version, even if the currently running Java toolchain is higher
182-
/// than it.
183-
///
184-
/// @param project The extension-aware object to get the Java extensions from
185-
/// @param version The version of Java required
186-
/// @return A provider for the Java launcher
187-
public static Provider<JavaLauncher> launcherForStrictly(Project project, JavaLanguageVersion version) {
188-
ProviderFactory providers = project.getProviders();
189-
ExtensionContainer extensions = project.getExtensions();
190-
return launcherForStrictly(providers.provider(() -> extensions.getByType(JavaToolchainService.class)), version);
150+
@Inject
151+
public ProjectServiceWrapper() { }
191152
}
192153
//endregion
193154

@@ -285,13 +246,15 @@ public static String toString(Dependency dependency) {
285246

286247
//region Properties
287248

288-
/// Makes a returning-self closure that finalizes a given property using [#finalizeProperty(Property)].
289-
///
290-
/// This is best used as the method argument for [org.codehaus.groovy.runtime.DefaultGroovyMethods#tap(Object,
291-
/// Closure)], which allows for in-lining property creation in Groovy code.
292-
///
293-
/// @param <P> The type of property to finalize
294-
/// @return The returning-self closure for finalizing a property
249+
/**
250+
* Makes a returning-self closure that finalizes a given property using {@link #finalizeProperty(Property)}.
251+
* <p>This is best used as the method argument for
252+
* {@link org.codehaus.groovy.runtime.DefaultGroovyMethods#tap(Object, Closure)}, which allows for in-lining
253+
* property creation in Groovy code.</p>
254+
*
255+
* @param <P> The type of property to finalize
256+
* @return The returning-self closure for finalizing a property
257+
*/
295258
public static <P extends Property<?>> Closure<P> finalizeProperty() {
296259
Closure<P> ret = Closures.unaryOperator(SharedUtil::finalizeProperty);
297260
ret.setResolveStrategy(Closure.DELEGATE_FIRST);
@@ -313,6 +276,16 @@ public static <P extends Property<?>> P finalizeProperty(P property) {
313276
property.finalizeValueOnRead();
314277
return property;
315278
}
279+
280+
/// Conditionally set the given provider's value to the given property's value if the property is
281+
/// [present][Provider#isPresent()].
282+
///
283+
/// @param from The provider value to apply
284+
/// @param to The property to apply the new value to
285+
/// @param <T> The type of property
286+
public static <T> void setOptional(Property<T> to, Provider<? extends T> from) {
287+
if (from.isPresent()) to.set(from);
288+
}
316289
//endregion
317290

318291
/// Empty constructor. This class should only be extended to make referencing these static methods easier.

0 commit comments

Comments
 (0)