mirror of
https://github.com/tadfisher/gradle2nix.git
synced 2026-01-11 23:40:37 -05:00
Separate plugins for different Gradle APIs
This commit is contained in:
12
plugin/base/build.gradle.kts
Normal file
12
plugin/base/build.gradle.kts
Normal file
@@ -0,0 +1,12 @@
|
||||
plugins {
|
||||
`plugin-conventions`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":plugin:common"))
|
||||
compileOnly(libs.gradle.api.get69())
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
archiveFileName = "plugin-base.jar"
|
||||
}
|
||||
18
plugin/base/src/main/kotlin/DependencyExtractor.base.kt
Normal file
18
plugin/base/src/main/kotlin/DependencyExtractor.base.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
7
plugin/base/src/main/kotlin/Gradle2NixPlugin.gradle69.kt
Normal file
7
plugin/base/src/main/kotlin/Gradle2NixPlugin.gradle69.kt
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
|
||||
GradleCacheAccessFactoryBase,
|
||||
DependencyExtractorApplierBase,
|
||||
ResolveAllArtifactsApplierBase,
|
||||
)
|
||||
18
plugin/base/src/main/kotlin/GradleCacheAccess.gradle69.kt
Normal file
18
plugin/base/src/main/kotlin/GradleCacheAccess.gradle69.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
20
plugin/base/src/main/kotlin/ResolveAllArtifacts.gradle69.kt
Normal file
20
plugin/base/src/main/kotlin/ResolveAllArtifacts.gradle69.kt
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
9
plugin/common/build.gradle.kts
Normal file
9
plugin/common/build.gradle.kts
Normal file
@@ -0,0 +1,9 @@
|
||||
plugins {
|
||||
`gradle-kotlin-conventions`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.gradle.api.get69())
|
||||
api(project(":model"))
|
||||
implementation(libs.serialization.json)
|
||||
}
|
||||
@@ -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() }
|
||||
27
plugin/common/src/main/kotlin/DependencySetModelBuilder.kt
Normal file
27
plugin/common/src/main/kotlin/DependencySetModelBuilder.kt
Normal 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
32
plugin/common/src/main/kotlin/Gradle2NixPlugin.kt
Normal file
32
plugin/common/src/main/kotlin/Gradle2NixPlugin.kt
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
11
plugin/common/src/main/kotlin/GradleCacheAccess.kt
Normal file
11
plugin/common/src/main/kotlin/GradleCacheAccess.kt
Normal 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)
|
||||
}
|
||||
6
plugin/common/src/main/kotlin/GradleExtensions.kt
Normal file
6
plugin/common/src/main/kotlin/GradleExtensions.kt
Normal 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)
|
||||
50
plugin/common/src/main/kotlin/ResolveAllArtifacts.kt
Normal file
50
plugin/common/src/main/kotlin/ResolveAllArtifacts.kt
Normal 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
|
||||
}
|
||||
}
|
||||
8
plugin/gradle8/build.gradle.kts
Normal file
8
plugin/gradle8/build.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
||||
plugins {
|
||||
`gradle-kotlin-conventions`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly(libs.gradle.api.get80())
|
||||
api(project(":plugin:common"))
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
12
plugin/gradle80/build.gradle.kts
Normal file
12
plugin/gradle80/build.gradle.kts
Normal file
@@ -0,0 +1,12 @@
|
||||
plugins {
|
||||
`plugin-conventions`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":plugin:gradle8"))
|
||||
compileOnly(libs.gradle.api.get80())
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
archiveFileName = "plugin-gradle80.jar"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
|
||||
GradleCacheAccessFactoryG80,
|
||||
DependencyExtractorApplierG8,
|
||||
ResolveAllArtifactsApplierG8,
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
12
plugin/gradle81/build.gradle.kts
Normal file
12
plugin/gradle81/build.gradle.kts
Normal file
@@ -0,0 +1,12 @@
|
||||
plugins {
|
||||
`plugin-conventions`
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":plugin:gradle8"))
|
||||
compileOnly(libs.gradle.api.get81())
|
||||
}
|
||||
|
||||
tasks.shadowJar {
|
||||
archiveFileName = "plugin-gradle81.jar"
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
abstract class Gradle2NixPlugin : AbstractGradle2NixPlugin(
|
||||
GradleCacheAccessFactoryG81,
|
||||
DependencyExtractorApplierG8,
|
||||
ResolveAllArtifactsApplierG8,
|
||||
)
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -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")
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user