From 301c64fa2f99d14e21281e6cef7f234e208bd2e9 Mon Sep 17 00:00:00 2001 From: Tad Fisher Date: Wed, 29 May 2024 17:47:31 -0700 Subject: [PATCH] Miscellaneous cleanup --- .editorconfig | 19 + README.org | 64 +- app/build.gradle.kts | 34 +- .../org/nixos/gradle2nix/GradleRunner.kt | 140 ++-- .../kotlin/org/nixos/gradle2nix/Logger.kt | 31 +- .../main/kotlin/org/nixos/gradle2nix/Main.kt | 183 ++--- .../kotlin/org/nixos/gradle2nix/Process.kt | 37 +- .../kotlin/org/nixos/gradle2nix/Projects.kt | 12 +- .../kotlin/org/nixos/gradle2nix/Version.kt | 134 ++-- .../kotlin/org/nixos/gradle2nix/TestUtil.kt | 101 +-- default.nix | 34 +- .../kotlin/settings.gradle.kts | 1 + .../kotlin/settings.gradle.kts | 1 + .../kotlin/buildSrc/settings.gradle.kts | 1 + .../kotlin/settings.gradle.kts | 1 + .../classifier/kotlin/settings.gradle.kts | 1 + .../maven-bom/kotlin/settings.gradle.kts | 1 + .../kotlin/settings.gradle.kts | 1 + .../snapshot/kotlin/settings.gradle.kts | 1 + .../settings-buildscript/groovy/default.nix | 14 +- .../groovy/gradle-env.nix | 434 ++++++----- .../ivy/basic/kotlin/settings.gradle.kts | 1 + .../kotlin/settings.gradle.kts | 1 + .../maven-snapshot/kotlin/settings.gradle.kts | 1 + .../s3/maven/kotlin/settings.gradle.kts | 1 + .../multi-module/kotlin/settings.gradle.kts | 2 +- flake.lock | 8 +- flake.nix | 53 +- gradle.lock | 734 +++++++----------- gradle.nix | 371 +++++---- gradle.properties | 2 +- gradle/libs.versions.toml | 4 +- .../gradle2nix/model/DependencyCoordinates.kt | 11 +- .../gradle2nix/model/PluginParameters.kt | 4 +- .../impl/DefaultDependencyCoordinates.kt | 5 +- .../model/impl/DefaultDependencySet.kt | 2 +- plugin/build.gradle.kts | 13 +- .../DependencyExtractor.kt | 130 ++-- .../org/nixos/gradle2nix/Gradle2NixPlugin.kt | 96 ++- .../org/nixos/gradle2nix/GradleExtensions.kt | 42 + .../nixos/gradle2nix/ResolveAllArtifacts.kt | 66 ++ .../AbstractResolveProjectDependenciesTask.kt | 15 - .../ForceDependencyResolutionPlugin.kt | 63 -- .../LegacyResolveProjectDependenciesTask.kt | 16 - .../ResolveProjectDependenciesTask.kt | 31 - .../nixos/gradle2nix/util/GradleExtensions.kt | 36 - 46 files changed, 1512 insertions(+), 1441 deletions(-) create mode 100644 .editorconfig rename plugin/src/main/kotlin/org/nixos/gradle2nix/{dependencygraph => }/DependencyExtractor.kt (51%) create mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/GradleExtensions.kt create mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/ResolveAllArtifacts.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/AbstractResolveProjectDependenciesTask.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ForceDependencyResolutionPlugin.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/LegacyResolveProjectDependenciesTask.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ResolveProjectDependenciesTask.kt delete mode 100644 plugin/src/main/kotlin/org/nixos/gradle2nix/util/GradleExtensions.kt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..697e2c3 --- /dev/null +++ b/.editorconfig @@ -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 diff --git a/README.org b/README.org index 07f9b87..80fc3f3 100644 --- a/README.org +++ b/README.org @@ -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 {} }: + +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= Gradle distribution URI - --gradle-home= Gradle home path (e.g. `nix eval nixpkgs#gradle.outPath`/lib/gradle) + --gradle-home= Gradle home path (e.g. `nix eval --raw nixpkgs#gradle.outPath`/lib/gradle) --gradle-wrapper= Gradle wrapper version Options: @@ -108,9 +159,8 @@ Options: -p, --project= Path to the project root (default: Current directory) -o, --out-dir= Path to write generated files (default: ) -l, --lock-file= Name of the generated lock file (default: gradle.lock) - -n, --nix-file= Name of the generated Nix file (default: gradle.nix) - -j, --gradle-jdk= 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= 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 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 91fa305..ef07f6f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -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 { - 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() diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt index fc92bb7..ec82f94 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/GradleRunner.kt @@ -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 { - override fun onComplete(result: GradleBuild) { - continuation.resume(result) + action { controller -> controller.buildModel } + .withCancellationToken(cancellationTokenSource.token()) + .run( + object : ResultHandler { + 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 { - override fun onComplete(result: DependencySet) { - continuation.resume(result) + } } + .run( + object : ResultHandler { + override fun onComplete(result: DependencySet) { + continuation.resume(result) + } - override fun onFailure(failure: GradleConnectionException) { - continuation.resumeWithException(failure) - } - }) -} + override fun onFailure(failure: GradleConnectionException) { + continuation.resumeWithException(failure) + } + }, + ) + } diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt index 13d3eb1..8968abb 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Logger.kt @@ -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 } diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt index b459802..dcb3125 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Main.kt @@ -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, 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 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("") { 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() - .default(LogLevel.error) + help = "Print messages with this priority or higher", + ) + .enum(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 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 = + 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 = buildList { - add(root) - addAll(root.editableBuilds) - } - builds.mapNotNull { build -> - build.rootProject.projectDirectory.resolve("buildSrc").takeIf { it.exists() } - } - } val dependencySets = mutableListOf() @@ -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) } } diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Process.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Process.kt index 481a0dc..3e1f62f 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Process.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Process.kt @@ -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 + dependencySets: Iterable, ): Env { return buildMap> { 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> { 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 = compareBy { it.group } - .thenBy { it.artifact } - .thenByDescending { Version(it.version) } - .thenByDescending { it.timestamp } +private val coordinatesComparator: Comparator = + compareBy { it.group } + .thenBy { it.artifact } + .thenByDescending { Version(it.version) } + .thenByDescending { it.timestamp } diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt index 7beba7f..154b993 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Projects.kt @@ -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) diff --git a/app/src/main/kotlin/org/nixos/gradle2nix/Version.kt b/app/src/main/kotlin/org/nixos/gradle2nix/Version.kt index c583621..89df247 100644 --- a/app/src/main/kotlin/org/nixos/gradle2nix/Version.kt +++ b/app/src/main/kotlin/org/nixos/gradle2nix/Version.kt @@ -3,95 +3,105 @@ package org.nixos.gradle2nix import java.util.concurrent.ConcurrentHashMap class Version(val source: String, val parts: List, base: Version?) : Comparable { - private val base: Version val numericParts: List 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 = 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 = + 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() // From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser - operator fun invoke(original: String): Version = cache.getOrPut(original) { - val parts = mutableListOf() - 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() + 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 } diff --git a/app/src/test/kotlin/org/nixos/gradle2nix/TestUtil.kt b/app/src/test/kotlin/org/nixos/gradle2nix/TestUtil.kt index 4d99c3e..c92b456 100644 --- a/app/src/test/kotlin/org/nixos/gradle2nix/TestUtil.kt +++ b/app/src/test/kotlin/org/nixos/gradle2nix/TestUtil.kt @@ -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, 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) { diff --git a/default.nix b/default.nix index e0009a4..4432960 100644 --- a/default.nix +++ b/default.nix @@ -1,9 +1,11 @@ -{ pkgs ? import {} }: +{ + pkgs ? import { }, +}: 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 diff --git a/fixtures/projects/basic/basic-java-project/kotlin/settings.gradle.kts b/fixtures/projects/basic/basic-java-project/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/basic/basic-java-project/kotlin/settings.gradle.kts +++ b/fixtures/projects/basic/basic-java-project/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/basic/basic-kotlin-project/kotlin/settings.gradle.kts b/fixtures/projects/basic/basic-kotlin-project/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/basic/basic-kotlin-project/kotlin/settings.gradle.kts +++ b/fixtures/projects/basic/basic-kotlin-project/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/buildSrc/settings.gradle.kts b/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/buildSrc/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/buildSrc/settings.gradle.kts +++ b/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/buildSrc/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/settings.gradle.kts b/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/settings.gradle.kts +++ b/fixtures/projects/buildsrc/plugin-in-buildsrc/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/dependency/classifier/kotlin/settings.gradle.kts b/fixtures/projects/dependency/classifier/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/dependency/classifier/kotlin/settings.gradle.kts +++ b/fixtures/projects/dependency/classifier/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/dependency/maven-bom/kotlin/settings.gradle.kts b/fixtures/projects/dependency/maven-bom/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/dependency/maven-bom/kotlin/settings.gradle.kts +++ b/fixtures/projects/dependency/maven-bom/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/dependency/snapshot-dynamic/kotlin/settings.gradle.kts b/fixtures/projects/dependency/snapshot-dynamic/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/dependency/snapshot-dynamic/kotlin/settings.gradle.kts +++ b/fixtures/projects/dependency/snapshot-dynamic/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/dependency/snapshot/kotlin/settings.gradle.kts b/fixtures/projects/dependency/snapshot/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/dependency/snapshot/kotlin/settings.gradle.kts +++ b/fixtures/projects/dependency/snapshot/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/integration/settings-buildscript/groovy/default.nix b/fixtures/projects/integration/settings-buildscript/groovy/default.nix index 292d035..89507f1 100644 --- a/fixtures/projects/integration/settings-buildscript/groovy/default.nix +++ b/fixtures/projects/integration/settings-buildscript/groovy/default.nix @@ -1,9 +1,9 @@ -with (import {}); +with (import { }); let - buildGradle = callPackage ./gradle-env.nix {}; + buildGradle = callPackage ./gradle-env.nix { }; in - buildGradle { - envSpec = ./gradle-env.json; - src = ./.; - gradleFlags = [ "tasks" ]; - } \ No newline at end of file +buildGradle { + envSpec = ./gradle-env.json; + src = ./.; + gradleFlags = [ "tasks" ]; +} diff --git a/fixtures/projects/integration/settings-buildscript/groovy/gradle-env.nix b/fixtures/projects/integration/settings-buildscript/groovy/gradle-env.nix index 9c7f708..c150b9c 100644 --- a/fixtures/projects/integration/settings-buildscript/groovy/gradle-env.nix +++ b/fixtures/projects/integration/settings-buildscript/groovy/gradle-env.nix @@ -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 '' - - - ${groupId} - ${artifactId} - - ${optionalString (latest != "") "${latest}"} - ${optionalString (release != "") "${release}"} - - ${concatMapStringsSep "\n " (v: "${v}") versions'} - - - - '' - ) modules); + with meta; + writeTextDir path '' + + + ${groupId} + ${artifactId} + + ${optionalString (latest != "") "${latest}"} + ${optionalString (release != "") "${release}"} + + ${concatMapStringsSep "\n " (v: "${v}") versions'} + + + + '' + ) 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: '' @@ -148,10 +189,12 @@ let ${optionalString (version.updated != "") "${version.updated}"} ''; - in - attrValues (mapAttrs (path: meta: - with meta; writeTextDir path '' + attrValues ( + mapAttrs ( + path: meta: + with meta; + writeTextDir path '' ${groupId} @@ -169,92 +212,98 @@ let '' - ) 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=' 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; + } +) diff --git a/fixtures/projects/ivy/basic/kotlin/settings.gradle.kts b/fixtures/projects/ivy/basic/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/ivy/basic/kotlin/settings.gradle.kts +++ b/fixtures/projects/ivy/basic/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/plugin/resolves-from-default-repo/kotlin/settings.gradle.kts b/fixtures/projects/plugin/resolves-from-default-repo/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/plugin/resolves-from-default-repo/kotlin/settings.gradle.kts +++ b/fixtures/projects/plugin/resolves-from-default-repo/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/s3/maven-snapshot/kotlin/settings.gradle.kts b/fixtures/projects/s3/maven-snapshot/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/s3/maven-snapshot/kotlin/settings.gradle.kts +++ b/fixtures/projects/s3/maven-snapshot/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/s3/maven/kotlin/settings.gradle.kts b/fixtures/projects/s3/maven/kotlin/settings.gradle.kts index e69de29..d39a25d 100644 --- a/fixtures/projects/s3/maven/kotlin/settings.gradle.kts +++ b/fixtures/projects/s3/maven/kotlin/settings.gradle.kts @@ -0,0 +1 @@ +// Intentionally left empty diff --git a/fixtures/projects/subprojects/multi-module/kotlin/settings.gradle.kts b/fixtures/projects/subprojects/multi-module/kotlin/settings.gradle.kts index 746f7ca..62adbc5 100644 --- a/fixtures/projects/subprojects/multi-module/kotlin/settings.gradle.kts +++ b/fixtures/projects/subprojects/multi-module/kotlin/settings.gradle.kts @@ -1 +1 @@ -include(":child-a", ":child-b") \ No newline at end of file +include(":child-a", ":child-b") diff --git a/flake.lock b/flake.lock index 3b7699d..9336b3f 100644 --- a/flake.lock +++ b/flake.lock @@ -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" } diff --git a/flake.nix b/flake.nix index d8bfb58..9d9554e 100644 --- a/flake.nix +++ b/flake.nix @@ -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 + ''; + } + ); } diff --git a/gradle.lock b/gradle.lock index 3dd2072..b740f49 100644 --- a/gradle.lock +++ b/gradle.lock @@ -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", diff --git a/gradle.nix b/gradle.nix index e5ead69..749e5fd 100644 --- a/gradle.nix +++ b/gradle.nix @@ -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}" = ; -# # ... -# } -# -# 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}" = ; + # # ... + # } + # + # 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 diff --git a/gradle.properties b/gradle.properties index db26ac0..3d9fb41 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5a048ce..ae27794 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" } diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/model/DependencyCoordinates.kt b/model/src/main/kotlin/org/nixos/gradle2nix/model/DependencyCoordinates.kt index 25f0cc1..d952782 100644 --- a/model/src/main/kotlin/org/nixos/gradle2nix/model/DependencyCoordinates.kt +++ b/model/src/main/kotlin/org/nixos/gradle2nix/model/DependencyCoordinates.kt @@ -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 diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/model/PluginParameters.kt b/model/src/main/kotlin/org/nixos/gradle2nix/model/PluginParameters.kt index 51f6157..8906b86 100644 --- a/model/src/main/kotlin/org/nixos/gradle2nix/model/PluginParameters.kt +++ b/model/src/main/kotlin/org/nixos/gradle2nix/model/PluginParameters.kt @@ -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" diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencyCoordinates.kt b/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencyCoordinates.kt index 98bc0c9..46df9da 100644 --- a/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencyCoordinates.kt +++ b/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencyCoordinates.kt @@ -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'", ) } } diff --git a/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencySet.kt b/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencySet.kt index 1606888..ccaf314 100644 --- a/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencySet.kt +++ b/model/src/main/kotlin/org/nixos/gradle2nix/model/impl/DefaultDependencySet.kt @@ -4,5 +4,5 @@ import org.nixos.gradle2nix.model.DependencySet import org.nixos.gradle2nix.model.ResolvedDependency data class DefaultDependencySet( - override val dependencies: List + override val dependencies: List, ) : DependencySet diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index 3dd678a..a00f9a7 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -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 { - useJUnitPlatform() - testLogging { - events("passed", "skipped", "failed") - } - } } diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/dependencygraph/DependencyExtractor.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyExtractor.kt similarity index 51% rename from plugin/src/main/kotlin/org/nixos/gradle2nix/dependencygraph/DependencyExtractor.kt rename to plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyExtractor.kt index 1c62060..755ca1c 100644 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/dependencygraph/DependencyExtractor.kt +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/DependencyExtractor.kt @@ -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, 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() - 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>() val mappings = mutableMapOf>() @@ -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? = try { - Json.decodeFromStream(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? = + try { + Json.decodeFromStream(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 + } diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt index b22b424..c44766a 100644 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/Gradle2NixPlugin.kt @@ -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 { +abstract class Gradle2NixPlugin + @Inject + constructor( + private val toolingModelBuilderRegistry: ToolingModelBuilderRegistry, + ) : Plugin { + 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, + ) } } diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleExtensions.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleExtensions.kt new file mode 100644 index 0000000..1447426 --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/GradleExtensions.kt @@ -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 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") diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/ResolveAllArtifacts.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/ResolveAllArtifacts.kt new file mode 100644 index 0000000..86314ec --- /dev/null +++ b/plugin/src/main/kotlin/org/nixos/gradle2nix/ResolveAllArtifacts.kt @@ -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 { + 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 { + 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() + } + } diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/AbstractResolveProjectDependenciesTask.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/AbstractResolveProjectDependenciesTask.kt deleted file mode 100644 index 9e05333..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/AbstractResolveProjectDependenciesTask.kt +++ /dev/null @@ -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 { - return project.configurations.filter { it.canSafelyBeResolved() } - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ForceDependencyResolutionPlugin.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ForceDependencyResolutionPlugin.kt deleted file mode 100644 index 73f358f..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ForceDependencyResolutionPlugin.kt +++ /dev/null @@ -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 { - 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 - - data object Current : ResolveProjectDependenciesTaskFactory { - override fun create(project: Project): TaskProvider { - return project.tasks.register(RESOLVE_PROJECT_TASK, ResolveProjectDependenciesTask::class.java) - } - } - - data object Legacy : ResolveProjectDependenciesTaskFactory { - override fun create(project: Project): TaskProvider { - return project.tasks.register(RESOLVE_PROJECT_TASK, LegacyResolveProjectDependenciesTask::class.java) - } - } - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/LegacyResolveProjectDependenciesTask.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/LegacyResolveProjectDependenciesTask.kt deleted file mode 100644 index 598f342..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/LegacyResolveProjectDependenciesTask.kt +++ /dev/null @@ -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 - } - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ResolveProjectDependenciesTask.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ResolveProjectDependenciesTask.kt deleted file mode 100644 index f35af26..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/forceresolve/ResolveProjectDependenciesTask.kt +++ /dev/null @@ -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() - } -} diff --git a/plugin/src/main/kotlin/org/nixos/gradle2nix/util/GradleExtensions.kt b/plugin/src/main/kotlin/org/nixos/gradle2nix/util/GradleExtensions.kt deleted file mode 100644 index 81f5c78..0000000 --- a/plugin/src/main/kotlin/org/nixos/gradle2nix/util/GradleExtensions.kt +++ /dev/null @@ -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 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