mirror of
https://github.com/tadfisher/gradle2nix.git
synced 2026-01-12 07:50:53 -05:00
Separate plugins for different Gradle APIs
This commit is contained in:
@@ -16,4 +16,5 @@ ktlint_function_naming_ignore_when_annotated_with = [unset]
|
|||||||
ktlint_function_signature_body_expression_wrapping = multiline
|
ktlint_function_signature_body_expression_wrapping = multiline
|
||||||
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2
|
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2
|
||||||
ktlint_ignore_back_ticked_identifier = false
|
ktlint_ignore_back_ticked_identifier = false
|
||||||
|
ktlint_standard_filename = disabled
|
||||||
max_line_length = 140
|
max_line_length = 140
|
||||||
|
|||||||
@@ -12,13 +12,14 @@ dependencies {
|
|||||||
implementation(project(":model"))
|
implementation(project(":model"))
|
||||||
implementation(libs.clikt)
|
implementation(libs.clikt)
|
||||||
implementation(libs.gradle.toolingApi)
|
implementation(libs.gradle.toolingApi)
|
||||||
|
implementation(libs.kotlin.stdlib)
|
||||||
implementation(libs.kotlinx.coroutines.core)
|
implementation(libs.kotlinx.coroutines.core)
|
||||||
implementation(libs.serialization.json)
|
implementation(libs.serialization.json)
|
||||||
runtimeOnly(libs.slf4j.simple)
|
runtimeOnly(libs.slf4j.simple)
|
||||||
|
|
||||||
"share"(project(":plugin", configuration = "shadow")) {
|
"share"(project(":plugin:base", configuration = "shadow"))
|
||||||
isTransitive = false
|
"share"(project(":plugin:gradle80", configuration = "shadow"))
|
||||||
}
|
"share"(project(":plugin:gradle81", configuration = "shadow"))
|
||||||
|
|
||||||
testImplementation(libs.kotest.assertions)
|
testImplementation(libs.kotest.assertions)
|
||||||
testImplementation(libs.kotest.runner)
|
testImplementation(libs.kotest.runner)
|
||||||
@@ -37,7 +38,6 @@ application {
|
|||||||
applicationDistribution
|
applicationDistribution
|
||||||
.from(configurations.named("share"))
|
.from(configurations.named("share"))
|
||||||
.into("share")
|
.into("share")
|
||||||
.rename("plugin.*\\.jar", "plugin.jar")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
|
|||||||
10
app/src/dist/share/init.gradle
vendored
10
app/src/dist/share/init.gradle
vendored
@@ -1,6 +1,14 @@
|
|||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
|
||||||
initscript {
|
initscript {
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath files("plugin.jar")
|
if (GradleVersion.current() >= GradleVersion.version("8.1")) {
|
||||||
|
classpath files("plugin-gradle81.jar")
|
||||||
|
} else if (GradleVersion.current() >= GradleVersion.version("8.0")) {
|
||||||
|
classpath files("plugin-gradle80.jar")
|
||||||
|
} else {
|
||||||
|
classpath files("plugin-base.jar")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
base
|
base
|
||||||
alias(libs.plugins.kotlin.jvm) apply false
|
|
||||||
alias(libs.plugins.kotlin.serialization) apply false
|
alias(libs.plugins.kotlin.serialization) apply false
|
||||||
alias(libs.plugins.pluginPublish) apply false
|
|
||||||
alias(libs.plugins.shadow) apply false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "org.nixos.gradle2nix"
|
group = "org.nixos.gradle2nix"
|
||||||
|
|||||||
8
buildSrc/build.gradle.kts
Normal file
8
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
plugins {
|
||||||
|
`kotlin-dsl`
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation(libs.gradle.kotlin)
|
||||||
|
implementation(libs.gradle.shadow)
|
||||||
|
}
|
||||||
14
buildSrc/settings.gradle.kts
Normal file
14
buildSrc/settings.gradle.kts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
|
dependencyResolutionManagement {
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
gradlePluginPortal()
|
||||||
|
}
|
||||||
|
|
||||||
|
versionCatalogs {
|
||||||
|
register("libs") {
|
||||||
|
from(files("../gradle/libs.versions.toml"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("org.jetbrains.kotlin.jvm")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(kotlin("stdlib"))
|
||||||
|
}
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.compilerOptions {
|
||||||
|
@Suppress("DEPRECATION") // we can't use api version greater than 1.4 as minimal supported Gradle version uses kotlin-stdlib 1.4
|
||||||
|
apiVersion.set(KotlinVersion.KOTLIN_1_4)
|
||||||
|
@Suppress("DEPRECATION") // we can't use language version greater than 1.5 as minimal supported Gradle embeds Kotlin 1.4
|
||||||
|
languageVersion.set(KotlinVersion.KOTLIN_1_5)
|
||||||
|
jvmTarget.set(JvmTarget.JVM_1_8)
|
||||||
|
optIn.add("kotlin.RequiresOptIn")
|
||||||
|
freeCompilerArgs.addAll(
|
||||||
|
listOf(
|
||||||
|
"-Xskip-prerelease-check",
|
||||||
|
"-Xsuppress-version-warnings",
|
||||||
|
// We have to override the default value for `-Xsam-conversions` to `class`
|
||||||
|
// otherwise the compiler would compile lambdas using invokedynamic,
|
||||||
|
// such lambdas are not serializable so are not compatible with Gradle configuration cache.
|
||||||
|
// It doesn't lead to a significant difference in binaries sizes, and previously (before LV 1.5) the `class` value was set by default.
|
||||||
|
"-Xsam-conversions=class",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
60
buildSrc/src/main/kotlin/plugin-conventions.gradle.kts
Normal file
60
buildSrc/src/main/kotlin/plugin-conventions.gradle.kts
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
@file:Suppress("UnstableApiUsage")
|
||||||
|
|
||||||
|
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
id("gradle-kotlin-conventions")
|
||||||
|
id("io.github.goooler.shadow")
|
||||||
|
`java-gradle-plugin`
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
}
|
||||||
|
|
||||||
|
configure<GradlePluginDevelopmentExtension> {
|
||||||
|
plugins {
|
||||||
|
register("gradle2nix") {
|
||||||
|
id = "org.nixos.gradle2nix"
|
||||||
|
displayName = "gradle2nix"
|
||||||
|
description = "Expose Gradle tooling model for the gradle2nix tool"
|
||||||
|
implementationClass = "org.nixos.gradle2nix.Gradle2NixPlugin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
"api" {
|
||||||
|
dependencies.remove(project.dependencies.gradleApi())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
"jar" {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
named("shadowJar", ShadowJar::class) {
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
|
isPreserveFileTimestamps = false
|
||||||
|
isReproducibleFileOrder = true
|
||||||
|
val mode644 = 0b110100100
|
||||||
|
val mode755 = 0b111101101
|
||||||
|
fileMode = mode644
|
||||||
|
dirMode = mode755
|
||||||
|
filesMatching("**/bin/*") { mode = mode755 }
|
||||||
|
filesMatching("**/bin/*.bat") { mode = mode644 }
|
||||||
|
|
||||||
|
relocate("kotlinx", "${project.group}.shadow.kotlinx")
|
||||||
|
relocate("org.intellij", "${project.group}.shadow.intellij")
|
||||||
|
relocate("org.jetbrains", "${project.group}.shadow.jetbrains")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-stdlib" }
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-stdlib-common" }
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-stdlib-jdk7" }
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-stdlib-jdk8" }
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-reflect" }
|
||||||
|
exclude { it.moduleGroup == "org.jetbrains.kotlin" && it.moduleName == "kotlin-script-runtime" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
formatter = pkgs.writeShellScriptBin "gradle2nix-fmt" ''
|
formatter = pkgs.writeShellScriptBin "gradle2nix-fmt" ''
|
||||||
fail=0
|
fail=0
|
||||||
${lib.getExe pkgs.nixfmt-rfc-style} $@ || fail=1
|
${lib.getExe pkgs.nixfmt-rfc-style} $@ || fail=1
|
||||||
${lib.getExe pkgs.ktlint} --relative -l warn -F || fail=1
|
${lib.getExe pkgs.git} ls-files -z '*.kt' '*.kts' | ${lib.getExe pkgs.ktlint} --relative -l warn -F --patterns-from-stdin= || fail=1
|
||||||
[ $fail -eq 0 ] || echo "Formatting failed." >&2
|
[ $fail -eq 0 ] || echo "Formatting failed." >&2
|
||||||
exit $fail
|
exit $fail
|
||||||
'';
|
'';
|
||||||
|
|||||||
3162
gradle-env.json
3162
gradle-env.json
File diff suppressed because it is too large
Load Diff
1200
gradle.lock
1200
gradle.lock
File diff suppressed because it is too large
Load Diff
@@ -1,3 +1,4 @@
|
|||||||
|
kotlin.stdlib.default.dependency=false
|
||||||
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
|
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.configuration-cache=true
|
org.gradle.configuration-cache=true
|
||||||
|
|||||||
@@ -1,27 +1,34 @@
|
|||||||
[versions]
|
[versions]
|
||||||
gradle = "8.7"
|
gradle = "8.7"
|
||||||
junit = "5.8.2"
|
junit = "5.8.2"
|
||||||
kotlin = "1.9.24"
|
# Intentionally using the version embedded in Gradle to reduce dependency count
|
||||||
|
# See https://docs.gradle.org/current/userguide/compatibility.html#kotlin
|
||||||
|
kotlin = { strictly = "1.9.22" }
|
||||||
ktor = "2.3.11"
|
ktor = "2.3.11"
|
||||||
kotest = "5.9.0"
|
kotest = "5.9.0"
|
||||||
|
shadow = "8.1.7"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
clikt = "com.github.ajalt.clikt:clikt:4.4.0"
|
clikt = "com.github.ajalt.clikt:clikt:4.4.0"
|
||||||
|
gradle-api-69 = "dev.gradleplugins:gradle-api:6.9"
|
||||||
|
gradle-api-80 = "dev.gradleplugins:gradle-api:8.0"
|
||||||
|
gradle-api-81 = "dev.gradleplugins:gradle-api:8.1"
|
||||||
|
gradle-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
|
||||||
|
gradle-shadow = { module = "io.github.goooler.shadow:shadow-gradle-plugin", version.ref = "shadow" }
|
||||||
gradle-toolingApi = { module = "org.gradle:gradle-tooling-api", version.ref = "gradle" }
|
gradle-toolingApi = { module = "org.gradle:gradle-tooling-api", version.ref = "gradle" }
|
||||||
kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
|
kotest-assertions = { module = "io.kotest:kotest-assertions-core", version.ref = "kotest" }
|
||||||
kotest-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
|
kotest-runner = { module = "io.kotest:kotest-runner-junit5", version.ref = "kotest" }
|
||||||
|
kotlin-stdlib = { module = "org.jetbrains.kotlin:kotlin-stdlib", version.ref = "kotlin" }
|
||||||
kotlinx-coroutines-core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1"
|
kotlinx-coroutines-core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.1"
|
||||||
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
|
ktor-server-core = { module = "io.ktor:ktor-server-core", version.ref = "ktor" }
|
||||||
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
|
ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor" }
|
||||||
okio = "com.squareup.okio:okio:3.9.0"
|
okio = "com.squareup.okio:okio:3.9.0"
|
||||||
serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
|
serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
|
||||||
slf4j-simple = "org.slf4j:slf4j-simple:1.7.36"
|
slf4j-simple = "org.slf4j:slf4j-simple:1.7.36"
|
||||||
xmlutil = "io.github.pdvrieze.xmlutil:serialization-jvm:0.90.0-RC1"
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
pluginPublish = { id = "com.gradle.plugin-publish", version = "1.2.1" }
|
|
||||||
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||||
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
|
||||||
shadow = { id = "com.github.johnrengelman.shadow", version = "8.1.1" }
|
shadow = { id = "io.github.goooler.shadow", version.ref = "shadow" }
|
||||||
|
|
||||||
[bundles]
|
[bundles]
|
||||||
|
|||||||
@@ -1,16 +1,34 @@
|
|||||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("org.jetbrains.kotlin.jvm")
|
id("org.jetbrains.kotlin.jvm")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
compileOnly(libs.kotlin.stdlib)
|
||||||
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
targetCompatibility = JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin.compilerOptions {
|
||||||
compilerOptions {
|
@Suppress("DEPRECATION") // we can't use api version greater than 1.4 as minimal supported Gradle version uses kotlin-stdlib 1.4
|
||||||
|
apiVersion.set(KotlinVersion.KOTLIN_1_4)
|
||||||
|
@Suppress("DEPRECATION") // we can't use language version greater than 1.5 as minimal supported Gradle embeds Kotlin 1.4
|
||||||
|
languageVersion.set(KotlinVersion.KOTLIN_1_5)
|
||||||
jvmTarget.set(JvmTarget.JVM_1_8)
|
jvmTarget.set(JvmTarget.JVM_1_8)
|
||||||
}
|
freeCompilerArgs.addAll(
|
||||||
|
listOf(
|
||||||
|
"-Xskip-prerelease-check",
|
||||||
|
"-Xsuppress-version-warnings",
|
||||||
|
// We have to override the default value for `-Xsam-conversions` to `class`
|
||||||
|
// otherwise the compiler would compile lambdas using invokedynamic,
|
||||||
|
// such lambdas are not serializable so are not compatible with Gradle configuration cache.
|
||||||
|
// It doesn't lead to a significant difference in binaries sizes, and previously (before LV 1.5) the `class` value was set by default.
|
||||||
|
"-Xsam-conversions=class",
|
||||||
|
),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
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.jsonArray
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
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.internal.artifacts.ivyservice.modulecache.FileStoreAndIndexProvider
|
||||||
import org.gradle.api.services.BuildService
|
import org.gradle.api.invocation.Gradle
|
||||||
import org.gradle.api.services.BuildServiceParameters
|
|
||||||
import org.gradle.internal.hash.ChecksumService
|
import org.gradle.internal.hash.ChecksumService
|
||||||
import org.gradle.internal.operations.BuildOperationDescriptor
|
import org.gradle.internal.operations.BuildOperationDescriptor
|
||||||
import org.gradle.internal.operations.BuildOperationListener
|
import org.gradle.internal.operations.BuildOperationListener
|
||||||
@@ -29,30 +27,11 @@ import org.nixos.gradle2nix.model.impl.DefaultResolvedDependency
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
internal abstract class DependencyExtractorService :
|
interface DependencyExtractorApplier {
|
||||||
BuildService<BuildServiceParameters.None>, BuildOperationListener, AutoCloseable {
|
fun apply(
|
||||||
var extractor: DependencyExtractor? = null
|
gradle: Gradle,
|
||||||
|
extractor: DependencyExtractor,
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class DependencyExtractor : BuildOperationListener {
|
class DependencyExtractor : BuildOperationListener {
|
||||||
@@ -80,14 +59,14 @@ class DependencyExtractor : BuildOperationListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun buildDependencySet(
|
fun buildDependencySet(
|
||||||
artifactCachesProvider: ArtifactCachesProvider,
|
cacheAccess: GradleCacheAccess,
|
||||||
checksumService: ChecksumService,
|
checksumService: ChecksumService,
|
||||||
fileStoreAndIndexProvider: FileStoreAndIndexProvider,
|
fileStoreAndIndexProvider: FileStoreAndIndexProvider,
|
||||||
): DependencySet {
|
): DependencySet {
|
||||||
val files = mutableMapOf<DependencyCoordinates, MutableMap<File, String>>()
|
val files = mutableMapOf<DependencyCoordinates, MutableMap<File, String>>()
|
||||||
val mappings = mutableMapOf<DependencyCoordinates, Map<String, String>>()
|
val mappings = mutableMapOf<DependencyCoordinates, Map<String, String>>()
|
||||||
|
|
||||||
artifactCachesProvider.writableCacheAccessCoordinator.useCache {
|
cacheAccess.useCache {
|
||||||
for ((url, _) in urls) {
|
for ((url, _) in urls) {
|
||||||
fileStoreAndIndexProvider.externalResourceIndex.lookup(url)?.let { cached ->
|
fileStoreAndIndexProvider.externalResourceIndex.lookup(url)?.let { cached ->
|
||||||
cached.cachedFile?.let { file ->
|
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? {
|
private fun cachedComponentId(file: File): DependencyCoordinates? {
|
||||||
val parts = file.invariantSeparatorsPath.split('/')
|
val parts = file.invariantSeparatorsPath.split('/')
|
||||||
if (parts.size < 6) return null
|
if (parts.size < 6) return null
|
||||||
@@ -148,7 +129,7 @@ private fun parseFileMappings(file: File): Map<String, String>? =
|
|||||||
?.mapNotNull {
|
?.mapNotNull {
|
||||||
val name = it["name"]?.jsonPrimitive?.content ?: return@mapNotNull null
|
val name = it["name"]?.jsonPrimitive?.content ?: return@mapNotNull null
|
||||||
val url = it["url"]?.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()
|
?.toMap()
|
||||||
?.takeUnless { it.isEmpty() }
|
?.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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -11,5 +11,9 @@ dependencyResolutionManagement {
|
|||||||
include(
|
include(
|
||||||
":app",
|
":app",
|
||||||
":model",
|
":model",
|
||||||
":plugin",
|
":plugin:base",
|
||||||
|
":plugin:common",
|
||||||
|
":plugin:gradle8",
|
||||||
|
":plugin:gradle80",
|
||||||
|
":plugin:gradle81",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user