Separate plugins for different Gradle APIs

This commit is contained in:
Tad Fisher
2024-06-04 13:11:18 -07:00
parent a935331795
commit 85cebdd557
40 changed files with 1258 additions and 3993 deletions

View File

@@ -0,0 +1,12 @@
plugins {
`plugin-conventions`
}
dependencies {
implementation(project(":plugin:common"))
compileOnly(libs.gradle.api.get69())
}
tasks.shadowJar {
archiveFileName = "plugin-base.jar"
}

View File

@@ -0,0 +1,18 @@
package org.nixos.gradle2nix
import org.gradle.api.invocation.Gradle
import org.gradle.internal.operations.BuildOperationListenerManager
object DependencyExtractorApplierBase : DependencyExtractorApplier {
override fun apply(
gradle: Gradle,
extractor: DependencyExtractor,
) {
val buildOperationListenerManager = gradle.service<BuildOperationListenerManager>()
buildOperationListenerManager.addListener(extractor)
gradle.buildFinished {
buildOperationListenerManager.removeListener(extractor)
}
}
}

View File

@@ -0,0 +1,7 @@
package org.nixos.gradle2nix
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
GradleCacheAccessFactoryBase,
DependencyExtractorApplierBase,
ResolveAllArtifactsApplierBase,
)

View File

@@ -0,0 +1,18 @@
package org.nixos.gradle2nix
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.invocation.Gradle
object GradleCacheAccessFactoryBase : GradleCacheAccessFactory {
override fun create(gradle: Gradle): GradleCacheAccess {
return GradleCacheAccessBase(gradle)
}
}
class GradleCacheAccessBase(gradle: Gradle) : GradleCacheAccess {
private val artifactCachesProvider = gradle.service<ArtifactCachesProvider>()
override fun useCache(block: () -> Unit) {
artifactCachesProvider.writableCacheLockingManager.useCache(block)
}
}

View File

@@ -0,0 +1,20 @@
package org.nixos.gradle2nix
import org.gradle.api.Project
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.nixos.gradle2nix.model.RESOLVE_PROJECT_TASK
object ResolveAllArtifactsApplierBase : AbstractResolveAllArtifactsApplier() {
override fun Project.registerProjectTask(): TaskProvider<*> =
tasks.register(RESOLVE_PROJECT_TASK, ResolveProjectDependenciesTaskBase::class.java)
}
abstract class ResolveProjectDependenciesTaskBase : ResolveProjectDependenciesTask() {
@TaskAction
fun action() {
for (configuration in getReportableConfigurations()) {
configuration.artifactFiles().count()
}
}
}

View File

