|
10 | 10 | import groovy.transform.stc.FirstParam; |
11 | 11 | import org.gradle.TaskExecutionRequest; |
12 | 12 | import org.gradle.api.Action; |
| 13 | +import org.gradle.api.DomainObjectCollection; |
13 | 14 | import org.gradle.api.Project; |
14 | 15 | import org.gradle.api.Transformer; |
| 16 | +import org.gradle.api.artifacts.Configuration; |
| 17 | +import org.gradle.api.artifacts.ConfigurationContainer; |
15 | 18 | import org.gradle.api.artifacts.Dependency; |
16 | 19 | import org.gradle.api.artifacts.FileCollectionDependency; |
17 | 20 | import org.gradle.api.artifacts.ModuleVersionSelector; |
|
22 | 25 | import org.gradle.api.provider.Property; |
23 | 26 | import org.gradle.api.provider.Provider; |
24 | 27 | import org.gradle.api.provider.ProviderFactory; |
| 28 | +import org.gradle.api.specs.Spec; |
| 29 | +import org.gradle.api.tasks.SourceSet; |
25 | 30 | import org.gradle.api.tasks.TaskProvider; |
26 | 31 | import org.gradle.jvm.toolchain.JavaLanguageVersion; |
27 | 32 | import org.gradle.jvm.toolchain.JavaLauncher; |
|
38 | 43 | import java.io.PipedOutputStream; |
39 | 44 | import java.util.ArrayList; |
40 | 45 | import java.util.List; |
| 46 | +import java.util.Objects; |
| 47 | +import java.util.Set; |
41 | 48 | import java.util.function.Consumer; |
| 49 | +import java.util.function.Predicate; |
| 50 | +import java.util.stream.Stream; |
42 | 51 |
|
43 | 52 | /// Shared utilities for Gradle plugins. |
44 | 53 | /// |
@@ -222,6 +231,105 @@ public List<String> getArgs() { |
222 | 231 | } |
223 | 232 | //endregion |
224 | 233 |
|
| 234 | + //region Dependency Handling |
| 235 | + |
| 236 | + /// Checks if the given dependency is in the given source set. |
| 237 | + /// |
| 238 | + /// @param configurations The configuration container to use |
| 239 | + /// @param sourceSet The source set to check |
| 240 | + /// @param transitive If the source set should be searched transitively (if `false`, for example, this method |
| 241 | + /// will return `false` if the dependency is in the `main` source set but not explicitely |
| 242 | + /// declared in one of the `test` source set's dependency-scope configurations) |
| 243 | + /// @param dependency The dependency to find |
| 244 | + /// @return If the source set contains the dependency |
| 245 | + public static boolean contains(ConfigurationContainer configurations, SourceSet sourceSet, boolean transitive, Dependency dependency) { |
| 246 | + return contains(configurations, sourceSet, transitive, dependency::equals); |
| 247 | + } |
| 248 | + |
| 249 | + /// Checks if the given dependency is in the given source set. |
| 250 | + /// |
| 251 | + /// @param configurations The configuration container to use |
| 252 | + /// @param sourceSet The source set to check |
| 253 | + /// @param transitive If the source set should be searched transitively (if `false`, for example, this method |
| 254 | + /// will return `false` if the dependency is in the `main` source set but not explicitely |
| 255 | + /// declared in one of the `test` source set's dependency-scope configurations) |
| 256 | + /// @param dependency The dependency to find |
| 257 | + /// @return If the source set contains the dependency |
| 258 | + public static boolean contains(ConfigurationContainer configurations, SourceSet sourceSet, boolean transitive, Spec<? super Dependency> dependency) { |
| 259 | + return contains(configurations, sourceSet.getCompileOnlyConfigurationName(), transitive, dependency) || |
| 260 | + contains(configurations, sourceSet.getCompileOnlyApiConfigurationName(), transitive, dependency) || |
| 261 | + contains(configurations, sourceSet.getCompileClasspathConfigurationName(), transitive, dependency) || |
| 262 | + contains(configurations, sourceSet.getAnnotationProcessorConfigurationName(), transitive, dependency) || |
| 263 | + contains(configurations, sourceSet.getApiConfigurationName(), transitive, dependency) || |
| 264 | + contains(configurations, sourceSet.getImplementationConfigurationName(), transitive, dependency) || |
| 265 | + contains(configurations, sourceSet.getApiElementsConfigurationName(), transitive, dependency) || |
| 266 | + contains(configurations, sourceSet.getRuntimeOnlyConfigurationName(), transitive, dependency) || |
| 267 | + contains(configurations, sourceSet.getRuntimeClasspathConfigurationName(), transitive, dependency) || |
| 268 | + contains(configurations, sourceSet.getRuntimeElementsConfigurationName(), transitive, dependency); |
| 269 | + } |
| 270 | + |
| 271 | + private static boolean contains(ConfigurationContainer configurations, String configurationName, boolean transitive, Spec<? super Dependency> dependency) { |
| 272 | + var configuration = configurations.findByName(configurationName); |
| 273 | + return configuration != null && !(transitive ? configuration.getAllDependencies() : configuration.getDependencies()).matching(dependency).isEmpty(); |
| 274 | + } |
| 275 | + |
| 276 | + /// Checks if the given dependency is in the given source set. |
| 277 | + /// |
| 278 | + /// @param configurations The configuration container to use |
| 279 | + /// @param sourceSet The source set to check |
| 280 | + /// @param transitive If the source set should be searched transitively (if `false`, for example, this method |
| 281 | + /// will return `false` if the dependency is in the `main` source set but not explicitely |
| 282 | + /// declared in one of the `test` source set's dependency-scope configurations) |
| 283 | + /// @param dependency The dependency to find |
| 284 | + /// @return The set containing the filtered dependencies |
| 285 | + public static Stream<Dependency> collect(ConfigurationContainer configurations, SourceSet sourceSet, boolean transitive, Predicate<? super Dependency> dependency) { |
| 286 | + return Stream |
| 287 | + .of( |
| 288 | + configurations.findByName(sourceSet.getCompileOnlyConfigurationName()), |
| 289 | + configurations.findByName(sourceSet.getCompileOnlyApiConfigurationName()), |
| 290 | + configurations.findByName(sourceSet.getCompileClasspathConfigurationName()), |
| 291 | + configurations.findByName(sourceSet.getAnnotationProcessorConfigurationName()), |
| 292 | + configurations.findByName(sourceSet.getApiConfigurationName()), |
| 293 | + configurations.findByName(sourceSet.getImplementationConfigurationName()), |
| 294 | + configurations.findByName(sourceSet.getApiElementsConfigurationName()), |
| 295 | + configurations.findByName(sourceSet.getRuntimeOnlyConfigurationName()), |
| 296 | + configurations.findByName(sourceSet.getRuntimeClasspathConfigurationName()), |
| 297 | + configurations.findByName(sourceSet.getRuntimeElementsConfigurationName()) |
| 298 | + ) |
| 299 | + .filter(Objects::nonNull) |
| 300 | + .flatMap(configuration -> transitive ? configuration.getAllDependencies().stream() : configuration.getDependencies().stream()) |
| 301 | + .distinct() |
| 302 | + .filter(dependency); |
| 303 | + } |
| 304 | + |
| 305 | + private static <T> void guardCheck(T t) { } |
| 306 | + |
| 307 | + public static void forClasspathConfigurations(ConfigurationContainer configurations, SourceSet sourceSet, Action<? super Configuration> action) { |
| 308 | + forEach(configurations.named( |
| 309 | + name -> name.equals(sourceSet.getCompileClasspathConfigurationName()) |
| 310 | + || name.equals(sourceSet.getRuntimeClasspathConfigurationName()) |
| 311 | + || name.equals(sourceSet.getAnnotationProcessorConfigurationName()) |
| 312 | + ), action); |
| 313 | + } |
| 314 | + //endregion |
| 315 | + |
| 316 | + //region Domain Object Handling |
| 317 | + public static <T> void forEach(DomainObjectCollection<T> collection, Action<? super T> action) { |
| 318 | + boolean eager = false; |
| 319 | + try { |
| 320 | + collection.configureEach(SharedUtil::guardCheck); |
| 321 | + } catch (IllegalStateException e) { |
| 322 | + eager = true; |
| 323 | + } |
| 324 | + |
| 325 | + if (eager) { |
| 326 | + collection.forEach(action::execute); |
| 327 | + } else { |
| 328 | + collection.configureEach(action); |
| 329 | + } |
| 330 | + } |
| 331 | + //endregion |
| 332 | + |
225 | 333 | //region Action Logging |
226 | 334 |
|
227 | 335 | /// Creates an output stream that logs to the given action. |
|
0 commit comments