Miscellaneous cleanup

This commit is contained in:
Tad Fisher
2024-05-29 17:47:31 -07:00
parent d13b7b0d6d
commit 301c64fa2f
46 changed files with 1512 additions and 1441 deletions

19
.editorconfig Normal file
View File

@@ -0,0 +1,19 @@
[*.{kt,kts}]
end_of_line = lf
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^
ij_kotlin_line_break_after_multiline_when_entry = true
ij_kotlin_packages_to_use_import_on_demand = unset
indent_size = 4
indent_style = space
insert_final_newline = true
ktlint_argument_list_wrapping_ignore_when_parameter_count_greater_or_equal_than = unset
ktlint_chain_method_rule_force_multiline_when_chain_operator_count_greater_or_equal_than = unset
ktlint_class_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 1
ktlint_code_style = ktlint_official
ktlint_function_naming_ignore_when_annotated_with = [unset]
ktlint_function_signature_body_expression_wrapping = multiline
ktlint_function_signature_rule_force_multiline_when_parameter_count_greater_or_equal_than = 2
ktlint_ignore_back_ticked_identifier = false
max_line_length = 140

View File

@@ -4,6 +4,19 @@
Generate [[https://nixos.org/nix/][Nix]] expressions which build [[https://gradle.org/][Gradle]]-based projects.
** Table of contents
#+BEGIN_QUOTE
- [[#why][Why?]]
- [[#installation][Installation]]
- [[#flake][Flake]]
- [[#usage][Usage]]
- [[#for-packagers][For packagers]]
- [[#specifying-the-gradle-installation][Specifying the Gradle installation]]
- [[#contributing][Contributing]]
- [[#license][License]]
#+END_QUOTE
** Why?
Nix is an OS-agnostic package manager, a language-agnostic build
@@ -80,7 +93,25 @@ nix-env -if "https://github.com/tadfisher/gradle2nix/archive/master.tar.gz"
=gradle2nix= is not yet packaged in =nixpkgs= itself, but work is
[[https://github.com/NixOS/nixpkgs/pull/77422][in progress]].
*** Flake (experimental)
The [[./gradle.nix][buildGradlePackage]] function is provided via the
=gradle2nix.passthru.buildGradlePackage= attribute.
#+begin_src nix
{ pkgs ? import <nixpkgs> {} }:
let
gradle2nix = import (fetchTarball "https://github.com/tadfisher/gradle2nix/archive/master.tar.gz") {}
in
gradle2nix.buildGradlePackage {
pname = "my-package";
version = "1.0";
lockFile = ./gradle.lock;
gradleFlags = [ "installDist" ];
# ...
}
#+end_src
*** Flake
A [[./flake.nix][flake.nix]] is provided for those using [[https://nixos.wiki/wiki/Flakes][Nix flakes]]. For example, the
following will build and run =gradle2nix= with the arguments provided
@@ -90,6 +121,26 @@ after =--=:
nix run github:tadfisher/gradle2nix -- --help
#+end_example
The [[./gradle.nix][buildGradlePackage]] function is provided via the
=builders= output.
#+begin_src nix
{
inputs.gradle2nix.url = "github:tadfisher/gradle2nix";
outputs = { self, gradle2nix }: {
packages.x86_64-linux.default = gradle2nix.builders.x86_64-linux.buildGradlePackage {
pname = "my-package";
version = "1.0";
lockFile = ./gradle.lock;
gradleFlags = [ "installDist" ];
# ...
};
};
}
#+end_src
** Usage
#+begin_example
@@ -100,7 +151,7 @@ Gradle installation:
Where to find Gradle. By default, use the project's wrapper.
--gradle-dist=<uri> Gradle distribution URI
--gradle-home=<dir> Gradle home path (e.g. `nix eval nixpkgs#gradle.outPath`/lib/gradle)
--gradle-home=<dir> Gradle home path (e.g. `nix eval --raw nixpkgs#gradle.outPath`/lib/gradle)
--gradle-wrapper=<value> Gradle wrapper version
Options:
@@ -108,9 +159,8 @@ Options:
-p, --project=<path> Path to the project root (default: Current directory)
-o, --out-dir=<dir> Path to write generated files (default: <project>)
-l, --lock-file=<filename> Name of the generated lock file (default: gradle.lock)
-n, --nix-file=<filename> Name of the generated Nix file (default: gradle.nix)
-j, --gradle-jdk=<dir> JDK home to use for launching Gradle (e.g. nix eval nixpkgs#openjdk.home)
--log=(debug|info|warn|error) Print messages with this priority or higher (default: error)
-j, --gradle-jdk=<dir> JDK home to use for launching Gradle (e.g. `nix eval --raw nixpkgs#openjdk.home`)
--log=(debug|info|warn|error) Print messages with this priority or higher (default: info)
--dump-events Dump Gradle event logs to the output directory
--stacktrace Print a stack trace on error
-h, --help Show this message and exit
@@ -169,8 +219,8 @@ Bug reports and feature requests are encouraged.
Code contributions are also encouraged. Please review the test cases
in the [[./fixtures][fixtures]] directory and create a new one to reproduce any fixes
or test new features. See the [[./plugin/src/compatTest/kotlin/org/nixos/gradle2nix][existing compatibility tests]] for
examples of testing with these fixtures.
or test new features. See the [[./app/src/test/kotlin/org/nixos/gradle2nix/GoldenTest.kt][existing tests]]
for examples of testing with these fixtures.
** License

View File

@@ -11,10 +11,8 @@ dependencies {
implementation(libs.clikt)
implementation(libs.gradle.toolingApi)
implementation(libs.kotlinx.coroutines.core)
implementation(libs.okio)
implementation(libs.serialization.json)
runtimeOnly(libs.slf4j.simple)
implementation(libs.xmlutil)
"share"(project(":plugin", configuration = "shadow")) {
isTransitive = false
@@ -29,12 +27,13 @@ dependencies {
application {
mainClass.set("org.nixos.gradle2nix.MainKt")
applicationName = "gradle2nix"
applicationDefaultJvmArgs = listOf(
"-Dorg.nixos.gradle2nix.share=@APP_HOME@/share",
"-Dslf4j.internal.verbosity=ERROR"
)
applicationDefaultJvmArgs =
listOf(
"-Dorg.nixos.gradle2nix.share=@APP_HOME@/share",
"-Dslf4j.internal.verbosity=ERROR",
)
applicationDistribution
.from(configurations.named("share"), files("../gradle.nix"))
.from(configurations.named("share"))
.into("share")
.rename("plugin.*\\.jar", "plugin.jar")
}
@@ -51,32 +50,31 @@ val updateGolden = providers.gradleProperty("update-golden")
tasks {
(run) {
dependsOn(installDist)
doFirst {
systemProperties("org.nixos.gradle2nix.share" to installDist.get().destinationDir.resolve("share"))
}
enabled = false
}
startScripts {
doLast {
unixScript.writeText(
unixScript.readText().replace("@APP_HOME@", "'\$APP_HOME'")
unixScript.readText().replace("@APP_HOME@", "'\$APP_HOME'"),
)
windowsScript.writeText(
windowsScript.readText().replace("@APP_HOME@", "%APP_HOME%"))
windowsScript.readText().replace("@APP_HOME@", "%APP_HOME%"),
)
}
}
withType<Test> {
notCompatibleWithConfigurationCache("huh?")
dependsOn(installDist)
// TODO Find out why this fails the configuration cache
test {
notCompatibleWithConfigurationCache("contains a Task reference")
val shareDir = layout.dir(installDist.map { it.destinationDir.resolve("share") })
doFirst {
if (updateGolden.isPresent) {
systemProperty("org.nixos.gradle2nix.update-golden", "")
}
systemProperties(
"org.nixos.gradle2nix.share" to installDist.get().destinationDir.resolve("share"),
"org.nixos.gradle2nix.m2" to "http://0.0.0.0:8989/m2"
"org.nixos.gradle2nix.share" to shareDir.get().asFile,
"org.nixos.gradle2nix.m2" to "http://0.0.0.0:8989/m2",
)
}
useJUnitPlatform()

View File

@@ -1,9 +1,5 @@
package org.nixos.gradle2nix
import java.io.File
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.io.path.absolutePathString
import kotlinx.coroutines.suspendCancellableCoroutine
import org.gradle.tooling.GradleConnectionException
import org.gradle.tooling.GradleConnector
@@ -12,8 +8,15 @@ import org.gradle.tooling.ResultHandler
import org.gradle.tooling.model.gradle.GradleBuild
import org.nixos.gradle2nix.model.DependencySet
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import java.io.File
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.io.path.absolutePathString
fun connect(config: Config, projectDir: File = config.projectDir): ProjectConnection =
fun connect(
config: Config,
projectDir: File = config.projectDir,
): ProjectConnection =
GradleConnector.newConnector()
.apply {
when (val source = config.gradleSource) {
@@ -26,70 +29,75 @@ fun connect(config: Config, projectDir: File = config.projectDir): ProjectConnec
.forProjectDirectory(projectDir)
.connect()
suspend fun ProjectConnection.buildModel(): GradleBuild = suspendCancellableCoroutine { continuation ->
val cancellationTokenSource = GradleConnector.newCancellationTokenSource()
suspend fun ProjectConnection.buildModel(): GradleBuild =
suspendCancellableCoroutine { continuation ->
val cancellationTokenSource = GradleConnector.newCancellationTokenSource()
continuation.invokeOnCancellation { cancellationTokenSource.cancel() }
continuation.invokeOnCancellation { cancellationTokenSource.cancel() }
action { controller -> controller.buildModel }
.withCancellationToken(cancellationTokenSource.token())
.run(object : ResultHandler<GradleBuild> {
override fun onComplete(result: GradleBuild) {
continuation.resume(result)
action { controller -> controller.buildModel }
.withCancellationToken(cancellationTokenSource.token())
.run(
object : ResultHandler<GradleBuild> {
override fun onComplete(result: GradleBuild) {
continuation.resume(result)
}
override fun onFailure(failure: GradleConnectionException) {
continuation.resumeWithException(failure)
}
},
)
}
suspend fun ProjectConnection.build(config: Config): DependencySet =
suspendCancellableCoroutine { continuation ->
val cancellationTokenSource = GradleConnector.newCancellationTokenSource()
continuation.invokeOnCancellation { cancellationTokenSource.cancel() }
action { controller -> controller.getModel(DependencySet::class.java) }
.withCancellationToken(cancellationTokenSource.token())
.apply {
if (config.tasks.isNotEmpty()) {
forTasks(*config.tasks.toTypedArray())
} else {
forTasks(RESOLVE_ALL_TASK)
}
}
override fun onFailure(failure: GradleConnectionException) {
continuation.resumeWithException(failure)
}
})
}
suspend fun ProjectConnection.build(config: Config): DependencySet = suspendCancellableCoroutine { continuation ->
val cancellationTokenSource = GradleConnector.newCancellationTokenSource()
continuation.invokeOnCancellation { cancellationTokenSource.cancel() }
action { controller -> controller.getModel(DependencySet::class.java) }
.withCancellationToken(cancellationTokenSource.token())
.apply {
if (config.tasks.isNotEmpty()) {
forTasks(*config.tasks.toTypedArray())
} else {
forTasks(RESOLVE_ALL_TASK)
}
}
.setJavaHome(config.gradleJdk)
.addArguments(config.gradleArgs)
.addArguments(
"--no-parallel",
"--refresh-dependencies",
"--gradle-user-home=${config.gradleHome}",
"--init-script=${config.appHome}/init.gradle",
)
.apply {
if (config.logger.stacktrace) {
addArguments("--stacktrace")
}
if (config.logger.logLevel < LogLevel.error) {
setStandardOutput(System.err)
setStandardError(System.err)
}
if (config.dumpEvents) {
withSystemProperties(
mapOf(
"org.gradle.internal.operations.trace" to
config.outDir.toPath().resolve("debug").absolutePathString()
.setJavaHome(config.gradleJdk)
.addArguments(config.gradleArgs)
.addArguments(
"--refresh-dependencies",
"--gradle-user-home=${config.gradleHome}",
"--init-script=${config.appHome}/init.gradle",
)
.apply {
if (config.logger.stacktrace) {
addArguments("--stacktrace")
}
if (config.logger.logLevel < LogLevel.ERROR) {
setStandardOutput(System.err)
setStandardError(System.err)
}
if (config.dumpEvents) {
withSystemProperties(
mapOf(
"org.gradle.internal.operations.trace" to
config.outDir.toPath().resolve("debug").absolutePathString(),
),
)
)
}
}
.run(object : ResultHandler<DependencySet> {
override fun onComplete(result: DependencySet) {
continuation.resume(result)
}
}
.run(
object : ResultHandler<DependencySet> {
override fun onComplete(result: DependencySet) {
continuation.resume(result)
}
override fun onFailure(failure: GradleConnectionException) {
continuation.resumeWithException(failure)
}
})
}
override fun onFailure(failure: GradleConnectionException) {
continuation.resumeWithException(failure)
}
},
)
}

View File

@@ -5,32 +5,43 @@ import kotlin.system.exitProcess
class Logger(
val out: PrintStream = System.err,
val logLevel: LogLevel = LogLevel.warn,
val logLevel: LogLevel = LogLevel.WARN,
val stacktrace: Boolean = false,
) {
fun debug(message: String, error: Throwable? = null) {
if (logLevel <= LogLevel.debug) {
fun debug(
message: String,
error: Throwable? = null,
) {
if (logLevel <= LogLevel.DEBUG) {
out.println("[DEBUG] $message")
printError(error)
}
}
fun info(message: String, error: Throwable? = null) {
if (logLevel <= LogLevel.info) {
fun info(
message: String,
error: Throwable? = null,
) {
if (logLevel <= LogLevel.INFO) {
out.println("[INFO] $message")
printError(error)
}
}
fun warn(message: String, error: Throwable? = null) {
if (logLevel <= LogLevel.warn) {
fun warn(
message: String,
error: Throwable? = null,
) {
if (logLevel <= LogLevel.WARN) {
out.println("[WARN] $message")
printError(error)
}
}
fun error(message: String, error: Throwable? = null): Nothing {
fun error(
message: String,
error: Throwable? = null,
): Nothing {
out.println("[ERROR] $message")
printError(error)
exitProcess(1)
@@ -43,6 +54,8 @@ class Logger(
}
operator fun component1() = ::info
operator fun component2() = ::warn
operator fun component3() = ::error
}

View File

@@ -14,19 +14,16 @@ import com.github.ajalt.clikt.parameters.options.defaultLazy
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.optionalValue
import com.github.ajalt.clikt.parameters.options.validate
import com.github.ajalt.clikt.parameters.types.enum
import com.github.ajalt.clikt.parameters.types.file
import java.io.File
import java.net.URI
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.gradle.internal.service.scopes.Scopes.Gradle
import org.gradle.tooling.model.gradle.GradleBuild
import org.nixos.gradle2nix.model.DependencySet
import java.io.File
import java.net.URI
data class Config(
val appHome: File,
@@ -38,100 +35,106 @@ data class Config(
val projectDir: File,
val tasks: List<String>,
val logger: Logger,
val dumpEvents: Boolean
val dumpEvents: Boolean,
)
@OptIn(ExperimentalSerializationApi::class)
val JsonFormat = Json {
ignoreUnknownKeys = true
prettyPrint = true
prettyPrintIndent = " "
}
val JsonFormat =
Json {
ignoreUnknownKeys = true
prettyPrint = true
prettyPrintIndent = " "
}
sealed interface GradleSource {
data class Distribution(val uri: URI) : GradleSource
data class Path(val path: File) : GradleSource
data object Project : GradleSource
data class Wrapper(val version: String) : GradleSource
}
enum class LogLevel {
debug,
info,
warn,
error,
DEBUG,
INFO,
WARN,
ERROR,
}
class Gradle2Nix : CliktCommand(
name = "gradle2nix",
) {
private val tasks: List<String> by option(
"--task", "-t",
"--task",
"-t",
metavar = "TASK",
help = "Gradle tasks to run"
help = "Gradle tasks to run",
).multiple()
private val projectDir: File by option(
"--project", "-p",
help = "Path to the project root")
.file()
.default(File("."), "Current directory")
.validate { file ->
if (!file.exists()) fail("Directory \"$file\" does not exist.")
if (file.isFile) fail("Directory \"$file\" is a file.")
if (!file.canRead()) fail("Directory \"$file\" is not readable.")
if (!file.isProjectRoot()) fail("Directory \"$file\" is not a Gradle project.")
}
"--project",
"-p",
help = "Path to the project root",
).file(
mustExist = true,
mustBeReadable = true,
canBeFile = false,
).convert { file ->
getProjectRoot(file) ?: fail("Could not locate project root in \"$file\" or its parents.")
}.defaultLazy("Current directory") {
File(".")
}
private val outDir: File? by option(
"--out-dir", "-o",
"--out-dir",
"-o",
metavar = "DIR",
help = "Path to write generated files")
help = "Path to write generated files",
)
.file(canBeFile = false, canBeDir = true)
.defaultLazy("<project>") { projectDir }
internal val lockFile: String by option(
"--lock-file", "-l",
"--lock-file",
"-l",
metavar = "FILENAME",
help = "Name of the generated lock file"
help = "Name of the generated lock file",
).default("gradle.lock")
private val nixFile: String by option(
"--nix-file", "-n",
metavar = "FILENAME",
help = "Name of the generated Nix file"
).default("gradle.nix")
private val gradleSource: GradleSource by mutuallyExclusiveOptions(
option(
"--gradle-dist",
metavar = "URI",
help = "Gradle distribution URI"
help = "Gradle distribution URI",
).convert { GradleSource.Distribution(URI(it)) },
option(
"--gradle-home",
metavar = "DIR",
help = "Gradle home path (e.g. \\`nix eval nixpkgs#gradle.outPath\\`/lib/gradle)"
help = "Gradle home path (e.g. \\`nix eval --raw nixpkgs#gradle.outPath\\`/lib/gradle)",
).file(mustExist = true, canBeFile = false).convert { GradleSource.Path(it) },
option(
"--gradle-wrapper",
help = "Gradle wrapper version"
help = "Gradle wrapper version",
).convert { GradleSource.Wrapper(it) },
name = "Gradle installation",
help = "Where to find Gradle. By default, use the project's wrapper."
help = "Where to find Gradle. By default, use the project's wrapper.",
).single().default(GradleSource.Project)
private val gradleJdk: File? by option(
"--gradle-jdk", "-j",
"--gradle-jdk",
"-j",
metavar = "DIR",
help = "JDK home to use for launching Gradle (e.g. `nix eval nixpkgs#openjdk.home`)",
help = "JDK home to use for launching Gradle (e.g. \\`nix eval --raw nixpkgs#openjdk.home\\`)",
).file(canBeFile = false, canBeDir = true)
private val logLevel: LogLevel by option(
"--log",
help = "Print messages with this priority or higher")
.enum<LogLevel>()
.default(LogLevel.error)
help = "Print messages with this priority or higher",
)
.enum<LogLevel>(key = { it.name.lowercase() })
.default(LogLevel.INFO, "info")
private val dumpEvents: Boolean by option(
"--dump-events",
@@ -140,12 +143,12 @@ class Gradle2Nix : CliktCommand(
private val stacktrace: Boolean by option(
"--stacktrace",
help = "Print a stack trace on error"
help = "Print a stack trace on error",
).flag()
private val gradleArgs: List<String> by argument(
name = "ARGS",
help = "Extra arguments to pass to Gradle"
help = "Extra arguments to pass to Gradle",
).multiple()
init {
@@ -158,48 +161,39 @@ class Gradle2Nix : CliktCommand(
override fun run() {
val logger = Logger(logLevel = logLevel, stacktrace = stacktrace)
val appHome = System.getProperty("org.nixos.gradle2nix.share")?.let(::File)
?: error("could not locate the /share directory in the gradle2nix installation: ${System.getenv("APP_HOME")}")
val appHome =
System.getProperty("org.nixos.gradle2nix.share")?.let(::File)
?: error("Could not locate the /share directory in the gradle2nix installation: ${System.getenv("APP_HOME")}")
logger.debug("appHome=$appHome")
val gradleHome =
System.getenv("GRADLE_USER_HOME")?.let(::File) ?: File("${System.getProperty("user.home")}/.gradle")
val config = Config(
appHome,
gradleHome,
gradleSource,
gradleJdk,
gradleArgs,
outDir ?: projectDir,
projectDir,
tasks,
logger,
dumpEvents
)
logger.debug("gradleHome=$gradleHome")
val config =
Config(
appHome,
gradleHome,
gradleSource,
gradleJdk,
gradleArgs,
outDir ?: projectDir,
projectDir,
tasks,
logger,
dumpEvents,
)
val metadata = File("$projectDir/gradle/verification-metadata.xml")
if (metadata.exists()) {
val backup = metadata.resolveSibling("verification-metadata.xml.bak")
if (metadata.renameTo(backup)) {
Runtime.getRuntime().addShutdownHook(Thread {
metadata.delete()
backup.renameTo(metadata)
})
} else {
metadata.deleteOnExit()
val buildSrcs =
connect(config).use { connection ->
val root = runBlocking { connection.buildModel() }
val builds: List<GradleBuild> =
buildList {
add(root)
addAll(root.editableBuilds)
}
builds.mapNotNull { build ->
build.rootProject.projectDirectory.resolve("buildSrc").takeIf { it.exists() }
}
}
} else {
metadata.deleteOnExit()
}
val buildSrcs = connect(config).use { connection ->
val root = runBlocking { connection.buildModel() }
val builds: List<GradleBuild> = buildList {
add(root)
addAll(root.editableBuilds)
}
builds.mapNotNull { build ->
build.rootProject.projectDirectory.resolve("buildSrc").takeIf { it.exists() }
}
}
val dependencySets = mutableListOf<DependencySet>()
@@ -213,11 +207,12 @@ class Gradle2Nix : CliktCommand(
}
}
val env = try {
processDependencies(config, dependencySets)
} catch (e: Throwable) {
logger.error("dependency parsing failed", e)
}
val env =
try {
processDependencies(config, dependencySets)
} catch (e: Throwable) {
logger.error("Dependency parsing failed", e)
}
config.outDir.mkdirs()
@@ -226,12 +221,6 @@ class Gradle2Nix : CliktCommand(
outLockFile.outputStream().buffered().use { output ->
JsonFormat.encodeToStream(env, output)
}
val inNixFile = config.appHome.resolve("gradle.nix").takeIf { it.exists() }
?: error("Couldn't locate gradle.nix in the the gradle2nix installation: ${config.appHome}")
val outNixFile = config.outDir.resolve(nixFile)
logger.info("Writing Nix builder to $outNixFile")
inNixFile.copyTo(outNixFile, overwrite = true)
}
}

View File

@@ -1,12 +1,13 @@
package org.nixos.gradle2nix
import okio.ByteString.Companion.decodeHex
import org.nixos.gradle2nix.model.DependencyCoordinates
import org.nixos.gradle2nix.model.DependencySet
import kotlin.io.encoding.Base64
import kotlin.io.encoding.ExperimentalEncodingApi
fun processDependencies(
config: Config,
dependencySets: Iterable<DependencySet>
dependencySets: Iterable<DependencySet>,
): Env {
return buildMap<DependencyCoordinates, Map<String, Artifact>> {
for (dependencySet in dependencySets) {
@@ -19,11 +20,13 @@ fun processDependencies(
for ((name, artifact) in b) {
merge(name, artifact) { aa, ba ->
check(aa.hash == ba.hash) {
config.logger.error("""
config.logger.error(
"""
Conflicting hashes found for $id:$name:
1: ${aa.hash}
2: ${ba.hash}
""".trimIndent())
""".trimIndent(),
)
}
aa
@@ -41,18 +44,22 @@ fun processDependencies(
private fun DependencySet.toEnv(): Map<DependencyCoordinates, Map<String, Artifact>> {
return dependencies.associate { dep ->
dep.coordinates to dep.artifacts.associate {
it.name to Artifact(it.url, it.hash.toSri())
}
dep.coordinates to
dep.artifacts.associate {
it.name to Artifact(it.url, it.hash.toSri())
}
}
}
internal fun String.toSri(): String {
val hash = decodeHex().base64()
return "sha256-$hash"
}
@OptIn(ExperimentalEncodingApi::class, ExperimentalStdlibApi::class)
internal fun String.toSri(): String =
buildString {
append("sha256-")
Base64.encodeToAppendable(hexToByteArray(), this)
}
private val coordinatesComparator: Comparator<DependencyCoordinates> = compareBy<DependencyCoordinates> { it.group }
.thenBy { it.artifact }
.thenByDescending { Version(it.version) }
.thenByDescending { it.timestamp }
private val coordinatesComparator: Comparator<DependencyCoordinates> =
compareBy<DependencyCoordinates> { it.group }
.thenBy { it.artifact }
.thenByDescending { Version(it.version) }
.thenByDescending { it.timestamp }

View File

@@ -2,5 +2,13 @@ package org.nixos.gradle2nix
import java.io.File
fun File.isProjectRoot(): Boolean =
isDirectory && (resolve("settings.gradle").isFile || resolve("settings.gradle.kts").isFile)
tailrec fun getProjectRoot(path: File): File? {
return if (path.isProjectRoot()) {
path
} else {
val parent = path.parentFile ?: return null
return getProjectRoot(parent)
}
}
fun File.isProjectRoot(): Boolean = isDirectory && (resolve("settings.gradle").isFile || resolve("settings.gradle.kts").isFile)

View File

@@ -3,95 +3,105 @@ package org.nixos.gradle2nix
import java.util.concurrent.ConcurrentHashMap
class Version(val source: String, val parts: List<String>, base: Version?) : Comparable<Version> {
private val base: Version
val numericParts: List<Long?>
init {
this.base = base ?: this
this.numericParts = parts.map {
try { it.toLong() } catch (e: NumberFormatException) { null }
}
this.numericParts =
parts.map {
try {
it.toLong()
} catch (e: NumberFormatException) {
null
}
}
}
override fun compareTo(other: Version): Int = compare(this, other)
override fun toString(): String = source
override fun equals(other: Any?): Boolean = when {
other === this -> true
other == null || other !is Version -> false
else -> source == other.source
}
override fun equals(other: Any?): Boolean =
when {
other === this -> true
other == null || other !is Version -> false
else -> source == other.source
}
override fun hashCode(): Int = source.hashCode()
companion object {
private val SPECIAL_MEANINGS: Map<String, Int> = mapOf(
"dev" to -1,
"rc" to 1,
"snapshot" to 2,
"final" to 3,
"ga" to 4,
"release" to 5,
"sp" to 6
)
private val SPECIAL_MEANINGS: Map<String, Int> =
mapOf(
"dev" to -1,
"rc" to 1,
"snapshot" to 2,
"final" to 3,
"ga" to 4,
"release" to 5,
"sp" to 6,
)
private val cache = ConcurrentHashMap<String, Version>()
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser
operator fun invoke(original: String): Version = cache.getOrPut(original) {
val parts = mutableListOf<String>()
var digit = false
var startPart = 0
var pos = 0
var endBase = 0
var endBaseStr = 0
while (pos < original.length) {
val ch = original[pos]
if (ch == '.' || ch == '_' || ch == '-' || ch == '+') {
parts.add(original.substring(startPart, pos))
startPart = pos + 1
digit = false
if (ch != '.' && endBaseStr == 0) {
endBase = parts.size
endBaseStr = pos
}
} else if (ch in '0'..'9') {
if (!digit && pos > startPart) {
if (endBaseStr == 0) {
endBase = parts.size + 1
operator fun invoke(original: String): Version =
cache.getOrPut(original) {
val parts = mutableListOf<String>()
var digit = false
var startPart = 0
var pos = 0
var endBase = 0
var endBaseStr = 0
while (pos < original.length) {
val ch = original[pos]
if (ch == '.' || ch == '_' || ch == '-' || ch == '+') {
parts.add(original.substring(startPart, pos))
startPart = pos + 1
digit = false
if (ch != '.' && endBaseStr == 0) {
endBase = parts.size
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = true
} else {
if (digit) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
} else if (ch in '0'..'9') {
if (!digit && pos > startPart) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
digit = true
} else {
if (digit) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = false
}
digit = false
pos++
}
pos++
if (pos > startPart) {
parts.add(original.substring(startPart, pos))
}
var base: Version? = null
if (endBaseStr > 0) {
base = Version(original.substring(0, endBaseStr), parts.subList(0, endBase), null)
}
Version(original, parts, base)
}
if (pos > startPart) {
parts.add(original.substring(startPart, pos))
}
var base: Version? = null
if (endBaseStr > 0) {
base = Version(original.substring(0, endBaseStr), parts.subList(0, endBase), null)
}
Version(original, parts, base)
}
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.StaticVersionComparator
private fun compare(version1: Version, version2: Version): Int {
private fun compare(
version1: Version,
version2: Version,
): Int {
if (version1 == version2) {
return 0
}

View File

@@ -21,11 +21,6 @@ import io.ktor.server.http.content.staticFiles
import io.ktor.server.netty.Netty
import io.ktor.server.netty.NettyApplicationEngine
import io.ktor.server.routing.routing
import java.io.File
import java.io.FileFilter
import java.nio.file.Files
import java.nio.file.Paths
import kotlin.random.Random
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -35,17 +30,22 @@ import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.decodeFromStream
import kotlinx.serialization.json.encodeToStream
import okio.use
import java.io.File
import java.io.FileFilter
import java.nio.file.Files
import java.nio.file.Paths
import kotlin.random.Random
private val app = Gradle2Nix()
@OptIn(ExperimentalSerializationApi::class)
private val json = Json {
prettyPrint = true
prettyPrintIndent = " "
}
private val json =
Json {
prettyPrint = true
prettyPrintIndent = " "
}
val testLogger = Logger(logLevel = LogLevel.debug, stacktrace = true)
val testLogger = Logger(logLevel = LogLevel.DEBUG, stacktrace = true)
fun fixture(path: String): File {
return Paths.get("../fixtures", path).toFile()
@@ -55,17 +55,19 @@ fun fixture(path: String): File {
suspend fun TestScope.fixture(
project: String,
vararg args: String,
test: suspend TestScope.(File, Env) -> Unit
test: suspend TestScope.(File, Env) -> Unit,
) {
val tmp = Paths.get("build/tmp/gradle2nix").apply { toFile().mkdirs() }
val baseDir = Paths.get("../fixtures/projects", project).toFile()
val children = baseDir.listFiles(FileFilter { it.isDirectory && (it.name == "groovy" || it.name == "kotlin") })
?.toList()
val cases = if (children.isNullOrEmpty()) {
listOf(project to baseDir)
} else {
children.map { "$project.${it.name}" to it }
}
val children =
baseDir.listFiles(FileFilter { it.isDirectory && (it.name == "groovy" || it.name == "kotlin") })
?.toList()
val cases =
if (children.isNullOrEmpty()) {
listOf(project to baseDir)
} else {
children.map { "$project.${it.name}" to it }
}
for (case in cases) {
registerTestCase(
NestedTest(
@@ -73,7 +75,7 @@ suspend fun TestScope.fixture(
disabled = false,
config = null,
type = TestType.Dynamic,
source = sourceRef()
source = sourceRef(),
) {
var dirName = case.second.toString().replace("/", ".")
while (dirName.startsWith(".")) dirName = dirName.removePrefix(".")
@@ -88,22 +90,25 @@ suspend fun TestScope.fixture(
}
app.main(
listOf(
"-p", tempDir.toString(),
"--log", "debug",
"-p",
tempDir.toString(),
"--log",
"debug",
"--stacktrace",
"--dump-events",
"--",
"-Dorg.nixos.gradle2nix.m2=$m2",
"--info"
) + args
"--info",
) + args,
)
val file = tempDir.resolve(app.lockFile)
file.shouldBeAFile()
val env: Env = file.inputStream().buffered().use { input ->
Json.decodeFromStream(input)
}
val env: Env =
file.inputStream().buffered().use { input ->
Json.decodeFromStream(input)
}
test(tempDir, env)
}
},
)
}
}
@@ -127,11 +132,12 @@ suspend fun TestScope.golden(
if (!goldenFile.exists()) {
fail("Golden file '$filename' doesn't exist. Run with --update-golden to generate.")
}
val goldenData = try {
goldenFile.readText()
} catch (e: SerializationException) {
fail("Failed to load golden data from '$filename'. Run with --update-golden to regenerate.")
}
val goldenData =
try {
goldenFile.readText()
} catch (e: SerializationException) {
fail("Failed to load golden data from '$filename'. Run with --update-golden to regenerate.")
}
json.encodeToString(env) should beEqual(goldenData)
}
}
@@ -172,24 +178,25 @@ object MavenRepo : MountableExtension<MavenRepo.Config, NettyApplicationEngine>,
private fun tryStart(attempts: Int): NettyApplicationEngine {
return try {
val p = config.port ?: Random.nextInt(10000, 65000)
val s = embeddedServer(Netty, port = p, host = config.host) {
routing {
staticFiles(
remotePath = config.path,
dir = config.repository,
index = null,
) {
enableAutoHeadResponse()
contentType { path ->
when (path.extension) {
"pom", "xml" -> ContentType.Text.Xml
"jar" -> ContentType("application", "java-archive")
else -> ContentType.Text.Plain
val s =
embeddedServer(Netty, port = p, host = config.host) {
routing {
staticFiles(
remotePath = config.path,
dir = config.repository,
index = null,
) {
enableAutoHeadResponse()
contentType { path ->
when (path.extension) {
"pom", "xml" -> ContentType.Text.Xml
"jar" -> ContentType("application", "java-archive")
else -> ContentType.Text.Plain
}
}
}
}
}
}
coroutineScope.launch { s.start(wait = true) }
s
} catch (e: Throwable) {

View File

@@ -1,9 +1,11 @@
{ pkgs ? import <nixpkgs> {} }:
{
pkgs ? import <nixpkgs> { },
}:
with pkgs;
let
buildGradlePackage = callPackage ./gradle.nix {};
buildGradlePackage = callPackage ./gradle.nix { };
gradle2nix = buildGradlePackage {
pname = "gradle2nix";
@@ -13,14 +15,15 @@ let
src = lib.cleanSourceWith {
filter = lib.cleanSourceFilter;
src = lib.cleanSourceWith {
filter = path: type: let baseName = baseNameOf path; in !(
(type == "directory" && (
baseName == "build" ||
baseName == ".idea" ||
baseName == ".gradle"
)) ||
(lib.hasSuffix ".iml" baseName)
);
filter =
path: type:
let
baseName = baseNameOf path;
in
!(
(type == "directory" && (baseName == "build" || baseName == ".idea" || baseName == ".gradle"))
|| (lib.hasSuffix ".iml" baseName)
);
src = ./.;
};
};
@@ -28,13 +31,14 @@ let
gradleFlags = [ "installDist" ];
installPhase = ''
mkdir -p $out
cp -r app/build/install/gradle2nix/* $out/
mkdir -p $out/{bin,/lib/gradle2nix}
cp -r app/build/install/gradle2nix/* $out/lib/gradle2nix/
rm $out/lib/gradle2nix/bin/gradle2nix.bat
ln -sf $out/lib/gradle2nix/bin/gradle2nix $out/bin
'';
passthru = {
inherit buildGradlePackage;
plugin = "${gradle2nix}/share/plugin.jar";
};
meta = with lib; {
@@ -46,5 +50,5 @@ let
mainProgram = "gradle2nix";
};
};
in gradle2nix
in
gradle2nix

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -1,9 +1,9 @@
with (import <nixpkgs> {});
with (import <nixpkgs> { });
let
buildGradle = callPackage ./gradle-env.nix {};
buildGradle = callPackage ./gradle-env.nix { };
in
buildGradle {
envSpec = ./gradle-env.json;
src = ./.;
gradleFlags = [ "tasks" ];
}
buildGradle {
envSpec = ./gradle-env.json;
src = ./.;
gradleFlags = [ "tasks" ];
}

View File

@@ -19,126 +19,167 @@
# '';
# }
{ stdenv, buildEnv, fetchurl, gradleGen, writeText, writeTextDir }:
{
stdenv,
buildEnv,
fetchurl,
gradleGen,
writeText,
writeTextDir,
}:
{ envSpec
, pname ? null
, version ? null
, enableParallelBuilding ? true
, gradleFlags ? [ "build" ]
, gradlePackage ? null
, enableDebug ? false
, ... } @ args:
{
envSpec,
pname ? null,
version ? null,
enableParallelBuilding ? true,
gradleFlags ? [ "build" ],
gradlePackage ? null,
enableDebug ? false,
...
}@args:
let
inherit (builtins)
attrValues concatStringsSep filter fromJSON match replaceStrings sort;
attrValues
concatStringsSep
filter
fromJSON
match
replaceStrings
sort
;
inherit (stdenv.lib)
assertMsg concatMapStringsSep groupBy' hasSuffix last mapAttrs
mapAttrsToList optionalString readFile removeSuffix unique versionAtLeast
versionOlder;
assertMsg
concatMapStringsSep
groupBy'
hasSuffix
last
mapAttrs
mapAttrsToList
optionalString
readFile
removeSuffix
unique
versionAtLeast
versionOlder
;
mkDep = depSpec: stdenv.mkDerivation {
inherit (depSpec) name;
mkDep =
depSpec:
stdenv.mkDerivation {
inherit (depSpec) name;
src = fetchurl {
inherit (depSpec) urls sha256;
src = fetchurl { inherit (depSpec) urls sha256; };
phases = "installPhase";
installPhase = ''
mkdir -p $out/${depSpec.path}
ln -s $src $out/${depSpec.path}/${depSpec.name}
'';
};
phases = "installPhase";
installPhase = ''
mkdir -p $out/${depSpec.path}
ln -s $src $out/${depSpec.path}/${depSpec.name}
'';
};
mkModuleMetadata = deps:
mkModuleMetadata =
deps:
let
ids = filter
(id: id.type == "pom")
(map (dep: dep.id) deps);
ids = filter (id: id.type == "pom") (map (dep: dep.id) deps);
modules = groupBy'
(meta: id:
let
isNewer = versionOlder meta.latest id.version;
isNewerRelease =
!(hasSuffix "-SNAPSHOT" id.version) &&
versionOlder meta.release id.version;
in {
groupId = id.group;
artifactId = id.name;
latest = if isNewer then id.version else meta.latest;
release = if isNewerRelease then id.version else meta.release;
versions = meta.versions ++ [id.version];
modules =
groupBy'
(
meta: id:
let
isNewer = versionOlder meta.latest id.version;
isNewerRelease = !(hasSuffix "-SNAPSHOT" id.version) && versionOlder meta.release id.version;
in
{
groupId = id.group;
artifactId = id.name;
latest = if isNewer then id.version else meta.latest;
release = if isNewerRelease then id.version else meta.release;
versions = meta.versions ++ [ id.version ];
}
)
{
latest = "";
release = "";
versions = [ ];
}
)
{
latest = "";
release = "";
versions = [];
}
(id: "${replaceStrings ["."] ["/"] id.group}/${id.name}/maven-metadata.xml")
ids;
(id: "${replaceStrings [ "." ] [ "/" ] id.group}/${id.name}/maven-metadata.xml")
ids;
in
attrValues (mapAttrs (path: meta:
attrValues (
mapAttrs (
path: meta:
let
versions' = sort versionOlder (unique meta.versions);
in
with meta; writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<versioning>
${optionalString (latest != "") "<latest>${latest}</latest>"}
${optionalString (release != "") "<release>${release}</release>"}
<versions>
${concatMapStringsSep "\n " (v: "<version>${v}</version>") versions'}
</versions>
</versioning>
</metadata>
''
) modules);
with meta;
writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<versioning>
${optionalString (latest != "") "<latest>${latest}</latest>"}
${optionalString (release != "") "<release>${release}</release>"}
<versions>
${concatMapStringsSep "\n " (v: "<version>${v}</version>") versions'}
</versions>
</versioning>
</metadata>
''
) modules
);
mkSnapshotMetadata = deps:
mkSnapshotMetadata =
deps:
let
snapshotDeps = filter (dep: dep ? build && dep ? timestamp) deps;
modules = groupBy'
(meta: dep:
let
id = dep.id;
isNewer = dep.build > meta.buildNumber;
# Timestamp values can be bogus, e.g. jitpack.io
updated = if (match "[0-9]{8}\.[0-9]{6}" dep.timestamp) != null
then replaceStrings ["."] [""] dep.timestamp
else "";
in {
groupId = id.group;
artifactId = id.name;
version = id.version;
timestamp = if isNewer then dep.timestamp else meta.timestamp;
buildNumber = if isNewer then dep.build else meta.buildNumber;
lastUpdated = if isNewer then updated else meta.lastUpdated;
versions = meta.versions or [] ++ [{
classifier = id.classifier or "";
extension = id.extension;
value = "${removeSuffix "-SNAPSHOT" id.version}-${dep.timestamp}-${toString dep.build}";
updated = updated;
}];
modules =
groupBy'
(
meta: dep:
let
id = dep.id;
isNewer = dep.build > meta.buildNumber;
# Timestamp values can be bogus, e.g. jitpack.io
updated =
if (match "[0-9]{8}\.[0-9]{6}" dep.timestamp) != null then
replaceStrings [ "." ] [ "" ] dep.timestamp
else
"";
in
{
groupId = id.group;
artifactId = id.name;
version = id.version;
timestamp = if isNewer then dep.timestamp else meta.timestamp;
buildNumber = if isNewer then dep.build else meta.buildNumber;
lastUpdated = if isNewer then updated else meta.lastUpdated;
versions = meta.versions or [ ] ++ [
{
classifier = id.classifier or "";
extension = id.extension;
value = "${removeSuffix "-SNAPSHOT" id.version}-${dep.timestamp}-${toString dep.build}";
updated = updated;
}
];
}
)
{
timestamp = "";
buildNumber = -1;
lastUpdated = "";
}
)
{
timestamp = "";
buildNumber = -1;
lastUpdated = "";
}
(dep: "${replaceStrings ["."] ["/"] dep.id.group}/${dep.id.name}/${dep.id.version}/maven-metadata.xml")
snapshotDeps;
(
dep:
"${replaceStrings [ "." ] [ "/" ] dep.id.group}/${dep.id.name}/${dep.id.version}/maven-metadata.xml"
)
snapshotDeps;
mkSnapshotVersion = version: ''
<snapshotVersion>
@@ -148,10 +189,12 @@ let
${optionalString (version.updated != "") "<updated>${version.updated}</updated>"}
</snapshotVersion>
'';
in
attrValues (mapAttrs (path: meta:
with meta; writeTextDir path ''
attrValues (
mapAttrs (
path: meta:
with meta;
writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
@@ -169,92 +212,98 @@ let
</versioning>
</metadata>
''
) modules);
) modules
);
mkRepo = project: type: deps: buildEnv {
name = "${project}-gradle-${type}-env";
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
};
mkRepo =
project: type: deps:
buildEnv {
name = "${project}-gradle-${type}-env";
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
};
mkInitScript = projectSpec: gradle:
mkInitScript =
projectSpec: gradle:
let
repos = mapAttrs (mkRepo projectSpec.name) projectSpec.dependencies;
hasDependencies = mapAttrs (type: deps: deps != []) projectSpec.dependencies;
hasDependencies = mapAttrs (type: deps: deps != [ ]) projectSpec.dependencies;
in
assert (assertMsg (hasDependencies.settings -> versionAtLeast gradle.version "6.0") ''
assert (
assertMsg (hasDependencies.settings -> versionAtLeast gradle.version "6.0") ''
Project `${projectSpec.name}' has settings script dependencies, such as settings
plugins, which are not supported by gradle2nix for Gradle versions prior to 6.0.
Potential remedies:
- Pass `--gradle-version=<version>' to the gradle2nix command.
- Patch the `settings.gradle[.kts]' file to remove script dependencies.
'');
''
);
writeText "init.gradle" ''
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
repositories.clear()
repositories.maven {
name "Nix''${env.capitalize()}MavenOffline"
url path
metadataSources {
it.gradleMetadata()
it.mavenPom()
it.artifact()
}
}
repositories.ivy {
name "Nix''${env.capitalize()}IvyOffline"
url path
layout "maven"
metadataSources {
it.gradleMetadata()
it.ivyDescriptor()
it.artifact()
writeText "init.gradle" ''
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
repositories.clear()
repositories.maven {
name "Nix''${env.capitalize()}MavenOffline"
url path
metadataSources {
it.gradleMetadata()
it.mavenPom()
it.artifact()
}
}
repositories.ivy {
name "Nix''${env.capitalize()}IvyOffline"
url path
layout "maven"
metadataSources {
it.gradleMetadata()
it.ivyDescriptor()
it.artifact()
}
}
}
${optionalString (hasDependencies.settings && (versionAtLeast gradle.version "6.0")) ''
gradle.beforeSettings {
offlineRepo(it.buildscript.repositories, "settings", "${repos.settings}")
}
''}
${optionalString (hasDependencies.plugin) ''
gradle.settingsEvaluated {
offlineRepo(it.pluginManagement.repositories, "plugin", "${repos.plugin}")
}
''}
${optionalString (hasDependencies.buildscript) ''
gradle.projectsLoaded {
allprojects {
buildscript {
offlineRepo(repositories, "buildscript", "${repos.buildscript}")
}
}
}
''}
${optionalString (hasDependencies.settings && (versionAtLeast gradle.version "6.0")) ''
gradle.beforeSettings {
offlineRepo(it.buildscript.repositories, "settings", "${repos.settings}")
}
''}
${optionalString (hasDependencies.project) ''
gradle.projectsLoaded {
allprojects {
offlineRepo(repositories, "project", "${repos.project}")
}
}
''}
'';
${optionalString (hasDependencies.plugin) ''
gradle.settingsEvaluated {
offlineRepo(it.pluginManagement.repositories, "plugin", "${repos.plugin}")
}
''}
${optionalString (hasDependencies.buildscript) ''
gradle.projectsLoaded {
allprojects {
buildscript {
offlineRepo(repositories, "buildscript", "${repos.buildscript}")
}
}
}
''}
${optionalString (hasDependencies.project) ''
gradle.projectsLoaded {
allprojects {
offlineRepo(repositories, "project", "${repos.project}")
}
}
''}
'';
mkGradle = gradleSpec:
mkGradle =
gradleSpec:
gradleGen.gradleGen {
inherit (gradleSpec) nativeVersion;
name = "gradle-${gradleSpec.version}-${gradleSpec.type}";
src = fetchurl {
inherit (gradleSpec) url sha256;
};
} // {
src = fetchurl { inherit (gradleSpec) url sha256; };
}
// {
inherit (gradleSpec) version;
};
@@ -264,9 +313,7 @@ let
initScript = mkInitScript projectSpec gradle;
};
gradleEnv = mapAttrs
(_: p: mkProjectEnv p)
(fromJSON (readFile envSpec));
gradleEnv = mapAttrs (_: p: mkProjectEnv p) (fromJSON (readFile envSpec));
projectEnv = gradleEnv."";
pname = args.pname or projectEnv.name;
@@ -282,37 +329,40 @@ let
${concatStringsSep " " flags}
'';
buildIncludedProjects =
concatStringsSep "\n" (mapAttrsToList
(_: env: buildProject env [ "build" ])
(removeAttrs gradleEnv [ "" ]));
buildIncludedProjects = concatStringsSep "\n" (
mapAttrsToList (_: env: buildProject env [ "build" ]) (removeAttrs gradleEnv [ "" ])
);
buildRootProject = buildProject projectEnv gradleFlags;
in
stdenv.mkDerivation (
args
// {
in stdenv.mkDerivation (args // {
inherit pname version;
inherit pname version;
nativeBuildInputs = (args.nativeBuildInputs or [ ]) ++ [ projectEnv.gradle ];
nativeBuildInputs = (args.nativeBuildInputs or []) ++ [ projectEnv.gradle ];
buildPhase =
args.buildPhase or ''
runHook preBuild
buildPhase = args.buildPhase or ''
runHook preBuild
(
set -x
(
set -x
# use the init script here
TMPHOME=$(mktemp -d)
mkdir -p $TMPHOME/init.d
cp ${projectEnv.initScript} $TMPHOME/init.d
# use the init script here
TMPHOME=$(mktemp -d)
mkdir -p $TMPHOME/init.d
cp ${projectEnv.initScript} $TMPHOME/init.d
export "GRADLE_USER_HOME=$TMPHOME"
${buildIncludedProjects}
${buildRootProject}
)
export "GRADLE_USER_HOME=$TMPHOME"
${buildIncludedProjects}
${buildRootProject}
)
runHook postBuild
'';
runHook postBuild
'';
dontStrip = true;
})
dontStrip = true;
}
)

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -0,0 +1 @@
// Intentionally left empty

View File

@@ -1 +1 @@
include(":child-a", ":child-b")
include(":child-a", ":child-b")

8
flake.lock generated
View File

@@ -20,16 +20,16 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1715954240,
"narHash": "sha256-eC0zRYkazBc2cKz1VSzMLvCc9uHXlSQEr1Be+c5UV1w=",
"lastModified": 1716769173,
"narHash": "sha256-7EXDb5WBw+d004Agt+JHC/Oyh/KTUglOaQ4MNjBbo5w=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "c2ea18b50a4c7fcb7c90402166769bf3b82b5aa9",
"rev": "9ca3f649614213b2aaf5f1e16ec06952fe4c2632",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable-small",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}

View File

@@ -3,22 +3,49 @@
inputs = {
flake-utils.url = "github:numtide/flake-utils";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable-small";
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs = { self, flake-utils, nixpkgs, ... }:
flake-utils.lib.eachDefaultSystem (system:
outputs =
{
self,
flake-utils,
nixpkgs,
...
}:
flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in {
builders.default = pkgs.callPackage ./gradle.nix {};
packages.default = pkgs.callPackage ./default.nix {};
apps.default = {
type = "app";
program = "${self.packages.${system}.default}/bin/gradle2nix";
inherit (nixpkgs) lib;
in
{
builders = rec {
buildGradlePackage = pkgs.callPackage ./gradle.nix { };
default = buildGradlePackage;
};
});
packages = rec {
gradle2nix = pkgs.callPackage ./default.nix { };
default = gradle2nix;
};
apps = rec {
gradle2nix = {
type = "app";
program = lib.getExe self.packages.${system}.default;
};
default = gradle2nix;
};
formatter = pkgs.writeShellScriptBin "gradle2nix-fmt" ''
fail=0
${lib.getExe pkgs.nixfmt-rfc-style} $@ || fail=1
${lib.getExe pkgs.ktlint} --relative -l warn -F || fail=1
[ $fail -eq 0 ] || echo "Formatting failed." >&2
exit $fail
'';
}
);
}

View File

@@ -161,34 +161,6 @@
"hash": "sha256-E6X+iu2+Rs/b6hLp/NcJemKygqpqtMkIZWuWzpoqX6M="
}
},
"com.squareup.okio:okio:3.9.0": {
"okio-3.9.0.jar": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.jar",
"hash": "sha256-5RilmFYnOh/OGKx9E938aQ3vphItflzQDK4Zti0DR9k="
},
"okio-3.9.0.module": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.module",
"hash": "sha256-aNHIef9liTHQKzrb6vu1EuFjwgqQyt8H2QyNvqfnYhA="
},
"okio-3.9.0.pom": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.pom",
"hash": "sha256-FPNR2puXtDaeP26PaWsK1ANtFNIbD9l6pcjG7BW+fZA="
}
},
"com.squareup.okio:okio-jvm:3.9.0": {
"okio-jvm-3.9.0.jar": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.0/okio-jvm-3.9.0.jar",
"hash": "sha256-3cOG/xS9JdXJNBZxlur0WxjeTyjhxVpNs3rllMv9N+Q="
},
"okio-jvm-3.9.0.module": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.0/okio-jvm-3.9.0.module",
"hash": "sha256-z5coTsYbtR5t/Lx/K22VVsm3s+PLIswOLU8O7782GVs="
},
"okio-jvm-3.9.0.pom": {
"url": "https://repo.maven.apache.org/maven2/com/squareup/okio/okio-jvm/3.9.0/okio-jvm-3.9.0.pom",
"hash": "sha256-VEiNRUqsyvaPcZnz3l3Ns4CBblfUYJBJF06FZSAROH4="
}
},
"com.typesafe:config:1.4.3": {
"config-1.4.3.jar": {
"url": "https://repo.maven.apache.org/maven2/com/typesafe/config/1.4.3/config-1.4.3.jar",
@@ -241,48 +213,6 @@
"hash": "sha256-2BHPnxGMwsrRMMlCetVcF01MCm8aAKwa4cm8vsXESxk="
}
},
"io.github.pdvrieze.xmlutil:core:0.86.3": {
"core-0.86.3.jar": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core/0.86.3/core-0.86.3.jar",
"hash": "sha256-ikZHG7Y7PHhzlsu6WqL2TU4zOgOSAiRBrhIRHn5yjJE="
},
"core-0.86.3.module": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core/0.86.3/core-0.86.3.module",
"hash": "sha256-MzlXsdCR2LrPqwYCCGgi+a2S9hMCy3Ru8g4Z9nprTbk="
},
"core-0.86.3.pom": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core/0.86.3/core-0.86.3.pom",
"hash": "sha256-ngeyUCJI+U7AYn9Wsn3wiBySBCrfzoCg35oa6sQWg4M="
}
},
"io.github.pdvrieze.xmlutil:core-jvm:0.86.3": {
"core-jvm-0.86.3.jar": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core-jvm/0.86.3/core-jvm-0.86.3.jar",
"hash": "sha256-kVJ9hv6gS9YYPRQKCfENqy3qcnrxLSfZFl7jQuo9Dt4="
},
"core-jvm-0.86.3.module": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core-jvm/0.86.3/core-jvm-0.86.3.module",
"hash": "sha256-FgIJExZWo2dDGWXYAYk7J3fuguD3ZmaD+nXE+Wck/wc="
},
"core-jvm-0.86.3.pom": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/core-jvm/0.86.3/core-jvm-0.86.3.pom",
"hash": "sha256-oBGIoPlVW1s7nZLlQz242AJ6vjleD/cIBRU+8v6qf4U="
}
},
"io.github.pdvrieze.xmlutil:serialization-jvm:0.86.3": {
"serialization-jvm-0.86.3.jar": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/serialization-jvm/0.86.3/serialization-jvm-0.86.3.jar",
"hash": "sha256-nOJz3LhguSpb8uw2rR4qEbQa7YnGyYTKc+h+/17aG9A="
},
"serialization-jvm-0.86.3.module": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/serialization-jvm/0.86.3/serialization-jvm-0.86.3.module",
"hash": "sha256-3ppDm3mA++bMPDS8rZyEqIMVmdyHZNceD2c93Ho91Jo="
},
"serialization-jvm-0.86.3.pom": {
"url": "https://repo.maven.apache.org/maven2/io/github/pdvrieze/xmlutil/serialization-jvm/0.86.3/serialization-jvm-0.86.3.pom",
"hash": "sha256-OX1XqPVTaUEf7HRETH1NTLaeyYANUkSTrGHekJIl4wc="
}
},
"io.kotest:kotest-assertions-api:5.9.0": {
"kotest-assertions-api-5.9.0.jar": {
"url": "https://repo.maven.apache.org/maven2/io/kotest/kotest-assertions-api/5.9.0/kotest-assertions-api-5.9.0.jar",
@@ -1039,16 +969,6 @@
"hash": "sha256-4E4llRUB3yWtx7Hc22xTNzyUiXuE0+FJISknY+4Hrj0="
}
},
"net.java.dev.jna:jna:5.9.0": {
"jna-5.9.0.jar": {
"url": "https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.9.0/jna-5.9.0.jar",
"hash": "sha256-6vzHgLRFQ008Wuf6L7ZmXeGnVg1TfSxAio6AzRTScWE="
},
"jna-5.9.0.pom": {
"url": "https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.9.0/jna-5.9.0.pom",
"hash": "sha256-a8i4RZFQtZ6VmPPa2a0kWh7yFQ0IJYEBcYTrFj5ZKCk="
}
},
"net.java.dev.jna:jna-platform:5.9.0": {
"jna-platform-5.9.0.jar": {
"url": "https://repo.maven.apache.org/maven2/net/java/dev/jna/jna-platform/5.9.0/jna-platform-5.9.0.jar",
@@ -1331,214 +1251,224 @@
"hash": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k="
}
},
"org.jetbrains.kotlin:kotlin-android-extensions:1.9.22": {
"kotlin-android-extensions-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.9.22/kotlin-android-extensions-1.9.22.jar",
"hash": "sha256-Hl6IFkKpnduPbRPmmVoIwZK8OEGHOWZj2ER8CB2H4k8="
"org.jetbrains.kotlin:kotlin-android-extensions:1.9.24": {
"kotlin-android-extensions-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.9.24/kotlin-android-extensions-1.9.24.jar",
"hash": "sha256-4z5UUlSR0ZgdRODKmnxTIWh91QRDPsVJZhqb5UYKEW4="
},
"kotlin-android-extensions-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.9.22/kotlin-android-extensions-1.9.22.pom",
"hash": "sha256-lEt8+zPgpvtoRVkEjwKMuWMmyTKiRdXLAhQ7zSwDEVk="
"kotlin-android-extensions-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.9.24/kotlin-android-extensions-1.9.24.pom",
"hash": "sha256-6QmjYHLn/lbQULgKdXEDwdP4dz+2wb0GcrxKr7hRCEs="
}
},
"org.jetbrains.kotlin:kotlin-build-common:1.9.22": {
"kotlin-build-common-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.9.22/kotlin-build-common-1.9.22.jar",
"hash": "sha256-U8PcxTA/WQPmJgrqc+zMaTD5o276KhHNO9On5V32OWY="
"org.jetbrains.kotlin:kotlin-build-common:1.9.24": {
"kotlin-build-common-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.9.24/kotlin-build-common-1.9.24.jar",
"hash": "sha256-+RqOaTfik7FEv6F0DHB3xa12EdtI9CnKMcCm2yduaUo="
},
"kotlin-build-common-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.9.22/kotlin-build-common-1.9.22.pom",
"hash": "sha256-KXxfSYoHdIPvic06cQzSt/LlrjgPOjrt+5xBvGI7E0A="
"kotlin-build-common-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-common/1.9.24/kotlin-build-common-1.9.24.pom",
"hash": "sha256-iNt6ER1bfbV+4gKFEX2mNz3NJQQxqd58h8ZCJRYL0RI="
}
},
"org.jetbrains.kotlin:kotlin-build-tools-api:1.9.22": {
"kotlin-build-tools-api-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-api/1.9.22/kotlin-build-tools-api-1.9.22.jar",
"hash": "sha256-3UnLfij08zgvUlDPsFyGT9XwqW0yZbspPHezCtzJP/Y="
"org.jetbrains.kotlin:kotlin-build-tools-api:1.9.24": {
"kotlin-build-tools-api-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-build-tools-api/1.9.24/kotlin-build-tools-api-1.9.24.jar",
"hash": "sha256-ZUX99qL/t4jN3O3KymMiOdx+XmHD90SCNzXjse2cG1Q="
},
"kotlin-build-tools-api-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-build-tools-api/1.9.22/kotlin-build-tools-api-1.9.22.pom",
"hash": "sha256-DFZLu4fcXs32Q005buob886Xar8IgYCN0Wb6SbBGSfs="
"kotlin-build-tools-api-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-build-tools-api/1.9.24/kotlin-build-tools-api-1.9.24.pom",
"hash": "sha256-efIYZmDsHYeQhu4jEEeY2M1PthcsJ5xeVuAsqeVbxHU="
}
},
"org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.22": {
"kotlin-build-tools-impl-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/1.9.22/kotlin-build-tools-impl-1.9.22.jar",
"hash": "sha256-G0jW3gQqUl9jtVdROuEmbWmTSCJbAT+UDjLGPeJolCg="
"org.jetbrains.kotlin:kotlin-build-tools-impl:1.9.24": {
"kotlin-build-tools-impl-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/1.9.24/kotlin-build-tools-impl-1.9.24.jar",
"hash": "sha256-VPyCvEOOGGoMEGH55uYZEQuozUnFH6GOcFb726IpFhc="
},
"kotlin-build-tools-impl-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/1.9.22/kotlin-build-tools-impl-1.9.22.pom",
"hash": "sha256-tWM/E0m+lcdHRuHimiqm51LoneGrmmUjSS85j6aVWN0="
"kotlin-build-tools-impl-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-build-tools-impl/1.9.24/kotlin-build-tools-impl-1.9.24.pom",
"hash": "sha256-WI+dA6B9qcDw3JZu6OWqjBEhsUf+1MdxsdwSTMnLONc="
}
},
"org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22": {
"kotlin-compiler-embeddable-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.9.22/kotlin-compiler-embeddable-1.9.22.jar",
"hash": "sha256-K/6t7lmrGYjDNtvW5l2ZH3Zq4d2Gg/Km3tX6oCefDKA="
"org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.24": {
"kotlin-compiler-embeddable-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.9.24/kotlin-compiler-embeddable-1.9.24.jar",
"hash": "sha256-5x/xnmsUGrhakyj9AQlBUxowJUMCa9QkTJWtwgjVAfY="
},
"kotlin-compiler-embeddable-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.9.22/kotlin-compiler-embeddable-1.9.22.pom",
"hash": "sha256-s9o0u29ClqzzoPRDRm8FBsbJnaXNliTW4LdFsiKHhOs="
"kotlin-compiler-embeddable-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.9.24/kotlin-compiler-embeddable-1.9.24.pom",
"hash": "sha256-1w0fiFkkQ/R1eVFUVqTWwxBRztoK0RRGkjrK/kwMldE="
}
},
"org.jetbrains.kotlin:kotlin-compiler-runner:1.9.22": {
"kotlin-compiler-runner-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.9.22/kotlin-compiler-runner-1.9.22.jar",
"hash": "sha256-c+x1u5nr/6iySiSjuFPz9mCWvEapNRrw2sk967acFes="
"org.jetbrains.kotlin:kotlin-compiler-runner:1.9.24": {
"kotlin-compiler-runner-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-runner/1.9.24/kotlin-compiler-runner-1.9.24.jar",
"hash": "sha256-g4Q5dMH/0NNmbTxkk0Hb/TB32eFAZlVKakR7laMB3S0="
},
"kotlin-compiler-runner-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-runner/1.9.22/kotlin-compiler-runner-1.9.22.pom",
"hash": "sha256-pO6KZ8HW8lODjAAnKAvLgFCsDc3MrZdIlhOKaaAX6wE="
"kotlin-compiler-runner-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-runner/1.9.24/kotlin-compiler-runner-1.9.24.pom",
"hash": "sha256-wb508udfB+SamqaJA+DctogA0iRkBBi0hHfuQsvDWQQ="
}
},
"org.jetbrains.kotlin:kotlin-daemon-client:1.9.22": {
"kotlin-daemon-client-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-client/1.9.22/kotlin-daemon-client-1.9.22.jar",
"hash": "sha256-XXPhgVsRZ+Sv4gjwCyp1wIC8WoEHhsqtuOFHh1k6k7k="
"org.jetbrains.kotlin:kotlin-daemon-client:1.9.24": {
"kotlin-daemon-client-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-client/1.9.24/kotlin-daemon-client-1.9.24.jar",
"hash": "sha256-WIqveo7Y55uL8+qLknj/Enii1ZKFpF4Jjxz8v7Dc080="
},
"kotlin-daemon-client-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-client/1.9.22/kotlin-daemon-client-1.9.22.pom",
"hash": "sha256-YsRKZZ2lXbb7El4pKbmNUEow4fSvgU4I5JIUJqpST4o="
"kotlin-daemon-client-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-client/1.9.24/kotlin-daemon-client-1.9.24.pom",
"hash": "sha256-tv4ne9GuP/zAzriOxmZZmHpc0TeaiXaDEvXe3x8uH+U="
}
},
"org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22": {
"kotlin-daemon-embeddable-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.9.22/kotlin-daemon-embeddable-1.9.22.jar",
"hash": "sha256-kqV4ExcUR9U0Rh+hP+N9yM07f4bYPpsfe7GwvjBUH4s="
"org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.24": {
"kotlin-daemon-embeddable-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.9.24/kotlin-daemon-embeddable-1.9.24.jar",
"hash": "sha256-F3vIsqQHbcznh4rQ2P0HFjrzF44/qQ7mPU9zO7R7/ck="
},
"kotlin-daemon-embeddable-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.9.22/kotlin-daemon-embeddable-1.9.22.pom",
"hash": "sha256-9uo9z2v7Og0GmER8SKa88I2Oqs+D/JX+nUGBpeXjwrE="
"kotlin-daemon-embeddable-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.9.24/kotlin-daemon-embeddable-1.9.24.pom",
"hash": "sha256-T7V/xqxyCVGzIkd0s7sqVFSelj0vTf3GhB6Ex77WKrE="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22": {
"kotlin-gradle-plugin-1.9.22-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.22/kotlin-gradle-plugin-1.9.22-gradle82.jar",
"hash": "sha256-1OcY3V8wxrqTLZPM/FswFendPkQUOgUrh3Ao8frlQtw="
"org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24": {
"kotlin-gradle-plugin-1.9.24-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.24/kotlin-gradle-plugin-1.9.24-gradle82.jar",
"hash": "sha256-6K7ZqBLmU2zu+z7VaPE0ZPoF8ka/0TaTONZDyDKUAks="
},
"kotlin-gradle-plugin-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.22/kotlin-gradle-plugin-1.9.22.module",
"hash": "sha256-pPRqwMq9jVzbaJ0tN9GdWFhPcIv59k/+TpgKL/dTS7U="
"kotlin-gradle-plugin-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.24/kotlin-gradle-plugin-1.9.24.module",
"hash": "sha256-txNZQoRrVH+xtZaGQXBGPC81+hW1qtkzX60P/YamE3s="
},
"kotlin-gradle-plugin-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.22/kotlin-gradle-plugin-1.9.22.pom",
"hash": "sha256-A3750tSupA9JKdglE1g+STwOBRVuDaix1/Ujurhobyc="
"kotlin-gradle-plugin-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.9.24/kotlin-gradle-plugin-1.9.24.pom",
"hash": "sha256-ilwTAHAhV//cHyV1hDZZbsVsM3Z8GqLouOskamWs9SM="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.22": {
"kotlin-gradle-plugin-annotations-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-annotations/1.9.22/kotlin-gradle-plugin-annotations-1.9.22.jar",
"hash": "sha256-lnaDy5jZkQFFYH+/W0VilbQ/Cq+Tsbunv2mS5zHLJOw="
"org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.24": {
"kotlin-gradle-plugin-annotations-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-annotations/1.9.24/kotlin-gradle-plugin-annotations-1.9.24.jar",
"hash": "sha256-syBxajMCclSau65oGoD14P5YBLo5TQ8kW1s3f6JWNVk="
},
"kotlin-gradle-plugin-annotations-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-annotations/1.9.22/kotlin-gradle-plugin-annotations-1.9.22.pom",
"hash": "sha256-Y7por+B4/3D3CPnpecaTxFv+iQQfeWQbC4H2tKEm7rs="
"kotlin-gradle-plugin-annotations-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-annotations/1.9.24/kotlin-gradle-plugin-annotations-1.9.24.pom",
"hash": "sha256-fHb3hHzJ5bWOGoJbbqAZV7QoHpHmzXBcFmy+afvDtYs="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.22": {
"kotlin-gradle-plugin-api-1.9.22-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.22/kotlin-gradle-plugin-api-1.9.22-gradle82.jar",
"hash": "sha256-7P9nVGBlxg4JX7k7P4i5uS7R7cN+P+u8b57TVCL6QSs="
"org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.24": {
"kotlin-gradle-plugin-api-1.9.24-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.24/kotlin-gradle-plugin-api-1.9.24-gradle82.jar",
"hash": "sha256-LV53JHoKf1klIL64gx6OPrl0m/OIhfgv+9Y8f/BRPhI="
},
"kotlin-gradle-plugin-api-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.22/kotlin-gradle-plugin-api-1.9.22.jar",
"hash": "sha256-7P9nVGBlxg4JX7k7P4i5uS7R7cN+P+u8b57TVCL6QSs="
"kotlin-gradle-plugin-api-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.24/kotlin-gradle-plugin-api-1.9.24.jar",
"hash": "sha256-LV53JHoKf1klIL64gx6OPrl0m/OIhfgv+9Y8f/BRPhI="
},
"kotlin-gradle-plugin-api-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.22/kotlin-gradle-plugin-api-1.9.22.module",
"hash": "sha256-H0SJxTBPmlEqVof/zAqvCTCvydcgUdOpBfrAcANi+3s="
"kotlin-gradle-plugin-api-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.24/kotlin-gradle-plugin-api-1.9.24.module",
"hash": "sha256-kB+s0LsPLdJ9XzvJDkQvJ3OrEuHOcgnT78HlhWNsfWQ="
},
"kotlin-gradle-plugin-api-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.22/kotlin-gradle-plugin-api-1.9.22.pom",
"hash": "sha256-ZAFewaGutVCqGCjCQuIoODDFD2g2TkCDH+FYj9wEEfU="
"kotlin-gradle-plugin-api-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.9.24/kotlin-gradle-plugin-api-1.9.24.pom",
"hash": "sha256-r9FlfZ0Vx2BxZ1InnZEdG73PjfTPXZYEUGHjCunBMX4="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.22": {
"kotlin-gradle-plugin-idea-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.22/kotlin-gradle-plugin-idea-1.9.22.jar",
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.24": {
"kotlin-gradle-plugin-idea-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.24/kotlin-gradle-plugin-idea-1.9.24.jar",
"hash": "sha256-jRr4djLZUUjxIqn6CuKQPBnub6t9AeAX924NLJoCLCA="
},
"kotlin-gradle-plugin-idea-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.22/kotlin-gradle-plugin-idea-1.9.22.module",
"hash": "sha256-z+LCbjMPaAMsAD+lJMAx5aYPzo2Jn/8uQjFBKL60QCs="
"kotlin-gradle-plugin-idea-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.24/kotlin-gradle-plugin-idea-1.9.24.module",
"hash": "sha256-4Jx9wdImjqtl5EGtLjgWDzGHsNjAv5zxrUyF+nUjm6Q="
},
"kotlin-gradle-plugin-idea-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.22/kotlin-gradle-plugin-idea-1.9.22.pom",
"hash": "sha256-3BSjKHVDun5QRs1OCVAtJ4hMqYfshwb1+xid54luOsw="
"kotlin-gradle-plugin-idea-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.9.24/kotlin-gradle-plugin-idea-1.9.24.pom",
"hash": "sha256-aTnfzQ6JgI3AA25alaOPcb+EKF53bpEFIdVWJnp8sMc="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.22": {
"kotlin-gradle-plugin-idea-proto-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.9.22/kotlin-gradle-plugin-idea-proto-1.9.22.jar",
"hash": "sha256-9dgu5hlmotmK364Z8k1hcwIsFUBIls3yNjQANe5owPU="
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.24": {
"kotlin-gradle-plugin-idea-proto-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.9.24/kotlin-gradle-plugin-idea-proto-1.9.24.jar",
"hash": "sha256-hR4BJ+5ixRDpf4UB6Q/V6yTQ15bHCcv5SvM5R0Fre/4="
},
"kotlin-gradle-plugin-idea-proto-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.9.22/kotlin-gradle-plugin-idea-proto-1.9.22.pom",
"hash": "sha256-huMsqCkn2ogKHPNDpA7MIJgHXm/XInOzTVDfpUTzRjs="
"kotlin-gradle-plugin-idea-proto-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.9.24/kotlin-gradle-plugin-idea-proto-1.9.24.pom",
"hash": "sha256-3gafD+sze0Nbc/GdKaISONBW5oegumvivczlmvqSa7Y="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.22": {
"kotlin-gradle-plugin-model-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.22/kotlin-gradle-plugin-model-1.9.22.jar",
"hash": "sha256-UQj61b4UmCXs46ABA8PCHPGv6VS7ZLhweJVyk511OMs="
"org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.24": {
"kotlin-gradle-plugin-model-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.24/kotlin-gradle-plugin-model-1.9.24.jar",
"hash": "sha256-VbEQENUcmcMXybbvXpVJrUhXEhjN5hvYRIGMti0aPxk="
},
"kotlin-gradle-plugin-model-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.22/kotlin-gradle-plugin-model-1.9.22.module",
"hash": "sha256-L/MBPfK6epteiwBOhIF1DI0PqVOtAHoZbYXSY2cdvq4="
"kotlin-gradle-plugin-model-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.24/kotlin-gradle-plugin-model-1.9.24.module",
"hash": "sha256-cQXlShB2dqp9KAzFqUl0QX4qO1cD1w3WH8yr6wccSug="
},
"kotlin-gradle-plugin-model-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.22/kotlin-gradle-plugin-model-1.9.22.pom",
"hash": "sha256-gfUmlHml2X7oeSpITIMr495DgggSZxlhUAHKyI5C9qg="
"kotlin-gradle-plugin-model-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.9.24/kotlin-gradle-plugin-model-1.9.24.pom",
"hash": "sha256-rquP4uqM+lwumZi1/nU4MaeYfCx4Q6U1MjYqB/pvABg="
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.22": {
"kotlin-gradle-plugins-bom-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugins-bom/1.9.22/kotlin-gradle-plugins-bom-1.9.22.module",
"hash": "sha256-Qj401h0iCxoN3BgUCGqM6rTa2ed5ArDOjLRyG789xu0="
"org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.24": {
"kotlin-gradle-plugins-bom-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugins-bom/1.9.24/kotlin-gradle-plugins-bom-1.9.24.module",
"hash": "sha256-BEh8cNHIzCkBwDdNgarX+k/Rp5NeJa200LH69WkKzNs="
},
"kotlin-gradle-plugins-bom-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugins-bom/1.9.22/kotlin-gradle-plugins-bom-1.9.22.pom",
"hash": "sha256-da2/XHjOJHwiuvNijQs/8c9+19N9YB66cwTXerdb3Z8="
"kotlin-gradle-plugins-bom-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugins-bom/1.9.24/kotlin-gradle-plugins-bom-1.9.24.pom",
"hash": "sha256-wqVTvkQFNLjTMOV69hNjc1WLXgIPppzPsDsuWDx1nAA="
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.22": {
"kotlin-klib-commonizer-api-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.9.22/kotlin-klib-commonizer-api-1.9.22.jar",
"hash": "sha256-jC9lQpwYLi5KLgnLkQ5iuW227tKFWUuPga+CO35ZROI="
"org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.24": {
"kotlin-klib-commonizer-api-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.9.24/kotlin-klib-commonizer-api-1.9.24.jar",
"hash": "sha256-U791bL22Uj3LTA16syrLZBR5bBz0nOQxvkC3DMV9tUk="
},
"kotlin-klib-commonizer-api-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.9.22/kotlin-klib-commonizer-api-1.9.22.pom",
"hash": "sha256-EMrJcNMAo0icM/CzBBVv8DLZWVm+WqrDuIAoKtWGIv4="
"kotlin-klib-commonizer-api-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.9.24/kotlin-klib-commonizer-api-1.9.24.pom",
"hash": "sha256-6pO4z4DdKXdKf7GEeclxH7uWPqhqwjq2FOepQAUsZ34="
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.22": {
"kotlin-klib-commonizer-embeddable-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.9.22/kotlin-klib-commonizer-embeddable-1.9.22.jar",
"hash": "sha256-c/50PnTSEoPTg9C6voX9CMRCr8GnvYgIL42gUQ0FPUs="
"org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable:1.9.24": {
"kotlin-klib-commonizer-embeddable-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.9.24/kotlin-klib-commonizer-embeddable-1.9.24.jar",
"hash": "sha256-AUyBXNeOK4yub4JeHOpPMd6v4HEBOh0G/jZXVzTDA6E="
},
"kotlin-klib-commonizer-embeddable-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.9.22/kotlin-klib-commonizer-embeddable-1.9.22.pom",
"hash": "sha256-dxghItppe2YqSRPX3Z/mu68ATOhH/YZ9oj6v8MTIJEs="
"kotlin-klib-commonizer-embeddable-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.9.24/kotlin-klib-commonizer-embeddable-1.9.24.pom",
"hash": "sha256-yshuQs6nFQwXJJW69k1hWar/vCjFm1+433K+p1iL9Rw="
}
},
"org.jetbrains.kotlin:kotlin-native-utils:1.9.22": {
"kotlin-native-utils-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.9.22/kotlin-native-utils-1.9.22.jar",
"hash": "sha256-eGwSfdVTXbLDmuWXzQsMrZ6RS4PiNvHbAlEjXMnGUqw="
"org.jetbrains.kotlin:kotlin-native-utils:1.9.24": {
"kotlin-native-utils-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.9.24/kotlin-native-utils-1.9.24.jar",
"hash": "sha256-I1WvMJo7FgeymmF02Fe05umxs2EH1sHvu8PMSbpDRQw="
},
"kotlin-native-utils-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.9.22/kotlin-native-utils-1.9.22.pom",
"hash": "sha256-EcUUwF7qOuno4Wq0l5bxEd9DxzSCMeNfr0xCjMT3Q+o="
"kotlin-native-utils-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.9.24/kotlin-native-utils-1.9.24.pom",
"hash": "sha256-uvA25RxRge8Q8wVRXRnfawKWsLcIS0g9I4oImN630i0="
}
},
"org.jetbrains.kotlin:kotlin-project-model:1.9.22": {
"kotlin-project-model-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.9.22/kotlin-project-model-1.9.22.jar",
"hash": "sha256-zBHVwLGQnFsKCP0l7w51T/0r9Wyu9mX7eFEiI15UKhg="
"org.jetbrains.kotlin:kotlin-project-model:1.9.24": {
"kotlin-project-model-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.9.24/kotlin-project-model-1.9.24.jar",
"hash": "sha256-Nri/x5EqvuVIWSxcI5keVRQODS17OhqTTdPOj6Q0+N0="
},
"kotlin-project-model-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.9.22/kotlin-project-model-1.9.22.pom",
"hash": "sha256-659KFngb/ADM7IAw++XuIo5vKydxxQwmezIY/rAGW0A="
"kotlin-project-model-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.9.24/kotlin-project-model-1.9.24.pom",
"hash": "sha256-sF4O4QAsGO3t626JrwfjvheFB9sT2hutbs52vmDz7es="
}
},
"org.jetbrains.kotlin:kotlin-reflect:1.9.24": {
"kotlin-reflect-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.24/kotlin-reflect-1.9.24.jar",
"hash": "sha256-plFmRFu4XvgWzeEnJ5/gAX0rfMQ5s7lyOQ4bc21k6Uw="
},
"kotlin-reflect-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.24/kotlin-reflect-1.9.24.pom",
"hash": "sha256-CghcMAUb1tSrdlrVoMUXnEE7NfdBjyiDFy+9m6GrzMk="
}
},
"org.jetbrains.kotlin:kotlin-reflect:1.9.23": {
@@ -1551,16 +1481,6 @@
"hash": "sha256-WXD72CdKWAyk6I/nhkeMR8i5ufo3TFsK3ekyhFYiX2o="
}
},
"org.jetbrains.kotlin:kotlin-reflect:1.9.22": {
"kotlin-reflect-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.22/kotlin-reflect-1.9.22.jar",
"hash": "sha256-d/MRyhOEgR1Rn9o4n8sSaL2qBY1gUEbg7edsA7DfPpc="
},
"kotlin-reflect-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.9.22/kotlin-reflect-1.9.22.pom",
"hash": "sha256-xxLjWN97kxi2j1RjlxsIhnODf8DKQoXRw4LIEC7da18="
}
},
"org.jetbrains.kotlin:kotlin-reflect:1.8.22": {
"kotlin-reflect-1.8.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.8.22/kotlin-reflect-1.8.22.jar",
@@ -1581,124 +1501,106 @@
"hash": "sha256-V5BVJCdKAK4CiqzMJyg/a8WSWpNKBGwcxdBsjuTW1ak="
}
},
"org.jetbrains.kotlin:kotlin-script-runtime:1.9.22": {
"kotlin-script-runtime-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.9.22/kotlin-script-runtime-1.9.22.jar",
"hash": "sha256-uAZwV59/ktRz2NWDTwsST3dVxFmP6UskQYOwKDSDRXQ="
"org.jetbrains.kotlin:kotlin-script-runtime:1.9.24": {
"kotlin-script-runtime-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.9.24/kotlin-script-runtime-1.9.24.jar",
"hash": "sha256-MUx9MI/nUGVDZbrGFEeAYTyRac89nh2vurkc+AvcNXw="
},
"kotlin-script-runtime-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.9.22/kotlin-script-runtime-1.9.22.pom",
"hash": "sha256-/ra0ns9pEG1MEoXnH5ob2noSfO9oMC4+n9yCmKTjR5U="
"kotlin-script-runtime-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.9.24/kotlin-script-runtime-1.9.24.pom",
"hash": "sha256-mGDF58qg5AlxmVCQEtoD01GX/teewKkKUOKPjeh1QE0="
}
},
"org.jetbrains.kotlin:kotlin-scripting-common:1.9.22": {
"kotlin-scripting-common-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.22/kotlin-scripting-common-1.9.22.jar",
"hash": "sha256-+lAMvwNJQ++BJvPT3GWvCf+Z3//kTFCZtPwu1b8vXcc="
"org.jetbrains.kotlin:kotlin-scripting-common:1.9.24": {
"kotlin-scripting-common-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.24/kotlin-scripting-common-1.9.24.jar",
"hash": "sha256-KqeY6XgokBDYByTdGdn+GQtSQkFIEQT89RjAO8OdTks="
},
"kotlin-scripting-common-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.22/kotlin-scripting-common-1.9.22.pom",
"hash": "sha256-ROURI7DCfm/ZM/wma00Nrw8GhKYq7Z/mhC6Noz8qKz8="
"kotlin-scripting-common-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.9.24/kotlin-scripting-common-1.9.24.pom",
"hash": "sha256-S9rpUqslCWFRsfqERCooGupzwW0dTNVdigLDccqJusQ="
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22": {
"kotlin-scripting-compiler-embeddable-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.9.22/kotlin-scripting-compiler-embeddable-1.9.22.jar",
"hash": "sha256-Ij/shIMCNEmc1MeiPqHJLroSfEGzXZux1LYdJBVa6zU="
"org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.24": {
"kotlin-scripting-compiler-embeddable-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.9.24/kotlin-scripting-compiler-embeddable-1.9.24.jar",
"hash": "sha256-02gR+1yZeXaEH/PQqxnGt96RkomeQIK6Hz/7oH6UBfQ="
},
"kotlin-scripting-compiler-embeddable-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.9.22/kotlin-scripting-compiler-embeddable-1.9.22.pom",
"hash": "sha256-wWCPP7yyqfdSPq0zWZwurc5MgSFhqeBmufSwBa97Qxw="
"kotlin-scripting-compiler-embeddable-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.9.24/kotlin-scripting-compiler-embeddable-1.9.24.pom",
"hash": "sha256-FUgOkd8v/sfFfOHgpfFBBltFIrbbyJsv2yk9xsVwwMU="
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22": {
"kotlin-scripting-compiler-impl-embeddable-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.9.22/kotlin-scripting-compiler-impl-embeddable-1.9.22.jar",
"hash": "sha256-OJkYFqKH/3YkHxp35/ERZIHU6To9tjJZplfd4g5tD2U="
"org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.24": {
"kotlin-scripting-compiler-impl-embeddable-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.9.24/kotlin-scripting-compiler-impl-embeddable-1.9.24.jar",
"hash": "sha256-i/2A2RNqKjJhALC3O/saG7NX7d+uDYEiDkYSa4im7no="
},
"kotlin-scripting-compiler-impl-embeddable-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.9.22/kotlin-scripting-compiler-impl-embeddable-1.9.22.pom",
"hash": "sha256-gmccM6lXsuKoINZqaSwvzmPjvwR/HLJeb7A5HF3c8uc="
"kotlin-scripting-compiler-impl-embeddable-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.9.24/kotlin-scripting-compiler-impl-embeddable-1.9.24.pom",
"hash": "sha256-Sg6yUXF8Sih6ZBfp/QRBZ4xJatxnAdhasPFi8W0s+4c="
}
},
"org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22": {
"kotlin-scripting-jvm-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.9.22/kotlin-scripting-jvm-1.9.22.jar",
"hash": "sha256-jRJ9dvz6BRfDbB6g4ijs4D1aRoJkKgH2R5prvccxKik="
"org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.24": {
"kotlin-scripting-jvm-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.9.24/kotlin-scripting-jvm-1.9.24.jar",
"hash": "sha256-G9aQBgqUhDl3N0pFds2J10nk7srx+3pYA2/rOuVRxKw="
},
"kotlin-scripting-jvm-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.9.22/kotlin-scripting-jvm-1.9.22.pom",
"hash": "sha256-cBJS6huo/4f8M0dqYePVxtnS3aQbqpiZTdaYDuE/vG0="
"kotlin-scripting-jvm-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.9.24/kotlin-scripting-jvm-1.9.24.pom",
"hash": "sha256-kkM+M+MLpFvMS/hKxUsX0p8Dlkp2BwYW1sZS3WxhySU="
}
},
"org.jetbrains.kotlin:kotlin-serialization:1.9.22": {
"kotlin-serialization-1.9.22-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.22/kotlin-serialization-1.9.22-gradle82.jar",
"hash": "sha256-AcrgEEPdT3sLAttWbZPHVoiwlsNAkJ9o0OSVcqvF6VQ="
"org.jetbrains.kotlin:kotlin-serialization:1.9.24": {
"kotlin-serialization-1.9.24-gradle82.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.24/kotlin-serialization-1.9.24-gradle82.jar",
"hash": "sha256-qwl/Ug33fXOXhQfsR6/B2K9ME0tn5hCrfcLLzYrFIFg="
},
"kotlin-serialization-1.9.22.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.22/kotlin-serialization-1.9.22.module",
"hash": "sha256-s3cuUZFg/is2t9G6MkGQYU27lLFZzmBk9M1z+RhhWiI="
"kotlin-serialization-1.9.24.module": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.24/kotlin-serialization-1.9.24.module",
"hash": "sha256-aRNY++5uyvcPyLLR8ic1q21RAErJHEh8Jbdm2xPD74k="
},
"kotlin-serialization-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.22/kotlin-serialization-1.9.22.pom",
"hash": "sha256-D9yUsPEx2Ct3RpAEB0r0f/yntGfVeIn762oVSWg+rL0="
"kotlin-serialization-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-serialization/1.9.24/kotlin-serialization-1.9.24.pom",
"hash": "sha256-5JgomGgooBL/9+I+cSUCASVSzCtmOdx3HgsX2VINhJ0="
}
},
"org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:1.9.22": {
"kotlin-serialization-compiler-plugin-embeddable-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin-embeddable/1.9.22/kotlin-serialization-compiler-plugin-embeddable-1.9.22.jar",
"hash": "sha256-OFR9AAsWYbFLkkZxz7F6tSAL64NOOj2kJ37gkGLppQA="
"org.jetbrains.kotlin:kotlin-serialization-compiler-plugin-embeddable:1.9.24": {
"kotlin-serialization-compiler-plugin-embeddable-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin-embeddable/1.9.24/kotlin-serialization-compiler-plugin-embeddable-1.9.24.jar",
"hash": "sha256-T/XIE76vaHjvBxFIZvU4keMdlscr+XWMvG81CmxNNs0="
},
"kotlin-serialization-compiler-plugin-embeddable-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin-embeddable/1.9.22/kotlin-serialization-compiler-plugin-embeddable-1.9.22.pom",
"hash": "sha256-i8LheiTLbQ4CMzLkjKq5e3P+MyuSdVWhGjAsb1xcPGQ="
"kotlin-serialization-compiler-plugin-embeddable-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-serialization-compiler-plugin-embeddable/1.9.24/kotlin-serialization-compiler-plugin-embeddable-1.9.24.pom",
"hash": "sha256-GWjfZLq2HzC6UvTrMQ0tzFl1IQGbsUL72ZPw5VWk3+k="
}
},
"org.jetbrains.kotlin:kotlin-stdlib:1.9.23": {
"kotlin-stdlib-1.9.23-all.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.23/kotlin-stdlib-1.9.23-all.jar",
"org.jetbrains.kotlin:kotlin-stdlib:1.9.24": {
"kotlin-stdlib-1.9.24-all.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24-all.jar",
"hash": "sha256-zsOLwzAucqiq+c3kNrWpBx7gMx4q0F6E2LuJczTX6dQ="
},
"kotlin-stdlib-1.9.23.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.23/kotlin-stdlib-1.9.23.jar",
"hash": "sha256-iRDMI4gH2G71UMsfCxDdXtQLNaTsGlJSX3YK7ehOrTc="
"kotlin-stdlib-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.jar",
"hash": "sha256-hYuQJpbanPWFq52Y/8HCcSJpgoNU3+kQfjcRsISjZGg="
},
"kotlin-stdlib-1.9.23.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.23/kotlin-stdlib-1.9.23.module",
"hash": "sha256-UZUZOzfc2touHAqw1RLEIrKtdq81V4Q6G5w0gPTnHQ4="
"kotlin-stdlib-1.9.24.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.module",
"hash": "sha256-8uKmVztbUmXEEtXFgfv46gDGKxC5yS1WdMnpfy8zNbM="
},
"kotlin-stdlib-1.9.23.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.23/kotlin-stdlib-1.9.23.pom",
"hash": "sha256-wm0n8mcQrUDiPu2f/gpkuFkejBPSI8ypDFk+5j87KKs="
"kotlin-stdlib-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.24/kotlin-stdlib-1.9.24.pom",
"hash": "sha256-uc6tTCIt7pDHT28BPTFqnlD4EaApMxPDNRrssvfM7V8="
}
},
"org.jetbrains.kotlin:kotlin-stdlib:1.9.22": {
"kotlin-stdlib-1.9.22-all.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22-all.jar",
"hash": "sha256-zsOLwzAucqiq+c3kNrWpBx7gMx4q0F6E2LuJczTX6dQ="
"org.jetbrains.kotlin:kotlin-stdlib-common:1.9.24": {
"kotlin-stdlib-common-1.9.24.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.24/kotlin-stdlib-common-1.9.24.module",
"hash": "sha256-6Y6oxE+zaCDQG7iwAxaOI6IhtAHLQyVtcjo/C3fWFsI="
},
"kotlin-stdlib-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22.jar",
"hash": "sha256-ar4UbCeGQTi4dMzM/l9TTj65I8maG3tdRUlO5WlPPgo="
},
"kotlin-stdlib-1.9.22.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22.module",
"hash": "sha256-9IIxS1B5wUVfb7DUJXp0XRAcYSTOlhUiuob53JCQHkc="
},
"kotlin-stdlib-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.9.22/kotlin-stdlib-1.9.22.pom",
"hash": "sha256-zOLxUoXsgHijd0a1cwigVAQt1cwlQgxD9zt4V8JGjwM="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23": {
"kotlin-stdlib-common-1.9.23.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.23/kotlin-stdlib-common-1.9.23.module",
"hash": "sha256-hjnwBfqZd67wjDL8jnonedoi7iYkZNcnMpiq/Ug3Fc0="
},
"kotlin-stdlib-common-1.9.23.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.23/kotlin-stdlib-common-1.9.23.pom",
"hash": "sha256-OuBxRYdw47aGCafTGet5emeJ9fBAyqQUQJgJmGhb5PY="
"kotlin-stdlib-common-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.9.24/kotlin-stdlib-common-1.9.24.pom",
"hash": "sha256-XZfiDNWGLoR6aYF1uTno3Fxr11vtmZ1vPU6ghIESFsA="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22": {
@@ -1711,24 +1613,14 @@
"hash": "sha256-10k21oh1ZK63EOhCmLVCB/U+m88jpSrSv6IsIIZ3V2c="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.22": {
"kotlin-stdlib-jdk7-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.22/kotlin-stdlib-jdk7-1.9.22.jar",
"hash": "sha256-+R8kz606dWaIo1Ep5fM1SA0OtAjxVooX9wfCifh2m90="
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.24": {
"kotlin-stdlib-jdk7-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24.jar",
"hash": "sha256-tmmbhQugeJ8ukEJ5zYvce+qRMP/RV826AB/HQl2KR7c="
},
"kotlin-stdlib-jdk7-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.22/kotlin-stdlib-jdk7-1.9.22.pom",
"hash": "sha256-SHnKgQKDPIraP0bHep/6+uGXDK/AvGIfUSAbatl0zp0="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.21": {
"kotlin-stdlib-jdk7-1.9.21.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.21/kotlin-stdlib-jdk7-1.9.21.jar",
"hash": "sha256-v+IfQkbIvKNQsYQEBv+803awXto36ypksBHeGMLKeBg="
},
"kotlin-stdlib-jdk7-1.9.21.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.21/kotlin-stdlib-jdk7-1.9.21.pom",
"hash": "sha256-AVFiDhh0XvJ2ECNw/GdHBPcN821kgsxBmh5S263Cg2I="
"kotlin-stdlib-jdk7-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.9.24/kotlin-stdlib-jdk7-1.9.24.pom",
"hash": "sha256-RYapN9W8vDqzBCwECaHHKWFLy6PHpylvJS1ibuNzh9Q="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.22": {
@@ -1741,24 +1633,14 @@
"hash": "sha256-T5WKqZPVmE+PXr7UFGVipfOp9pW2BJyfKHOBN5ytqzM="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.22": {
"kotlin-stdlib-jdk8-1.9.22.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.22/kotlin-stdlib-jdk8-1.9.22.jar",
"hash": "sha256-RwRsPtwy/g2xo2v+PTgilYu1vkQRxbqA866JWj7CcpE="
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.24": {
"kotlin-stdlib-jdk8-1.9.24.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24.jar",
"hash": "sha256-W1u/s+EYS14TMXw9QiN/okrdRDsud4GWHuozTbE2rbE="
},
"kotlin-stdlib-jdk8-1.9.22.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.22/kotlin-stdlib-jdk8-1.9.22.pom",
"hash": "sha256-yUBIJZxtAAdXi6r+tx74/3ut6wjy1ZQ3/DllHg+396s="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.21": {
"kotlin-stdlib-jdk8-1.9.21.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.21/kotlin-stdlib-jdk8-1.9.21.jar",
"hash": "sha256-BwLWS6qpDlxW5GdzeCTJvjreHlFWJHPBQ60DWByVUSc="
},
"kotlin-stdlib-jdk8-1.9.21.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.21/kotlin-stdlib-jdk8-1.9.21.pom",
"hash": "sha256-J79Q6ETwZc0emFT8m8K9pRIrh4ZOoDBL1pW7En0AMvQ="
"kotlin-stdlib-jdk8-1.9.24.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.9.24/kotlin-stdlib-jdk8-1.9.24.pom",
"hash": "sha256-BuBt70n5aq9uXD7EKDauWdbi2mJUcAkUKBZ1Z53J8qU="
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.22": {
@@ -1771,46 +1653,46 @@
"hash": "sha256-ko8hhyF0djE8uBbUgHC8dlSqO5pa6B0/xfjCecyPjZ4="
}
},
"org.jetbrains.kotlin:kotlin-tooling-core:1.9.22": {
"kotlin-tooling-core-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.22/kotlin-tooling-core-1.9.22.jar",
"org.jetbrains.kotlin:kotlin-tooling-core:1.9.24": {
"kotlin-tooling-core-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.24/kotlin-tooling-core-1.9.24.jar",
"hash": "sha256-iTjrl+NjINqj5vsqYP0qBbIy/0pVcXPFAZ8EW4gy2fQ="
},
"kotlin-tooling-core-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.22/kotlin-tooling-core-1.9.22.pom",
"hash": "sha256-FPx/NcY15fzRvqU3q0+kQxLoQyUtUzNRnjaxJeoImyE="
"kotlin-tooling-core-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.9.24/kotlin-tooling-core-1.9.24.pom",
"hash": "sha256-dbytE+kWgPzwEsjuGqGqxxn1m2IbOUyj/DLGJf+YclY="
}
},
"org.jetbrains.kotlin:kotlin-util-io:1.9.22": {
"kotlin-util-io-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.9.22/kotlin-util-io-1.9.22.jar",
"hash": "sha256-9telhJGjeLCDrRvq1IikheEdFgsx52wYwa1SDx0o9Gs="
"org.jetbrains.kotlin:kotlin-util-io:1.9.24": {
"kotlin-util-io-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.9.24/kotlin-util-io-1.9.24.jar",
"hash": "sha256-u0z0H/UG5Q+bLDQiBkmIFupO3f6ImYqQtotDlLT6xfo="
},
"kotlin-util-io-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.9.22/kotlin-util-io-1.9.22.pom",
"hash": "sha256-ZP1qINbsBAE7ttdWJ/ZYC7c2QdlIkJ1cFmTi53MQbe4="
"kotlin-util-io-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.9.24/kotlin-util-io-1.9.24.pom",
"hash": "sha256-82VnN3kyTzMtOTkMeAd1h4BNEeznKv5K7uMlOtZTPFE="
}
},
"org.jetbrains.kotlin:kotlin-util-klib:1.9.22": {
"kotlin-util-klib-1.9.22.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.9.22/kotlin-util-klib-1.9.22.jar",
"hash": "sha256-pnnuL1EPOrkmkYGN5etbCQLobYjJdnTn20TcTyJSxfk="
"org.jetbrains.kotlin:kotlin-util-klib:1.9.24": {
"kotlin-util-klib-1.9.24.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.9.24/kotlin-util-klib-1.9.24.jar",
"hash": "sha256-4NqKfwZIV8BIOmVyfRYtPtV84m1+R3ix8ADg0MDck3E="
},
"kotlin-util-klib-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.9.22/kotlin-util-klib-1.9.22.pom",
"hash": "sha256-Dep9//Cit0CIrJlwQ8vCQINdK/9Zs5/MiwysbqPrNpc="
"kotlin-util-klib-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.9.24/kotlin-util-klib-1.9.24.pom",
"hash": "sha256-krQjr9XnKbsRT3G1ip4DhF3+K9pWJFTrvbg8nYOyMHE="
}
},
"org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.9.22": {
"org.jetbrains.kotlin.jvm.gradle.plugin-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.9.22/org.jetbrains.kotlin.jvm.gradle.plugin-1.9.22.pom",
"hash": "sha256-HLTsuTPJGbL7/XZe/KX+SQeghxLoyZQsM6IIsrFpsYw="
"org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin:1.9.24": {
"org.jetbrains.kotlin.jvm.gradle.plugin-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.9.24/org.jetbrains.kotlin.jvm.gradle.plugin-1.9.24.pom",
"hash": "sha256-7v934tgCArrgxdMiTdws8lklMcyyuJL2uFSyMd+fEBU="
}
},
"org.jetbrains.kotlin.plugin.serialization:org.jetbrains.kotlin.plugin.serialization.gradle.plugin:1.9.22": {
"org.jetbrains.kotlin.plugin.serialization.gradle.plugin-1.9.22.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/plugin/serialization/org.jetbrains.kotlin.plugin.serialization.gradle.plugin/1.9.22/org.jetbrains.kotlin.plugin.serialization.gradle.plugin-1.9.22.pom",
"hash": "sha256-+9WDi7OolDJys/EfhJrIlDeJL9MJstA012QjjEVPoyI="
"org.jetbrains.kotlin.plugin.serialization:org.jetbrains.kotlin.plugin.serialization.gradle.plugin:1.9.24": {
"org.jetbrains.kotlin.plugin.serialization.gradle.plugin-1.9.24.pom": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlin/plugin/serialization/org.jetbrains.kotlin.plugin.serialization.gradle.plugin/1.9.24/org.jetbrains.kotlin.plugin.serialization.gradle.plugin-1.9.24.pom",
"hash": "sha256-4VQlt07TxI1q7g8h3u9MQ5npbV4lZ3vxVZVNOBYRZII="
}
},
"org.jetbrains.kotlinx:atomicfu:0.23.1": {
@@ -1859,20 +1741,6 @@
"hash": "sha256-+IkY2/qHh8TRcasCVToUrR3viqmwxcLCDMmUVdMkHiI="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0": {
"kotlinx-coroutines-core-1.8.0.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.8.0/kotlinx-coroutines-core-1.8.0.jar",
"hash": "sha256-IKpDS2qTDqZtLmGwDe764J/qPTL5ZA0uDCcTEogOCt0="
},
"kotlinx-coroutines-core-1.8.0.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.8.0/kotlinx-coroutines-core-1.8.0.module",
"hash": "sha256-FE7s1TZd4+MNe0YibAWAUeOZVbXBieMfpMfP+5nWILo="
},
"kotlinx-coroutines-core-1.8.0.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core/1.8.0/kotlinx-coroutines-core-1.8.0.pom",
"hash": "sha256-yglaS/iLR0+trOgzLBCXC3nLgBu/XfBHo5Ov4Ql28yE="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.1": {
"kotlinx-coroutines-core-jvm-1.8.1.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.1/kotlinx-coroutines-core-jvm-1.8.1.jar",
@@ -1887,20 +1755,6 @@
"hash": "sha256-R8alCxQVHo+vfzUKlSNcN9EqvDi/sFW2aJdCkxctryw="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0": {
"kotlinx-coroutines-core-jvm-1.8.0.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.jar",
"hash": "sha256-mGCQahk3SQv187BtLw4Q70UeZblbJp8i2vaKPR9QZcU="
},
"kotlinx-coroutines-core-jvm-1.8.0.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.module",
"hash": "sha256-/2oi2kAECTh1HbCuIRd+dlF9vxJqdnlvVCZye/dsEig="
},
"kotlinx-coroutines-core-jvm-1.8.0.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.8.0/kotlinx-coroutines-core-jvm-1.8.0.pom",
"hash": "sha256-pWM6vVNGfOuRYi2B8umCCAh3FF4LduG3V4hxVDSIXQs="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0": {
"kotlinx-coroutines-core-jvm-1.5.0.jar": {
"url": "https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.jar",
@@ -1929,20 +1783,6 @@
"hash": "sha256-x9+Ci/O0+ofumYH7ATaN1NwHmV0XzLqPpmEhcTwF69Q="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-debug:1.8.0": {
"kotlinx-coroutines-debug-1.8.0.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-debug/1.8.0/kotlinx-coroutines-debug-1.8.0.jar",
"hash": "sha256-Zy1UU0UXCoyrgoeygZRL55DWdUWXK+vdVKor9MhsxT8="
},
"kotlinx-coroutines-debug-1.8.0.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-debug/1.8.0/kotlinx-coroutines-debug-1.8.0.module",
"hash": "sha256-piquUrrd+ncw5Wey6kHzYOoQqbN8FiJDqNIaWnySHGI="
},
"kotlinx-coroutines-debug-1.8.0.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-debug/1.8.0/kotlinx-coroutines-debug-1.8.0.pom",
"hash": "sha256-EZPR60nUsUgNqlrGIBctfcmZFidM2Ra+NpQVLA5vb3w="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.8.1": {
"kotlinx-coroutines-jdk8-1.8.1.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-jdk8/1.8.1/kotlinx-coroutines-jdk8-1.8.1.jar",
@@ -1958,10 +1798,6 @@
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:1.8.0": {
"kotlinx-coroutines-jdk8-1.8.0.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-jdk8/1.8.0/kotlinx-coroutines-jdk8-1.8.0.jar",
"hash": "sha256-2EGf2zy6quxAfmKrFL5WQ20edrW/MyRMV2VWH8E/0Gs="
},
"kotlinx-coroutines-jdk8-1.8.0.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-jdk8/1.8.0/kotlinx-coroutines-jdk8-1.8.0.module",
"hash": "sha256-HKyxz+5adTBFR1rzCF+4DcnMzjA3VKnVIApB3/W+AOk="
@@ -2015,32 +1851,12 @@
"hash": "sha256-4qht+xaCAWeYuVoPAGy0tdAQRsVaAS6hs2vSAjLcVXQ="
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-test-jvm:1.8.0": {
"kotlinx-coroutines-test-jvm-1.8.0.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-test-jvm/1.8.0/kotlinx-coroutines-test-jvm-1.8.0.jar",
"hash": "sha256-FTXMH0MjXYVm+NW8bRwR8HBBF+TlY/Ls5+aqPmhpXyA="
},
"kotlinx-coroutines-test-jvm-1.8.0.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-test-jvm/1.8.0/kotlinx-coroutines-test-jvm-1.8.0.module",
"hash": "sha256-HS0Zc6L0GowMEmPmCyXneS9ji4xV18ocbQZztkvlfac="
},
"kotlinx-coroutines-test-jvm-1.8.0.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-coroutines-test-jvm/1.8.0/kotlinx-coroutines-test-jvm-1.8.0.pom",
"hash": "sha256-BtHlPqNm5to7FxkwV1+RYnzxnkUqTnqfDeMNLwQdZFE="
}
},
"org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.3": {
"kotlinx-serialization-bom-1.6.3.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-bom/1.6.3/kotlinx-serialization-bom-1.6.3.pom",
"hash": "sha256-KdaYQrt9RJviqkreakp85qpVgn0KsT0Wh0X+bZVzkzI="
}
},
"org.jetbrains.kotlinx:kotlinx-serialization-bom:1.6.2": {
"kotlinx-serialization-bom-1.6.2.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-bom/1.6.2/kotlinx-serialization-bom-1.6.2.pom",
"hash": "sha256-ew4dde6GIUmc+VQwyhL9qjL0p/kg1cMBv+lfoYfyczc="
}
},
"org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3": {
"kotlinx-serialization-core-1.6.3.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core/1.6.3/kotlinx-serialization-core-1.6.3.jar",
@@ -2055,16 +1871,6 @@
"hash": "sha256-0tv2/BU2TIlp1qq24+zMdROZU/LMBXtzDjUmdGWztX4="
}
},
"org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.2": {
"kotlinx-serialization-core-1.6.2.module": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core/1.6.2/kotlinx-serialization-core-1.6.2.module",
"hash": "sha256-arz0gTrJTfA3AS4xZzaKNEUHD9+OqyHQjYhtTtnC+2c="
},
"kotlinx-serialization-core-1.6.2.pom": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core/1.6.2/kotlinx-serialization-core-1.6.2.pom",
"hash": "sha256-BibddZLIUwKToOPoHgiBltNRh3o422hHaTY3S6ZJ+S8="
}
},
"org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.6.3": {
"kotlinx-serialization-core-jvm-1.6.3.jar": {
"url": "https://repo.maven.apache.org/maven2/org/jetbrains/kotlinx/kotlinx-serialization-core-jvm/1.6.3/kotlinx-serialization-core-jvm-1.6.3.jar",

View File

@@ -19,123 +19,143 @@
# '';
# }
{ lib
, stdenv
, buildEnv
, fetchs3
, fetchurl
, gradle
, maven
, runCommandLocal
, symlinkJoin
, writeText
, writeTextDir
{
lib,
stdenv,
buildEnv,
fetchs3,
fetchurl,
gradle,
maven,
runCommandLocal,
symlinkJoin,
writeText,
writeTextDir,
}:
let defaultGradle = gradle; in
let
defaultGradle = gradle;
in
{
# Path to the lockfile generated by gradle2nix (e.g. gradle.lock).
lockFile ? null
, pname ? "project"
, version ? null
, enableParallelBuilding ? true
# The Gradle package to use. Default is 'pkgs.gradle'.
, gradle ? defaultGradle
# Arguments to Gradle used to build the project in buildPhase.
, gradleFlags ? [ "build" ]
# Enable debugging for the Gradle build; this will cause Gradle to run
# a debug server and wait for a JVM debugging client to attach.
, enableDebug ? false
# Additional code to run in the Gradle init script (init.gradle).
, extraInit ? ""
# Override the default JDK used to run Gradle itself.
, buildJdk ? null
# Override functions which fetch dependency artifacts.
# Keys in this set are URL schemes such as "https" or "s3".
# Values are functions which take a dependency in the form
# `{ urls, hash }` and fetch into the Nix store. For example:
#
# {
# s3 = { name, urls, hash }: fetchs3 {
# s3url = builtins.head urls;
# # TODO This doesn't work without patching fetchs3 to accept SRI hashes
# inherit name hash;
# region = "us-west-2";
# credentials = {
# access_key_id = "foo";
# secret_access_key = "bar";
# };
# };
# }
, fetchers ? { }
# Overlays for dependencies in the offline Maven repository.
#
# Acceps an attrset of dependencies (usually parsed from 'lockFile'), and produces an attrset
# containing dependencies to merge into the final set.
#
# The attrset is of the form:
#
# {
# "${group}:${module}:${version}" = <derivation>;
# # ...
# }
#
# A dependency derivation unpacks multiple source files into a single Maven-style directory named
# "${out}/${groupPath}/${module}/${version}/", where 'groupPath' is the dependency group ID with dot
# characters ('.') replaced by the path separator ('/').
#
# Examples:
#
# 1. Add or replace a dependency with a single JAR file:
#
# (_: {
# "com.squareup.okio:okio:3.9.0" = fetchurl {
# url = "https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.jar";
# hash = "...";
# downloadToTemmp = true;
# postFetch = "install -Dt $out/com/squareup/okio/okio/3.9.0/ $downloadedFile"
# };
# })
#
# 2. Remove a dependency entirely:
#
# # This works because the result is filtered for values that are derivations.
# (_: {
# "org.apache.log4j:core:2.23.1" = null;
# })
, overlays ? []
, ... } @ args:
lockFile ? null,
pname ? "project",
version ? null,
enableParallelBuilding ? true,
# The Gradle package to use. Default is 'pkgs.gradle'.
gradle ? defaultGradle,
# Arguments to Gradle used to build the project in buildPhase.
gradleFlags ? [ "build" ],
# Enable debugging for the Gradle build; this will cause Gradle to run
# a debug server and wait for a JVM debugging client to attach.
enableDebug ? false,
# Additional code to run in the Gradle init script (init.gradle).
extraInit ? "",
# Override the default JDK used to run Gradle itself.
buildJdk ? null,
# Override functions which fetch dependency artifacts.
# Keys in this set are URL schemes such as "https" or "s3".
# Values are functions which take a dependency in the form
# `{ urls, hash }` and fetch into the Nix store. For example:
#
# {
# s3 = { name, urls, hash }: fetchs3 {
# s3url = builtins.head urls;
# # TODO This doesn't work without patching fetchs3 to accept SRI hashes
# inherit name hash;
# region = "us-west-2";
# credentials = {
# access_key_id = "foo";
# secret_access_key = "bar";
# };
# };
# }
fetchers ? { },
# Overlays for dependencies in the offline Maven repository.
#
# Acceps an attrset of dependencies (usually parsed from 'lockFile'), and produces an attrset
# containing dependencies to merge into the final set.
#
# The attrset is of the form:
#
# {
# "${group}:${module}:${version}" = <derivation>;
# # ...
# }
#
# A dependency derivation unpacks multiple source files into a single Maven-style directory named
# "${out}/${groupPath}/${module}/${version}/", where 'groupPath' is the dependency group ID with dot
# characters ('.') replaced by the path separator ('/').
#
# Examples:
#
# 1. Add or replace a dependency with a single JAR file:
#
# (_: {
# "com.squareup.okio:okio:3.9.0" = fetchurl {
# url = "https://repo.maven.apache.org/maven2/com/squareup/okio/okio/3.9.0/okio-3.9.0.jar";
# hash = "...";
# downloadToTemmp = true;
# postFetch = "install -Dt $out/com/squareup/okio/okio/3.9.0/ $downloadedFile"
# };
# })
#
# 2. Remove a dependency entirely:
#
# # This works because the result is filtered for values that are derivations.
# (_: {
# "org.apache.log4j:core:2.23.1" = null;
# })
overlays ? [ ],
...
}@args:
let
inherit (builtins)
attrValues concatStringsSep elemAt filter fromJSON getAttr head length mapAttrs removeAttrs
replaceStrings;
attrValues
concatStringsSep
elemAt
filter
fromJSON
getAttr
head
length
mapAttrs
removeAttrs
replaceStrings
;
inherit (lib)
mapAttrsToList optionalString readFile versionAtLeast versionOlder;
mapAttrsToList
optionalString
readFile
versionAtLeast
versionOlder
;
inherit (lib.strings) sanitizeDerivationName;
toCoordinates = id:
toCoordinates =
id:
let
coords = builtins.split ":" id;
parseVersion = version:
parseVersion =
version:
let
parts = builtins.split ":" version;
base = elemAt parts 0;
in
if length parts >= 2
then
let
snapshot = elemAt parts 2;
in
replaceStrings [ "-SNAPSHOT" ] [ "-${snapshot}" ] base
else
base;
in rec {
if length parts >= 2 then
let
snapshot = elemAt parts 2;
in
replaceStrings [ "-SNAPSHOT" ] [ "-${snapshot}" ] base
else
base;
in
rec {
group = elemAt coords 0;
module = elemAt coords 2;
version = elemAt coords 4;
@@ -150,43 +170,46 @@ let
# Fetch urls using the scheme for the first entry only; there isn't a
# straightforward way to tell Nix to try multiple fetchers in turn
# and short-circuit on the first successful fetch.
fetch = name: { url, hash }:
fetch =
name:
{ url, hash }:
let
scheme = head (builtins.match "([a-z0-9+.-]+)://.*" url);
fetch' = getAttr scheme fetchers';
in
fetch' { inherit url hash; };
fetch' { inherit url hash; };
mkModule = id: artifacts:
mkModule =
id: artifacts:
let
coords = toCoordinates id;
modulePath = "${replaceStrings ["."] ["/"] coords.group}/${coords.module}/${coords.version}";
modulePath = "${replaceStrings [ "." ] [ "/" ] coords.group}/${coords.module}/${coords.version}";
in
stdenv.mkDerivation {
pname = sanitizeDerivationName "${coords.group}-${coords.module}";
version = coords.uniqueVersion;
stdenv.mkDerivation {
pname = sanitizeDerivationName "${coords.group}-${coords.module}";
version = coords.uniqueVersion;
srcs = mapAttrsToList fetch artifacts;
srcs = mapAttrsToList fetch artifacts;
dontPatch = true;
dontConfigure = true;
dontBuild = true;
dontFixup = true;
dontInstall = true;
dontPatch = true;
dontConfigure = true;
dontBuild = true;
dontFixup = true;
dontInstall = true;
preUnpack = ''
mkdir -p "$out/${modulePath}"
'';
preUnpack = ''
mkdir -p "$out/${modulePath}"
'';
unpackCmd = ''
cp "$curSrc" "$out/${modulePath}/$(stripHash "$curSrc")"
'';
unpackCmd = ''
cp "$curSrc" "$out/${modulePath}/$(stripHash "$curSrc")"
'';
sourceRoot = ".";
sourceRoot = ".";
preferLocalBuild = true;
allowSubstitutes = false;
};
preferLocalBuild = true;
allowSubstitutes = false;
};
# Intermediate dependency spec.
#
@@ -195,11 +218,15 @@ let
# derivation created with 'mkModule'. This allows users extra flexibility
# to do things like patching native libraries with patchelf or replacing
# artifacts entirely.
lockedDependencies = final: if lockFile == null then {} else
let
lockedDependencySpecs = fromJSON (readFile lockFile);
in mapAttrs mkModule lockedDependencySpecs;
lockedDependencies =
final:
if lockFile == null then
{ }
else
let
lockedDependencySpecs = fromJSON (readFile lockFile);
in
mapAttrs mkModule lockedDependencySpecs;
finalDependencies =
let
@@ -207,7 +234,7 @@ let
extended = lib.extends composedExtension lockedDependencies;
fixed = lib.fix extended;
in
filter lib.isDerivation (attrValues fixed);
filter lib.isDerivation (attrValues fixed);
offlineRepo = symlinkJoin {
name = if version != null then "${pname}-${version}-gradle-repo" else "${pname}-gradle-repo";
@@ -261,54 +288,68 @@ let
${extraInit}
'';
buildGradlePackage = stdenv.mkDerivation (finalAttrs: {
buildGradlePackage = stdenv.mkDerivation (
finalAttrs:
{
inherit buildJdk enableParallelBuilding enableDebug gradle gradleFlags pname version;
inherit
buildJdk
enableParallelBuilding
enableDebug
gradle
gradleFlags
pname
version
;
dontStrip = true;
dontStrip = true;
nativeBuildInputs = [ finalAttrs.gradle ]
++ lib.optional (finalAttrs.buildJdk != null) finalAttrs.buildJdk;
nativeBuildInputs = [
finalAttrs.gradle
] ++ lib.optional (finalAttrs.buildJdk != null) finalAttrs.buildJdk;
buildPhase = ''
runHook preBuild
buildPhase = ''
runHook preBuild
(
set -eux
(
set -eux
export NIX_OFFLINE_REPO='${offlineRepo}'
export NIX_OFFLINE_REPO='${offlineRepo}'
${optionalString (versionOlder finalAttrs.gradle.version "8.0") ''
# Work around https://github.com/gradle/gradle/issues/1055
TMPHOME="$(mktemp -d)"
mkdir -p "$TMPHOME/init.d"
export GRADLE_USER_HOME="$TMPHOME"
cp ${initScript} $TMPHOME/
''}
${optionalString (versionOlder finalAttrs.gradle.version "8.0") ''
# Work around https://github.com/gradle/gradle/issues/1055
TMPHOME="$(mktemp -d)"
mkdir -p "$TMPHOME/init.d"
export GRADLE_USER_HOME="$TMPHOME"
cp ${initScript} $TMPHOME/
''}
gradle --offline --no-daemon --no-build-cache --no-watch-fs \
--info --full-stacktrace --warning-mode=all \
--no-configuration-cache --console=plain \
-Dmaven.repo.local=${offlineRepo} \
${optionalString finalAttrs.enableParallelBuilding "--parallel"} \
${optionalString finalAttrs.enableDebug "-Dorg.gradle.debug=true"} \
${optionalString (finalAttrs.buildJdk != null) "-Dorg.gradle.java.home=${finalAttrs.buildJdk.home}"} \
--init-script ${initScript} \
${concatStringsSep " " finalAttrs.gradleFlags}
)
gradle --offline --no-daemon --no-build-cache --no-watch-fs \
--info --full-stacktrace --warning-mode=all \
--no-configuration-cache --console=plain \
-Dmaven.repo.local=${offlineRepo} \
${optionalString finalAttrs.enableParallelBuilding "--parallel"} \
${optionalString finalAttrs.enableDebug "-Dorg.gradle.debug=true"} \
${
optionalString (finalAttrs.buildJdk != null) "-Dorg.gradle.java.home=${finalAttrs.buildJdk.home}"
} \
--init-script ${initScript} \
${concatStringsSep " " finalAttrs.gradleFlags}
)
runHook postBuild
'';
passthru = {
inherit offlineRepo;
};
} // removeAttrs args [
"lockFile"
"extraInit"
"fetchers"
"overlays"
]);
runHook postBuild
'';
passthru = {
inherit offlineRepo;
};
}
// removeAttrs args [
"lockFile"
"extraInit"
"fetchers"
"overlays"
]
);
in
buildGradlePackage

View File

@@ -2,4 +2,4 @@ org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.caching=true
org.gradle.configuration-cache=true
VERSION=1.0.0-rc2
VERSION=2.0.0

View File

@@ -1,7 +1,7 @@
[versions]
gradle = "8.7"
junit = "5.8.2"
kotlin = "1.9.22"
kotlin = "1.9.24"
ktor = "2.3.11"
kotest = "5.9.0"
@@ -16,7 +16,7 @@ ktor-server-netty = { module = "io.ktor:ktor-server-netty", version.ref = "ktor"
okio = "com.squareup.okio:okio:3.9.0"
serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
slf4j-simple = "org.slf4j:slf4j-simple:1.7.36"
xmlutil = "io.github.pdvrieze.xmlutil:serialization-jvm:+"
xmlutil = "io.github.pdvrieze.xmlutil:serialization-jvm:0.90.0-RC1"
[plugins]
pluginPublish = { id = "com.gradle.plugin-publish", version = "1.2.1" }

View File

@@ -20,11 +20,12 @@ interface DependencyCoordinates : Serializable {
*/
val timestamp: String?
val id: String get() = if (timestamp != null) {
"$group:$artifact:$version:$timestamp"
} else {
"$group:$artifact:$version"
}
val id: String get() =
if (timestamp != null) {
"$group:$artifact:$version:$timestamp"
} else {
"$group:$artifact:$version"
}
val timestampedCoordinates: DependencyCoordinates

View File

@@ -1,4 +1,4 @@
package org.nixos.gradle2nix.model
const val RESOLVE_PROJECT_TASK = "resolveProjectDependencies"
const val RESOLVE_ALL_TASK = "resolveAllDependencies"
const val RESOLVE_PROJECT_TASK = "resolveProjectArtifacts"
const val RESOLVE_ALL_TASK = "resolveAllArtifacts"

View File

@@ -6,9 +6,8 @@ data class DefaultDependencyCoordinates(
override val group: String,
override val artifact: String,
override val version: String,
override val timestamp: String? = null
override val timestamp: String? = null,
) : DependencyCoordinates {
override val timestampedCoordinates: DependencyCoordinates
get() = DefaultDependencyCoordinates(group, artifact, timestampedVersion)
@@ -21,7 +20,7 @@ data class DefaultDependencyCoordinates(
3 -> DefaultDependencyCoordinates(parts[0], parts[1], parts[2])
4 -> DefaultDependencyCoordinates(parts[0], parts[1], parts[2], parts[3])
else -> throw IllegalStateException(
"couldn't parse dependency coordinates: '$id'"
"couldn't parse dependency coordinates: '$id'",
)
}
}

View File

@@ -4,5 +4,5 @@ import org.nixos.gradle2nix.model.DependencySet
import org.nixos.gradle2nix.model.ResolvedDependency
data class DefaultDependencySet(
override val dependencies: List<ResolvedDependency>
override val dependencies: List<ResolvedDependency>,
) : DependencySet

View File

@@ -1,4 +1,5 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
id("org.jetbrains.kotlin.jvm")
@@ -11,8 +12,6 @@ dependencies {
shadow(kotlin("reflect"))
implementation(project(":model"))
implementation(libs.serialization.json)
testImplementation(libs.kotest.assertions)
testImplementation(libs.kotest.runner)
}
java {
@@ -22,7 +21,10 @@ java {
kotlin {
compilerOptions {
apiVersion.set(KotlinVersion.KOTLIN_1_6)
languageVersion.set(KotlinVersion.KOTLIN_1_6)
jvmTarget.set(JvmTarget.JVM_1_8)
optIn.add("kotlin.RequiresOptIn")
}
}
@@ -56,11 +58,4 @@ tasks {
validatePlugins {
enableStricterValidation.set(true)
}
withType<Test> {
useJUnitPlatform()
testLogging {
events("passed", "skipped", "failed")
}
}
}

View File

@@ -1,7 +1,5 @@
package org.nixos.gradle2nix.dependencygraph
package org.nixos.gradle2nix
import java.io.File
import java.util.concurrent.ConcurrentHashMap
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
@@ -11,6 +9,8 @@ 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.internal.hash.ChecksumService
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
@@ -26,20 +26,52 @@ import org.nixos.gradle2nix.model.impl.DefaultDependencyCoordinates
import org.nixos.gradle2nix.model.impl.DefaultDependencySet
import org.nixos.gradle2nix.model.impl.DefaultResolvedArtifact
import org.nixos.gradle2nix.model.impl.DefaultResolvedDependency
import java.io.File
import java.util.concurrent.ConcurrentHashMap
class DependencyExtractor(
private val artifactCachesProvider: ArtifactCachesProvider,
private val checksumService: ChecksumService,
private val fileStoreAndIndexProvider: FileStoreAndIndexProvider,
) : BuildOperationListener {
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
}
}
class DependencyExtractor : BuildOperationListener {
private val urls = ConcurrentHashMap<String, Unit>()
override fun started(buildOperation: BuildOperationDescriptor, startEvent: OperationStartEvent) {}
override fun started(
buildOperation: BuildOperationDescriptor,
startEvent: OperationStartEvent,
) {}
override fun progress(operationIdentifier: OperationIdentifier, progressEvent: OperationProgressEvent) {}
override fun progress(
operationIdentifier: OperationIdentifier,
progressEvent: OperationProgressEvent,
) {}
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
override fun finished(
buildOperation: BuildOperationDescriptor,
finishEvent: OperationFinishEvent,
) {
when (val details = buildOperation.details) {
is ExternalResourceReadBuildOperationType.Details -> urls.computeIfAbsent(details.location) { Unit }
is ExternalResourceReadMetadataBuildOperationType.Details -> urls.computeIfAbsent(details.location) { Unit }
@@ -47,7 +79,11 @@ class DependencyExtractor(
} ?: return
}
fun buildDependencySet(): DependencySet {
fun buildDependencySet(
artifactCachesProvider: ArtifactCachesProvider,
checksumService: ChecksumService,
fileStoreAndIndexProvider: FileStoreAndIndexProvider,
): DependencySet {
val files = mutableMapOf<DependencyCoordinates, MutableMap<File, String>>()
val mappings = mutableMapOf<DependencyCoordinates, Map<String, String>>()
@@ -69,23 +105,28 @@ class DependencyExtractor(
}
return DefaultDependencySet(
dependencies = buildList {
for ((componentId, componentFiles) in files) {
add(DefaultResolvedDependency(
componentId,
buildList {
val remoteMappings = mappings[componentId]
for ((file, url) in componentFiles) {
add(DefaultResolvedArtifact(
remoteMappings?.get(file.name) ?: file.name,
checksumService.sha256(file).toString(),
url
))
}
}
))
}
}
dependencies =
buildList {
for ((componentId, componentFiles) in files) {
add(
DefaultResolvedDependency(
componentId,
buildList {
val remoteMappings = mappings[componentId]
for ((file, url) in componentFiles) {
add(
DefaultResolvedArtifact(
remoteMappings?.get(file.name) ?: file.name,
checksumService.sha256(file).toString(),
url,
),
)
}
},
),
)
}
},
)
}
}
@@ -98,18 +139,19 @@ private fun cachedComponentId(file: File): DependencyCoordinates? {
}
@OptIn(ExperimentalSerializationApi::class)
private fun parseFileMappings(file: File): Map<String, String>? = try {
Json.decodeFromStream<JsonObject>(file.inputStream())
.jsonObject["variants"]?.jsonArray
?.flatMap { it.jsonObject["files"]?.jsonArray ?: emptyList() }
?.map { it.jsonObject }
?.mapNotNull {
val name = it["name"]?.jsonPrimitive?.content ?: return@mapNotNull null
val url = it["url"]?.jsonPrimitive?.content ?: return@mapNotNull null
name to url
}
?.toMap()
?.takeUnless { it.isEmpty() }
} catch (e: Throwable) {
null
}
private fun parseFileMappings(file: File): Map<String, String>? =
try {
Json.decodeFromStream<JsonObject>(file.inputStream())
.jsonObject["variants"]?.jsonArray
?.flatMap { it.jsonObject["files"]?.jsonArray ?: emptyList() }
?.map { it.jsonObject }
?.mapNotNull {
val name = it["name"]?.jsonPrimitive?.content ?: return@mapNotNull null
val url = it["url"]?.jsonPrimitive?.content ?: return@mapNotNull null
name to url
}
?.toMap()
?.takeUnless { it.isEmpty() }
} catch (e: Throwable) {
null
}

View File

@@ -2,53 +2,91 @@
package org.nixos.gradle2nix
import javax.inject.Inject
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.nixos.gradle2nix.dependencygraph.DependencyExtractor
import org.nixos.gradle2nix.forceresolve.ForceDependencyResolutionPlugin
import org.gradle.util.GradleVersion
import org.nixos.gradle2nix.model.DependencySet
import org.nixos.gradle2nix.util.artifactCachesProvider
import org.nixos.gradle2nix.util.buildOperationListenerManager
import org.nixos.gradle2nix.util.checksumService
import org.nixos.gradle2nix.util.fileStoreAndIndexProvider
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import javax.inject.Inject
abstract class Gradle2NixPlugin @Inject constructor(
private val toolingModelBuilderRegistry: ToolingModelBuilderRegistry
): Plugin<Gradle> {
abstract class Gradle2NixPlugin
@Inject
constructor(
private val toolingModelBuilderRegistry: ToolingModelBuilderRegistry,
) : Plugin<Gradle> {
override fun apply(gradle: Gradle) {
val dependencyExtractor = DependencyExtractor()
override fun apply(gradle: Gradle) {
val dependencyExtractor = DependencyExtractor(
gradle.artifactCachesProvider,
gradle.checksumService,
gradle.fileStoreAndIndexProvider,
)
toolingModelBuilderRegistry.register(
DependencySetModelBuilder(
dependencyExtractor,
gradle.artifactCachesProvider,
gradle.checksumService,
gradle.fileStoreAndIndexProvider,
),
)
toolingModelBuilderRegistry.register(DependencySetModelBuilder(dependencyExtractor))
if (GradleVersion.current() < GradleVersion.version("8.0")) {
val extractor = DependencyExtractor()
gradle.buildOperationListenerManager.addListener(extractor)
gradle.buildOperationListenerManager.addListener(dependencyExtractor)
@Suppress("DEPRECATION")
gradle.buildFinished {
gradle.buildOperationListenerManager.removeListener(extractor)
}
} else {
val serviceProvider =
gradle.sharedServices.registerIfAbsent(
"nixDependencyExtractor",
DependencyExtractorService::class.java,
).map { service ->
service.apply { extractor = dependencyExtractor }
}
// Configuration caching is not enabled with dependency verification so this is fine for now.
// Gradle 9.x might remove this though.
@Suppress("DEPRECATION")
gradle.buildFinished {
gradle.buildOperationListenerManager.removeListener(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"))
}
}
}
}
gradle.pluginManager.apply(ForceDependencyResolutionPlugin::class.java)
}
}
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()
override fun buildAll(
modelName: String,
project: Project,
): DependencySet {
return dependencyExtractor.buildDependencySet(
artifactCachesProvider,
checksumService,
fileStoreAndIndexProvider,
)
}
}

View File

@@ -0,0 +1,42 @@
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

@@ -0,0 +1,66 @@
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()
}
}

View File

@@ -1,15 +0,0 @@
package org.nixos.gradle2nix.forceresolve
import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.Internal
import org.gradle.work.DisableCachingByDefault
import org.nixos.gradle2nix.util.canSafelyBeResolved
@DisableCachingByDefault(because = "Not worth caching")
abstract class AbstractResolveProjectDependenciesTask : DefaultTask() {
@Internal
protected fun getReportableConfigurations(): List<Configuration> {
return project.configurations.filter { it.canSafelyBeResolved() }
}
}

View File

@@ -1,63 +0,0 @@
package org.nixos.gradle2nix.forceresolve
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.invocation.Gradle
import org.gradle.api.tasks.TaskProvider
import org.gradle.util.GradleVersion
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import org.nixos.gradle2nix.model.RESOLVE_PROJECT_TASK
// TODO: Rename these
/**
* Adds a task to resolve all dependencies in a Gradle build tree.
*/
class ForceDependencyResolutionPlugin : Plugin<Gradle> {
override fun apply(gradle: Gradle) {
gradle.projectsEvaluated {
val resolveAllDeps = gradle.rootProject.tasks.register(RESOLVE_ALL_TASK)
// Depend on "dependencies" task in all projects
gradle.allprojects { project ->
val projectTaskFactory = getResolveProjectDependenciesTaskFactory()
val resolveProjectDeps = projectTaskFactory.create(project)
resolveAllDeps.configure { it.dependsOn(resolveProjectDeps) }
}
// Depend on all 'resolveBuildDependencies' task in each included build
gradle.includedBuilds.forEach { includedBuild ->
resolveAllDeps.configure {
it.dependsOn(includedBuild.task(":$RESOLVE_ALL_TASK"))
}
}
}
}
private fun getResolveProjectDependenciesTaskFactory(): ResolveProjectDependenciesTaskFactory {
val gradleVersion = GradleVersion.current()
val gradle8 = GradleVersion.version("8.0")
return if (gradleVersion >= gradle8) {
ResolveProjectDependenciesTaskFactory.Current
} else {
ResolveProjectDependenciesTaskFactory.Legacy
}
}
private sealed interface ResolveProjectDependenciesTaskFactory {
fun create(project: Project): TaskProvider<out Task>
data object Current : ResolveProjectDependenciesTaskFactory {
override fun create(project: Project): TaskProvider<out Task> {
return project.tasks.register(RESOLVE_PROJECT_TASK, ResolveProjectDependenciesTask::class.java)
}
}
data object Legacy : ResolveProjectDependenciesTaskFactory {
override fun create(project: Project): TaskProvider<out Task> {
return project.tasks.register(RESOLVE_PROJECT_TASK, LegacyResolveProjectDependenciesTask::class.java)
}
}
}
}

View File

@@ -1,16 +0,0 @@
package org.nixos.gradle2nix.forceresolve
import org.gradle.api.DefaultTask
import org.gradle.api.artifacts.Configuration
import org.gradle.api.tasks.TaskAction
import org.gradle.work.DisableCachingByDefault
@DisableCachingByDefault(because = "Not worth caching")
abstract class LegacyResolveProjectDependenciesTask : AbstractResolveProjectDependenciesTask() {
@TaskAction
fun action() {
for (configuration in getReportableConfigurations()) {
configuration.incoming.resolutionResult.root
}
}
}

View File

@@ -1,31 +0,0 @@
package org.nixos.gradle2nix.forceresolve
import javax.inject.Inject
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.file.FileCollection
import org.gradle.api.model.ObjectFactory
import org.gradle.api.tasks.TaskAction
import org.gradle.internal.serialization.Cached
import org.gradle.work.DisableCachingByDefault
@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()
}
}

View File

@@ -1,36 +0,0 @@
package org.nixos.gradle2nix.util
import java.lang.reflect.Method
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.hash.ChecksumService
import org.gradle.internal.operations.BuildOperationAncestryTracker
import org.gradle.internal.operations.BuildOperationListenerManager
internal inline val Gradle.artifactCachesProvider: ArtifactCachesProvider
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