@@ -1,61 +0,0 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
id("org.jetbrains.kotlin.jvm")
id("com.gradle.plugin-publish")
id("com.github.johnrengelman.shadow")
}
dependencies {
shadow(kotlin("stdlib-jdk8"))
shadow(kotlin("reflect"))
implementation(project(":model"))
implementation(libs.serialization.json)
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlin {
compilerOptions {
apiVersion.set(KotlinVersion.KOTLIN_1_6)
languageVersion.set(KotlinVersion.KOTLIN_1_6)
jvmTarget.set(JvmTarget.JVM_1_8)
optIn.add("kotlin.RequiresOptIn")
}
}
gradlePlugin {
plugins {
register("gradle2nix") {
id = "org.nixos.gradle2nix"
displayName = "gradle2nix"
description = "Expose Gradle tooling model for the gradle2nix tool"
implementationClass = "org.nixos.gradle2nix.Gradle2NixPlugin"
}
}
}
tasks {
jar {
manifest {
attributes["Implementation-Version"] = archiveVersion.get()
attributes["Implementation-Title"] = "Gradle2Nix Plugin"
attributes["Implementation-Vendor"] = "Tad Fisher"
}
}
shadowJar {
archiveClassifier.set("")
relocate("kotlin", "${project.group}.shadow.kotlin")
relocate("org.intellij", "${project.group}.shadow.intellij")
relocate("org.jetbrains", "${project.group}.shadow.jetbrains")
}
validatePlugins {
enableStricterValidation.set(true)
}
}

View File

@@ -0,0 +1,9 @@
plugins {
`gradle-kotlin-conventions`
}
dependencies {
compileOnly(libs.gradle.api.get69())
api(project(":model"))
implementation(libs.serialization.json)
}

View File

@@ -7,10 +7,8 @@ import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.api.invocation.Gradle
import org.gradle.internal.hash.ChecksumService
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
@@ -29,30 +27,11 @@ import org.nixos.gradle2nix.model.impl.DefaultResolvedDependency
import java.io.File
import java.util.concurrent.ConcurrentHashMap
internal abstract class DependencyExtractorService :
BuildService<BuildServiceParameters.None>, BuildOperationListener, AutoCloseable {
var extractor: DependencyExtractor? = null
override fun started(
buildOperation: BuildOperationDescriptor,
startEvent: OperationStartEvent,
) {}
override fun progress(
operationIdentifier: OperationIdentifier,
progressEvent: OperationProgressEvent,
) {}
override fun finished(
buildOperation: BuildOperationDescriptor,
finishEvent: OperationFinishEvent,
) {
extractor?.finished(buildOperation, finishEvent)
}
override fun close() {
extractor = null
}
interface DependencyExtractorApplier {
fun apply(
gradle: Gradle,
extractor: DependencyExtractor,
)
}
class DependencyExtractor : BuildOperationListener {
@@ -80,14 +59,14 @@ class DependencyExtractor : BuildOperationListener {
}
fun buildDependencySet(
artifactCachesProvider: ArtifactCachesProvider,
cacheAccess: GradleCacheAccess,
checksumService: ChecksumService,
fileStoreAndIndexProvider: FileStoreAndIndexProvider,
): DependencySet {
val files = mutableMapOf<DependencyCoordinates, MutableMap<File, String>>()
val mappings = mutableMapOf<DependencyCoordinates, Map<String, String>>()
artifactCachesProvider.writableCacheAccessCoordinator.useCache {
cacheAccess.useCache {
for ((url, _) in urls) {
fileStoreAndIndexProvider.externalResourceIndex.lookup(url)?.let { cached ->
cached.cachedFile?.let { file ->
@@ -131,6 +110,8 @@ class DependencyExtractor : BuildOperationListener {
}
}
private fun <T> buildList(block: MutableList<T>.() -> Unit): List<T> = mutableListOf<T>().apply(block).toList()
private fun cachedComponentId(file: File): DependencyCoordinates? {
val parts = file.invariantSeparatorsPath.split('/')
if (parts.size < 6) return null
@@ -148,7 +129,7 @@ private fun parseFileMappings(file: File): Map<String, String>? =
?.mapNotNull {
val name = it["name"]?.jsonPrimitive?.content ?: return@mapNotNull null
val url = it["url"]?.jsonPrimitive?.content ?: return@mapNotNull null
name to url
if (name != url) name to url else null
}
?.toMap()
?.takeUnless { it.isEmpty() }

View File

@@ -0,0 +1,27 @@
package org.nixos.gradle2nix
import org.gradle.api.Project
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.internal.hash.ChecksumService
import org.gradle.tooling.provider.model.ToolingModelBuilder
import org.nixos.gradle2nix.model.DependencySet
class DependencySetModelBuilder(
private val dependencyExtractor: DependencyExtractor,
private val cacheAccess: GradleCacheAccess,
private val checksumService: ChecksumService,
private val fileStoreAndIndexProvider: FileStoreAndIndexProvider,
) : ToolingModelBuilder {
override fun canBuild(modelName: String): Boolean = modelName == DependencySet::class.qualifiedName
override fun buildAll(
modelName: String,
project: Project,
): DependencySet {
return dependencyExtractor.buildDependencySet(
cacheAccess,
checksumService,
fileStoreAndIndexProvider,
)
}
}

View File

@@ -0,0 +1,32 @@
package org.nixos.gradle2nix
import org.gradle.api.Plugin
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.api.invocation.Gradle
import org.gradle.internal.hash.ChecksumService
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
abstract class AbstractGradle2NixPlugin(
private val cacheAccessFactory: GradleCacheAccessFactory,
private val dependencyExtractorApplier: DependencyExtractorApplier,
private val resolveAllArtifactsApplier: ResolveAllArtifactsApplier,
) : Plugin<Gradle> {
override fun apply(gradle: Gradle) {
val extractor = DependencyExtractor()
gradle.service<ToolingModelBuilderRegistry>().register(
DependencySetModelBuilder(
extractor,
cacheAccessFactory.create(gradle),
gradle.service<ChecksumService>(),
gradle.service<FileStoreAndIndexProvider>(),
),
)
dependencyExtractorApplier.apply(gradle, extractor)
gradle.projectsEvaluated {
resolveAllArtifactsApplier.apply(gradle)
}
}
}

View File

@@ -0,0 +1,11 @@
package org.nixos.gradle2nix
import org.gradle.api.invocation.Gradle
fun interface GradleCacheAccessFactory {
fun create(gradle: Gradle): GradleCacheAccess
}
interface GradleCacheAccess {
fun useCache(block: () -> Unit)
}

View File

@@ -0,0 +1,6 @@
package org.nixos.gradle2nix
import org.gradle.api.internal.GradleInternal
import org.gradle.api.invocation.Gradle
inline fun <reified T> Gradle.service(): T = (this as GradleInternal).services.get(T::class.java)

View File

@@ -0,0 +1,50 @@
package org.nixos.gradle2nix
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.invocation.Gradle
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskProvider
import org.gradle.internal.deprecation.DeprecatableConfiguration
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
fun interface ResolveAllArtifactsApplier {
fun apply(gradle: Gradle)
}
abstract class AbstractResolveAllArtifactsApplier : ResolveAllArtifactsApplier {
abstract fun Project.registerProjectTask(): TaskProvider<*>
final override fun apply(gradle: Gradle) {
val resolveAll = gradle.rootProject.tasks.register(RESOLVE_ALL_TASK)
// Depend on "dependencies" task in all projects
gradle.allprojects { project ->
val resolveProject = project.registerProjectTask()
resolveAll.configure { it.dependsOn(resolveProject) }
}
// Depend on all 'resolveBuildDependencies' task in each included build
gradle.includedBuilds.forEach { includedBuild ->
resolveAll.configure {
it.dependsOn(includedBuild.task(":$RESOLVE_ALL_TASK"))
}
}
}
}
abstract class ResolveProjectDependenciesTask : DefaultTask() {
@Internal
protected fun getReportableConfigurations(): List<Configuration> {
return project.configurations.filter { (it as? DeprecatableConfiguration)?.canSafelyBeResolved() ?: true }
}
protected fun Configuration.artifactFiles(): FileCollection {
return incoming.artifactView { viewConfiguration ->
viewConfiguration.componentFilter { it is ModuleComponentIdentifier }
}.files
}
}

View File

@@ -0,0 +1,8 @@
plugins {
`gradle-kotlin-conventions`
}
dependencies {
compileOnly(libs.gradle.api.get80())
api(project(":plugin:common"))
}

View File

@@ -0,0 +1,57 @@
package org.nixos.gradle2nix
import org.gradle.api.invocation.Gradle
import org.gradle.api.services.BuildService
import org.gradle.api.services.BuildServiceParameters
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
import org.gradle.internal.operations.OperationFinishEvent
import org.gradle.internal.operations.OperationIdentifier
import org.gradle.internal.operations.OperationProgressEvent
import org.gradle.internal.operations.OperationStartEvent
object DependencyExtractorApplierG8 : DependencyExtractorApplier {
@Suppress("UnstableApiUsage")
override fun apply(
gradle: Gradle,
extractor: DependencyExtractor,
) {
val serviceProvider =
gradle.sharedServices.registerIfAbsent(
"nixDependencyExtractor",
DependencyExtractorService::class.java,
) {}.map { service ->
service.apply { this.extractor = extractor }
}
gradle.service<BuildEventListenerRegistryInternal>().onOperationCompletion(serviceProvider)
}
}
@Suppress("UnstableApiUsage")
internal abstract class DependencyExtractorService :
BuildService<BuildServiceParameters.None>, BuildOperationListener, AutoCloseable {
var extractor: DependencyExtractor? = null
override fun started(
buildOperation: BuildOperationDescriptor,
startEvent: OperationStartEvent,
) {}
override fun progress(
operationIdentifier: OperationIdentifier,
progressEvent: OperationProgressEvent,
) {}
override fun finished(
buildOperation: BuildOperationDescriptor,
finishEvent: OperationFinishEvent,
) {
extractor?.finished(buildOperation, finishEvent)
}
override fun close() {
extractor = null
}
}

View File

@@ -0,0 +1,38 @@
package org.nixos.gradle2nix
import org.gradle.api.Project
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.internal.serialization.Cached
import org.gradle.work.DisableCachingByDefault
import org.nixos.gradle2nix.model.RESOLVE_PROJECT_TASK
import javax.inject.Inject
object ResolveAllArtifactsApplierG8 : AbstractResolveAllArtifactsApplier() {
override fun Project.registerProjectTask(): TaskProvider<*> =
tasks.register(RESOLVE_PROJECT_TASK, ResolveProjectDependenciesTaskG8::class.java)
}
@DisableCachingByDefault(because = "Not worth caching")
abstract class ResolveProjectDependenciesTaskG8
@Inject
constructor(
private val objects: ObjectFactory,
) : ResolveProjectDependenciesTask() {
private val artifactFiles = Cached.of { artifactFiles() }
private fun artifactFiles(): FileCollection {
return objects.fileCollection().from(
getReportableConfigurations().map { configuration ->
configuration.artifactFiles()
},
)
}
@TaskAction
fun action() {
artifactFiles.get().count()
}
}

View File

@@ -0,0 +1,12 @@
plugins {
`plugin-conventions`
}
dependencies {
implementation(project(":plugin:gradle8"))
compileOnly(libs.gradle.api.get80())
}
tasks.shadowJar {
archiveFileName = "plugin-gradle80.jar"
}

View File

@@ -0,0 +1,7 @@
package org.nixos.gradle2nix
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
GradleCacheAccessFactoryG80,
DependencyExtractorApplierG8,
ResolveAllArtifactsApplierG8,
)

View File

@@ -0,0 +1,18 @@
package org.nixos.gradle2nix
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.invocation.Gradle
object GradleCacheAccessFactoryG80 : GradleCacheAccessFactory {
override fun create(gradle: Gradle): GradleCacheAccess {
return GradleCacheAccessG80(gradle)
}
}
class GradleCacheAccessG80(gradle: Gradle) : GradleCacheAccess {
private val artifactCachesProvider = gradle.service<ArtifactCachesProvider>()
override fun useCache(block: () -> Unit) {
artifactCachesProvider.writableCacheLockingManager.useCache(block)
}
}

View File

@@ -0,0 +1,12 @@
plugins {
`plugin-conventions`
}
dependencies {
implementation(project(":plugin:gradle8"))
compileOnly(libs.gradle.api.get81())
}
tasks.shadowJar {
archiveFileName = "plugin-gradle81.jar"
}

View File

@@ -0,0 +1,7 @@
package org.nixos.gradle2nix
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
GradleCacheAccessFactoryG81,
DependencyExtractorApplierG8,
ResolveAllArtifactsApplierG8,
)

View File

@@ -0,0 +1,18 @@
package org.nixos.gradle2nix
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.invocation.Gradle
object GradleCacheAccessFactoryG81 : GradleCacheAccessFactory {
override fun create(gradle: Gradle): GradleCacheAccess {
return GradleCacheAccessG81(gradle)
}
}
class GradleCacheAccessG81(gradle: Gradle) : GradleCacheAccess {
private val artifactCachesProvider = gradle.service<ArtifactCachesProvider>()
override fun useCache(block: () -> Unit) {
artifactCachesProvider.writableCacheAccessCoordinator.useCache(block)
}
}

View File

@@ -1,93 +0,0 @@
@file:Suppress("UnstableApiUsage")
package org.nixos.gradle2nix
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.api.invocation.Gradle
import org.gradle.internal.hash.ChecksumService
import org.gradle.tooling.provider.model.ToolingModelBuilder
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.gradle.util.GradleVersion
import org.nixos.gradle2nix.model.DependencySet
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import javax.inject.Inject
@Suppress("UNUSED")
abstract class Gradle2NixPlugin
@Inject
constructor(
private val toolingModelBuilderRegistry: ToolingModelBuilderRegistry,
) : Plugin<Gradle> {
override fun apply(gradle: Gradle) {
val dependencyExtractor = DependencyExtractor()
toolingModelBuilderRegistry.register(
DependencySetModelBuilder(
dependencyExtractor,
gradle.artifactCachesProvider,
gradle.checksumService,
gradle.fileStoreAndIndexProvider,
),
)
if (GradleVersion.current() < GradleVersion.version("8.0")) {
val extractor = DependencyExtractor()
gradle.buildOperationListenerManager.addListener(extractor)
@Suppress("DEPRECATION")
gradle.buildFinished {
gradle.buildOperationListenerManager.removeListener(extractor)
}
} else {
val serviceProvider =
gradle.sharedServices.registerIfAbsent(
"nixDependencyExtractor",
DependencyExtractorService::class.java,
) {}.map { service ->
service.apply { extractor = dependencyExtractor }
}
gradle.buildEventListenerRegistryInternal.onOperationCompletion(serviceProvider)
}
gradle.projectsEvaluated {
val resolveAll = gradle.rootProject.tasks.register(RESOLVE_ALL_TASK)
// Depend on "dependencies" task in all projects
gradle.allprojects { project ->
val resolveProject = project.createResolveTask()
resolveAll.configure { it.dependsOn(resolveProject) }
}
// Depend on all 'resolveBuildDependencies' task in each included build
gradle.includedBuilds.forEach { includedBuild ->
resolveAll.configure {
it.dependsOn(includedBuild.task(":$RESOLVE_ALL_TASK"))
}
}
}
}
}
internal class DependencySetModelBuilder(
private val dependencyExtractor: DependencyExtractor,
private val artifactCachesProvider: ArtifactCachesProvider,
private val checksumService: ChecksumService,
private val fileStoreAndIndexProvider: FileStoreAndIndexProvider,
) : ToolingModelBuilder {
override fun canBuild(modelName: String): Boolean = modelName == DependencySet::class.qualifiedName
override fun buildAll(
modelName: String,
project: Project,
): DependencySet {
return dependencyExtractor.buildDependencySet(
artifactCachesProvider,
checksumService,
fileStoreAndIndexProvider,
)
}
}

View File

@@ -1,42 +0,0 @@
package org.nixos.gradle2nix
import org.gradle.api.artifacts.Configuration
import org.gradle.api.internal.GradleInternal
import org.gradle.api.internal.artifacts.ivyservice.ArtifactCachesProvider
import org.gradle.api.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
import org.gradle.api.invocation.Gradle
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
import org.gradle.internal.hash.ChecksumService
import org.gradle.internal.operations.BuildOperationListenerManager
import org.gradle.util.GradleVersion
import java.lang.reflect.Method
internal inline val Gradle.artifactCachesProvider: ArtifactCachesProvider
get() = service()
internal inline val Gradle.buildEventListenerRegistryInternal: BuildEventListenerRegistryInternal
get() = service()
internal inline val Gradle.buildOperationListenerManager: BuildOperationListenerManager
get() = service()
internal inline val Gradle.checksumService: ChecksumService
get() = service()
internal inline val Gradle.fileStoreAndIndexProvider: FileStoreAndIndexProvider
get() = service()
internal inline fun <reified T> Gradle.service(): T = (this as GradleInternal).services.get(T::class.java)
private val canSafelyBeResolvedMethod: Method? =
try {
val dc = Class.forName("org.gradle.internal.deprecation.DeprecatableConfiguration")
dc.getMethod("canSafelyBeResolved")
} catch (e: ReflectiveOperationException) {
null
}
internal fun Configuration.canSafelyBeResolved(): Boolean = canSafelyBeResolvedMethod?.invoke(this) as? Boolean ?: isCanBeResolved
internal val gradleVersionIsAtLeast8: Boolean =
GradleVersion.current() >= GradleVersion.version("8.0")

View File

@@ -1,66 +0,0 @@
package org.nixos.gradle2nix
import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskProvider
import org.gradle.internal.serialization.Cached
import org.gradle.work.DisableCachingByDefault
import org.nixos.gradle2nix.model.RESOLVE_PROJECT_TASK
import javax.inject.Inject
internal fun Project.createResolveTask(): TaskProvider<out Task> {
return if (gradleVersionIsAtLeast8) {
tasks.register(RESOLVE_PROJECT_TASK, ResolveProjectDependenciesTask::class.java)
} else {
tasks.register(RESOLVE_PROJECT_TASK, LegacyResolveProjectDependenciesTask::class.java)
}
}
@DisableCachingByDefault(because = "Not worth caching")
sealed class AbstractResolveProjectDependenciesTask : DefaultTask() {
@Internal
protected fun getReportableConfigurations(): List<Configuration> {
return project.configurations.filter { it.canSafelyBeResolved() }
}
}
@DisableCachingByDefault(because = "Not worth caching")
abstract class LegacyResolveProjectDependenciesTask : AbstractResolveProjectDependenciesTask() {
@TaskAction
fun action() {
for (configuration in getReportableConfigurations()) {
configuration.incoming.resolutionResult.root
}
}
}
@DisableCachingByDefault(because = "Not worth caching")
abstract class ResolveProjectDependenciesTask
@Inject
constructor(
private val objects: ObjectFactory,
) : AbstractResolveProjectDependenciesTask() {
private val artifactFiles = Cached.of { artifactFiles() }
private fun artifactFiles(): FileCollection {
return objects.fileCollection().from(
getReportableConfigurations().map { configuration ->
configuration.incoming.artifactView { viewConfiguration ->
viewConfiguration.componentFilter { it is ModuleComponentIdentifier }
}.files
},
)
}
@TaskAction
fun action() {
artifactFiles.get().count()
}
}