1010import groovy .transform .stc .FirstParam ;
1111import org .gradle .api .Action ;
1212import org .gradle .api .Project ;
13+ import org .gradle .api .Transformer ;
1314import org .gradle .api .artifacts .Dependency ;
1415import org .gradle .api .artifacts .FileCollectionDependency ;
1516import org .gradle .api .artifacts .ModuleVersionSelector ;
2122import org .gradle .jvm .toolchain .JavaLanguageVersion ;
2223import org .gradle .jvm .toolchain .JavaLauncher ;
2324import org .gradle .jvm .toolchain .JavaToolchainService ;
24- import org .gradle .jvm .toolchain .JavaToolchainSpec ;
2525import org .jetbrains .annotations .Contract ;
2626
27+ import javax .inject .Inject ;
2728import java .io .BufferedReader ;
2829import java .io .File ;
2930import java .io .IOException ;
3839public 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