This commit is contained in:
Tad Fisher
2023-12-19 13:52:14 -08:00
parent 6da87262a4
commit 8ceeeb9611
69 changed files with 5970 additions and 13633 deletions

View File

@@ -2,6 +2,9 @@ package org.nixos.gradle2nix
import org.gradle.tooling.GradleConnector
import org.gradle.tooling.ProjectConnection
import org.nixos.gradle2nix.model.PARAM_INCLUDE_CONFIGURATIONS
import org.nixos.gradle2nix.model.PARAM_INCLUDE_PROJECTS
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
fun connect(config: Config): ProjectConnection =
GradleConnector.newConnector()
@@ -28,19 +31,23 @@ fun ProjectConnection.build(
}
addArguments(config.gradleArgs)
addArguments(
"--gradle-user-home=${config.gradleHome}",
"--init-script=${config.appHome}/init.gradle",
"--write-verification-metadata", "sha256"
)
if (config.projectFilter != null) {
addArguments("-D${PARAM_INCLUDE_PROJECTS}")
addArguments("-D$PARAM_INCLUDE_PROJECTS")
}
if (config.configurationFilter != null) {
addArguments("-D${PARAM_INCLUDE_CONFIGURATIONS}")
addArguments("-D$PARAM_INCLUDE_CONFIGURATIONS")
}
if (config.logger.verbose) {
setStandardOutput(System.err)
setStandardError(System.err)
}
if (config.logger.stacktrace) {
addArguments("--stacktrace")
}
}
.run()
}

View File

@@ -116,7 +116,8 @@ class Gradle2Nix : CliktCommand(
if (appHome == null) {
System.err.println("Error: could not locate the /share directory in the gradle2nix installation")
}
val gradleHome = System.getenv("GRADLE_USER_HOME")?.let(::File) ?: File("${System.getProperty("user.home")}/.gradle")
val gradleHome =
System.getenv("GRADLE_USER_HOME")?.let(::File) ?: File("${System.getProperty("user.home")}/.gradle")
val logger = Logger(verbose = !quiet, stacktrace = debug)
val config = Config(
@@ -152,7 +153,7 @@ class Gradle2Nix : CliktCommand(
val env = try {
processDependencies(config)
} catch (e: Throwable) {
logger.error("Dependency parsing failed", e)
logger.error("dependency parsing failed", e)
}
val outDir = outDir ?: projectDir

View File

@@ -14,9 +14,8 @@ import okio.HashingSource
import okio.blackholeSink
import okio.buffer
import okio.source
import org.nixos.gradle2nix.dependencygraph.model.Repository
import org.nixos.gradle2nix.dependencygraph.model.ResolvedConfiguration
import org.nixos.gradle2nix.dependencygraph.model.ResolvedDependency
import org.nixos.gradle2nix.model.Repository
import org.nixos.gradle2nix.model.ResolvedConfiguration
import org.nixos.gradle2nix.env.ArtifactFile
import org.nixos.gradle2nix.env.ArtifactSet
import org.nixos.gradle2nix.env.Env
@@ -49,6 +48,8 @@ fun processDependencies(config: Config): Env {
ModuleVersionId(ModuleId(it.group, it.name), it.version)
} ?: emptyMap()
val moduleCache = mutableMapOf<ModuleVersionId, GradleModule?>()
val pomCache = mutableMapOf<ModuleVersionId, Pair<String, ArtifactFile>?>()
val ivyCache = mutableMapOf<ModuleVersionId, Pair<String, ArtifactFile>?>()
val configurations = readDependencyGraph(config)
val repositories = configurations
@@ -64,11 +65,11 @@ fun processDependencies(config: Config): Env {
}
if (repositories.isEmpty()) {
config.logger.warn("no repositories found in any configuration")
return Env(emptyMap())
return emptyMap()
}
config.logger.debug("Repositories:\n ${repositories.values.joinToString("\n ")}")
val modules = configurations.asSequence()
return configurations.asSequence()
.flatMap { it.allDependencies.asSequence() }
.filterNot { it.id.startsWith("project ") || it.repository == null || it.repository !in repositories }
.groupBy { ModuleId(it.coordinates.group, it.coordinates.module) }
@@ -83,34 +84,40 @@ fun processDependencies(config: Config): Env {
val component = verificationComponents[componentId]
?: verifyComponentFilesInCache(config, componentId)
?: verifyComponentFilesInTestRepository(config, componentId)
?: config.logger.error("$componentId: no dependency metadata found")
val gradleModule = moduleCache.getOrPut(componentId) {
maybeGetGradleModule(config.logger, componentId, dep.repositories)
maybeDownloadGradleModule(config.logger, component, dep.repositories)?.artifact?.second
}
ArtifactSet(
needsPomRedirect = repositories.values.any {
"mavenPom" in it.metadataSources &&
"ignoreGradleMetadataRedirection" !in it.metadataSources
},
needsIvyRedirect = repositories.values.any {
"ivyDescriptor" in it.metadataSources &&
"ignoreGradleMetadataRedirection" !in it.metadataSources
},
files = (component?.artifacts ?: emptyList()).associate { meta ->
meta.name to ArtifactFile(
urls = dep.repositories
.flatMap { repository -> artifactUrls(componentId, meta.name, repository, gradleModule) }
.distinct(),
hash = meta.checksums.first().toSri()
val pomArtifact = pomCache.getOrPut(componentId) {
maybeDownloadMavenPom(config.logger, component, dep.repositories, gradleModule)
}
val ivyArtifact = ivyCache.getOrPut(componentId) {
maybeDownloadIvyDescriptor(config.logger, component, dep.repositories, gradleModule)
}
val files = buildMap {
if (pomArtifact != null) put(pomArtifact.first, pomArtifact.second)
if (ivyArtifact != null) put(ivyArtifact.first, ivyArtifact.second)
for (artifact in component.artifacts) {
put(
artifact.name,
ArtifactFile(
urls = dep.repositories.flatMap { repo ->
artifactUrls(componentId, artifact.name, repo, gradleModule)
}.distinct(),
hash = artifact.checksums.first().toSri()
)
)
}
}.toSortedMap()
)
ArtifactSet(files)
}
.toSortedMap(Version.Comparator.reversed())
Module(versions)
}
.toSortedMap(compareBy(ModuleId::toString))
return Env(modules)
}
private fun readVerificationMetadata(config: Config): VerificationMetadata? {
@@ -162,25 +169,87 @@ private fun verifyComponentFilesInTestRepository(
return Component(id, verifications.toList())
}
@OptIn(ExperimentalSerializationApi::class)
private fun maybeGetGradleModule(logger: Logger, id: ModuleVersionId, repos: List<Repository>): GradleModule? {
val filename = with(id) { "$name-$version.module" }
val reposWithGradleMetadata = repos
.filter { "gradleMetadata" in it.metadataSources }
.flatMap { artifactUrls(id, filename, it, null)}
for (url in reposWithGradleMetadata) {
private fun maybeDownloadGradleModule(
logger: Logger,
component: Component,
repos: List<Repository>
): ArtifactDownload<Pair<String, GradleModule>>? {
if (component.artifacts.none { it.name.endsWith(".module") }) return null
val filename = with(component.id) { "$name-$version.module" }
return maybeDownloadArtifact(logger, component.id, filename, repos)?.let { artifact ->
try {
return URL(url).openStream().buffered().use { input ->
JsonFormat.decodeFromStream(input)
}
ArtifactDownload(
filename to JsonFormat.decodeFromString<GradleModule>(artifact.artifact),
artifact.url,
artifact.hash
)
} catch (e: SerializationException) {
logger.error("$id: failed to parse Gradle module metadata ($url)", e)
logger.warn("${component.id}: failed to parse Gradle module metadata from ${artifact.url}")
null
}
}
}
private fun maybeDownloadMavenPom(
logger: Logger,
component: Component,
repos: List<Repository>,
gradleModule: GradleModule?
): Pair<String, ArtifactFile>? {
if (component.artifacts.any { it.name.endsWith(".pom") }) return null
val pomRepos = repos.filter { "mavenPom" in it.metadataSources }
if (pomRepos.isEmpty()) return null
val filename = with(component.id) { "$name-$version.pom" }
return maybeDownloadArtifact(logger, component.id, filename, pomRepos)?.let { artifact ->
filename to ArtifactFile(
urls = pomRepos.flatMap { repo ->
artifactUrls(component.id, filename, repo, gradleModule)
}.distinct(),
hash = artifact.hash.toSri()
)
}
}
private fun maybeDownloadIvyDescriptor(
logger: Logger,
component: Component,
repos: List<Repository>,
gradleModule: GradleModule?
): Pair<String, ArtifactFile>? {
if (component.artifacts.any { it.name == "ivy.xml" }) return null
val ivyRepos = repos.filter { "ivyDescriptor" in it.metadataSources }
if (ivyRepos.isEmpty()) return null
return maybeDownloadArtifact(logger, component.id, "ivy.xml", ivyRepos)?.let { artifact ->
"ivy.xml" to ArtifactFile(
urls = ivyRepos.flatMap { repo ->
artifactUrls(component.id, "ivy.xml", repo, gradleModule)
}.distinct(),
hash = artifact.hash.toSri()
)
}
}
private fun maybeDownloadArtifact(
logger: Logger,
id: ModuleVersionId,
filename: String,
repos: List<Repository>
): ArtifactDownload<String>? {
val urls = repos.flatMap { artifactUrls(id, filename, it, null)}
for (url in urls) {
try {
val source = HashingSource.sha256(URL(url).openStream().source())
val text = source.buffer().readUtf8()
val hash = source.hash
return ArtifactDownload(text, url, Sha256(hash.hex()))
} catch (e: IOException) {
// Pass
}
}
logger.debug("artifact $filename not found in any repository")
return null
}
@@ -276,3 +345,9 @@ private data class MergedDependency(
val id: ModuleVersionId,
val repositories: List<Repository>
)
private data class ArtifactDownload<T>(
val artifact: T,
val url: String,
val hash: Checksum
)

View File

@@ -12,11 +12,7 @@ import kotlinx.serialization.encoding.Encoder
import org.gradle.internal.impldep.com.google.common.collect.ImmutableMap
import org.gradle.internal.impldep.com.google.common.primitives.Longs
@Serializable
@JvmInline
value class Env(
val modules: Map<ModuleId, Module>,
)
typealias Env = Map<ModuleId, Module>
@Serializable
@JvmInline
@@ -25,23 +21,30 @@ value class Module(
)
@Serializable
data class ArtifactSet(
val needsPomRedirect: Boolean,
val needsIvyRedirect: Boolean,
@JvmInline
value class ArtifactSet(
val files: Map<String, ArtifactFile>
)
@Serializable
data class ArtifactFile(
data class ArtifactFile internal constructor(
val urls: List<String>,
val hash: String,
)
) {
companion object {
operator fun invoke(urls: List<String>, hash: String) = ArtifactFile(urls.sorted(), hash)
}
}
@Serializable(ModuleId.Serializer::class)
data class ModuleId(
val group: String,
val name: String,
) {
) : Comparable<ModuleId> {
override fun compareTo(other: ModuleId): Int =
compareValuesBy(this, other, ModuleId::group, ModuleId::name)
override fun toString(): String = "$group:$name"
@@ -52,7 +55,7 @@ data class ModuleId(
)
override fun serialize(encoder: Encoder, value: ModuleId) {
encoder.encodeString("${value.name}:${value.group}")
encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): ModuleId {
@@ -66,20 +69,55 @@ data class ModuleId(
}
}
@Serializable(ModuleVersionId.Serializer::class)
data class ModuleVersionId(
val moduleId: ModuleId,
val version: Version
) {
) : Comparable<ModuleVersionId> {
constructor(group: String, name: String, version: Version) : this(ModuleId(group, name), version)
val group: String get() = moduleId.group
val name: String get() = moduleId.name
override fun toString(): String = "$moduleId:$version"
override fun compareTo(other: ModuleVersionId): Int =
compareValuesBy(
this,
other,
ModuleVersionId::moduleId,
ModuleVersionId::version
)
override fun toString(): String = "$group:$name:$version"
internal object Serializer : KSerializer<ModuleVersionId> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
Version::class.qualifiedName!!,
PrimitiveKind.STRING
)
override fun serialize(encoder: Encoder, value: ModuleVersionId) {
encoder.encodeString(value.toString())
}
override fun deserialize(decoder: Decoder): ModuleVersionId {
val encoded = decoder.decodeString()
val parts = encoded.split(":")
if (parts.size != 3 || parts.any(String::isBlank)) {
throw SerializationException("invalid module version id: $encoded")
}
return ModuleVersionId(
moduleId = ModuleId(parts[0], parts[1]),
version = Version(parts[3])
)
}
}
}
@Serializable(Version.Serializer::class)
class Version(val source: String, val parts: List<String>, base: Version?) : Comparable<Version> {
val base: Version
private val base: Version
val numericParts: List<Long?>
init {

View File

@@ -3,13 +3,12 @@ package org.nixos.gradle2nix.metadata
import java.io.File
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import nl.adaptivity.xmlutil.XmlStreaming
import nl.adaptivity.xmlutil.serialization.XML
import nl.adaptivity.xmlutil.serialization.XmlChildrenName
import nl.adaptivity.xmlutil.serialization.XmlElement
import nl.adaptivity.xmlutil.serialization.XmlSerialName
import nl.adaptivity.xmlutil.xmlStreaming
import org.nixos.gradle2nix.Logger
import org.nixos.gradle2nix.DependencyCoordinates
import org.nixos.gradle2nix.env.ModuleVersionId
import org.nixos.gradle2nix.env.Version
@@ -108,6 +107,8 @@ data class Component(
val version: Version,
val artifacts: List<Artifact> = emptyList(),
) {
val id: ModuleVersionId get() = ModuleVersionId(group, name, version)
constructor(id: ModuleVersionId, artifacts: List<Artifact>) : this(
id.group,
id.name,
@@ -134,7 +135,7 @@ val XmlFormat = XML {
fun parseVerificationMetadata(logger: Logger, metadata: File): VerificationMetadata? {
return try {
metadata.reader().buffered().let(XmlStreaming::newReader).use { input ->
metadata.reader().buffered().let(xmlStreaming::newReader).use { input ->
XmlFormat.decodeFromReader(input)
}
} catch (e: Exception) {

View File

@@ -17,6 +17,9 @@ class GoldenTest : FunSpec({
golden("dependency/snapshot-dynamic")
golden("dependency/snapshot-redirect")
}
context("included-build") {
golden("included-build")
}
context("integration") {
golden("integration/settings-buildscript")
}

View File

@@ -73,7 +73,7 @@ suspend fun TestScope.fixture(
if (!tempDir.resolve("settings.gradle").exists() && !tempDir.resolve("settings.gradle.kts").exists()) {
Files.createFile(tempDir.resolve("settings.gradle").toPath())
}
app.main(listOf("-d", tempDir.toString()) + args.withM2())
app.main(listOf("-d", tempDir.toString()) + listOf("--debug") + args.withM2() + "-Dorg.gradle.internal.operations.trace=${tempDir.resolve("build").absolutePath}")
val file = tempDir.resolve("${app.envFile}.json")
file.shouldBeAFile()
val env: Env = file.inputStream().buffered().use { input ->

View File

@@ -16,7 +16,7 @@ subprojects {
tasks {
wrapper {
gradleVersion = "8.3"
gradleVersion = libs.versions.gradle.get()
distributionType = Wrapper.DistributionType.ALL
}
}

View File

@@ -35,4 +35,7 @@ let
};
};
in gradle2nix
in buildGradle {
envSpec = ./gradle-env.json;
pname = "gradle2nix";
}

View File

@@ -9,3 +9,12 @@ repositories {
dependencies {
implementation("com.gradle.publish:plugin-publish-plugin:1.2.1")
}
gradlePlugin {
plugins {
register("apply-plugin-publish") {
id = "com.example.apply-plugin-publish"
implementationClass = "com.example.ApplyPluginPublishPlugin"
}
}
}

View File

@@ -1,5 +0,0 @@
package com.example
plugins {
id("com.gradle.plugin-publish")
}

View File

@@ -0,0 +1,10 @@
package com.example
import org.gradle.api.Plugin
import org.gradle.api.Project
open class ApplyPluginPublishPlugin : Plugin<Project> {
override fun apply(project: Project) {
project.pluginManager.apply("com.gradle.plugin-publish")
}
}

View File

@@ -1,9 +1,6 @@
{
"com.squareup.moshi:moshi": {
"1.8.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"moshi-1.8.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/moshi/moshi/1.8.0/moshi-1.8.0.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-FLuAWbnddiACWSkN+IfjfmaaB0qsnImUAePIEC/lII8="
}
}
}
},
"com.squareup.okio:okio": {
"2.2.2": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-2.2.2.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
@@ -37,13 +30,9 @@
"hash": "sha256-/WIZiPf2lXAlc13G3QkLAKIPOju413ynkDYHf2KbFAs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.60/kotlin-stdlib-1.2.60.jar"
@@ -57,13 +46,9 @@
"hash": "sha256-5jKJkgnmtMqrlA/YLk7GOjLjJkP4Fff6cJdkeJDXnxg="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.60/kotlin-stdlib-common-1.2.60.jar"
@@ -77,13 +62,9 @@
"hash": "sha256-gwwnrx4c8k8PUm6kV5AcQ/OMGbtvfl03Y8PSU98bjaE="
}
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -98,5 +79,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.squareup.moshi:moshi": {
"1.8.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"moshi-1.8.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/moshi/moshi/1.8.0/moshi-1.8.0.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-FLuAWbnddiACWSkN+IfjfmaaB0qsnImUAePIEC/lII8="
}
}
}
},
"com.squareup.okio:okio": {
"2.2.2": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-2.2.2.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
@@ -37,13 +30,9 @@
"hash": "sha256-/WIZiPf2lXAlc13G3QkLAKIPOju413ynkDYHf2KbFAs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.60/kotlin-stdlib-1.2.60.jar"
@@ -57,13 +46,9 @@
"hash": "sha256-5jKJkgnmtMqrlA/YLk7GOjLjJkP4Fff6cJdkeJDXnxg="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.60/kotlin-stdlib-common-1.2.60.jar"
@@ -77,13 +62,9 @@
"hash": "sha256-gwwnrx4c8k8PUm6kV5AcQ/OMGbtvfl03Y8PSU98bjaE="
}
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -98,5 +79,4 @@
}
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,6 @@
{
"com.badlogicgames.gdx:gdx-platform": {
"1.9.9": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"gdx-platform-1.9.9-natives-desktop.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/badlogicgames/gdx/gdx-platform/1.9.9/gdx-platform-1.9.9-natives-desktop.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.badlogicgames.gdx:gdx-platform": {
"1.9.9": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"gdx-platform-1.9.9-natives-desktop.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/badlogicgames/gdx/gdx-platform/1.9.9/gdx-platform-1.9.9-natives-desktop.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"io.micrometer:micrometer-bom": {
"1.5.1": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"micrometer-bom-1.5.1.pom": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/io/micrometer/micrometer-bom/1.5.1/micrometer-bom-1.5.1.pom"
@@ -11,13 +8,9 @@
"hash": "sha256-K/qF6ds8ck5sWvelJBYk+w+K04oQpT/4BtY57WVLRUI="
}
}
}
},
"io.micrometer:micrometer-core": {
"1.5.1": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"micrometer-core-1.5.1.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/io/micrometer/micrometer-core/1.5.1/micrometer-core-1.5.1.jar"
@@ -31,13 +24,9 @@
"hash": "sha256-Cb4KaUHaOvdOz7VpDax6kJKuT2KWY5Ci73foX2xl6xw="
}
}
}
},
"org.hdrhistogram:HdrHistogram": {
"2.1.12": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"HdrHistogram-2.1.12.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/hdrhistogram/HdrHistogram/2.1.12/HdrHistogram-2.1.12.jar"
@@ -52,5 +41,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test-SNAPSHOT1": {
"2.0.2-SNAPSHOT": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-SNAPSHOT1-2.0.2-20070310.181613-3.jar": {
"urls": [
],
@@ -16,5 +13,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test-SNAPSHOT1": {
"2.0.2-SNAPSHOT": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-SNAPSHOT1-2.0.2-20070310.181613-3.jar": {
"urls": [
],
@@ -16,5 +13,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.github.anuken:packr": {
"-SNAPSHOT": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"packr--SNAPSHOT.jar": {
"urls": [
"https://jitpack.io/com/github/anuken/packr/-SNAPSHOT/packr--SNAPSHOT.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test-SNAPSHOT2": {
"2.0.2-SNAPSHOT": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-SNAPSHOT2-2.0.2-SNAPSHOT.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test-SNAPSHOT2/2.0.2-SNAPSHOT/test-SNAPSHOT2-2.0.2-SNAPSHOT.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test-SNAPSHOT2": {
"2.0.2-SNAPSHOT": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-SNAPSHOT2-2.0.2-SNAPSHOT.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test-SNAPSHOT2/2.0.2-SNAPSHOT/test-SNAPSHOT2-2.0.2-SNAPSHOT.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -0,0 +1,48 @@
{
"org.apache:foo": {
"2.0.0": {
"foo-2.0.0.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/foo/2.0.0/foo-2.0.0.jar"
],
"hash": "sha256-M95zEuAwVCam7c2rKIET5qs4Q60sA84RyTA3a9jdQd8="
},
"foo-2.0.0.pom": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/foo/2.0.0/foo-2.0.0.pom"
],
"hash": "sha256-gcL/k4xoI5SK4qDNcyH1uHkgiGQv3WohPb45Gsb9gi8="
}
},
"1.0.0": {
"foo-1.0.0.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/foo/1.0.0/foo-1.0.0.jar"
],
"hash": "sha256-M95zEuAwVCam7c2rKIET5qs4Q60sA84RyTA3a9jdQd8="
},
"foo-1.0.0.pom": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/foo/1.0.0/foo-1.0.0.pom"
],
"hash": "sha256-roNL3MgAJuUPxIdJJiSpjU3yEFlJFDQ99QvnaWlkVcE="
}
}
},
"org.apache:test": {
"1.0.0": {
"test-1.0.0.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test/1.0.0/test-1.0.0.jar"
],
"hash": "sha256-M95zEuAwVCam7c2rKIET5qs4Q60sA84RyTA3a9jdQd8="
},
"test-1.0.0.pom": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test/1.0.0/test-1.0.0.pom"
],
"hash": "sha256-sYk8m4+T+hRJ+43tpPkthrE/JftrsMnmuzORCLCK1To="
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.googlecode.javaewah:JavaEWAH": {
"1.1.6": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"JavaEWAH-1.1.6.jar": {
"urls": [
"https://plugins.gradle.org/m2/com/googlecode/javaewah/JavaEWAH/1.1.6/JavaEWAH-1.1.6.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-f0/5GbHuF783duBYo/IOYXPbI6XkTPLRB+x1cMGGq/A="
}
}
}
},
"com.jcraft:jsch": {
"0.1.54": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"jsch-0.1.54.jar": {
"urls": [
"https://plugins.gradle.org/m2/com/jcraft/jsch/0.1.54/jsch-0.1.54.jar"
@@ -37,13 +30,9 @@
"hash": "sha256-q49RIDm+f2riDhjnQ7Sp2KIJWElEMZF9pYrlqu+KNHg="
}
}
}
},
"commons-codec:commons-codec": {
"1.6": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"commons-codec-1.6.jar": {
"urls": [
"https://plugins.gradle.org/m2/commons-codec/commons-codec/1.6/commons-codec-1.6.jar"
@@ -57,13 +46,9 @@
"hash": "sha256-oG410//zprgT2UiU6/PkmPlUDIZMWzmueDkH46bHKIk="
}
}
}
},
"commons-logging:commons-logging": {
"1.1.3": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"commons-logging-1.1.3.jar": {
"urls": [
"https://plugins.gradle.org/m2/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar"
@@ -77,13 +62,9 @@
"hash": "sha256-MlCsOsa9YO0GMfXNAzUDKymT1j5AWmrgVV0np+SGWEk="
}
}
}
},
"gradle.plugin.net.vivin:gradle-semantic-build-versioning": {
"4.0.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"gradle-semantic-build-versioning-4.0.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/gradle/plugin/net/vivin/gradle-semantic-build-versioning/4.0.0/gradle-semantic-build-versioning-4.0.0.jar"
@@ -97,13 +78,9 @@
"hash": "sha256-TygodBYH7RAtletfGJ1JbHhA7UY6zqifHlGmBWdxTvc="
}
}
}
},
"org.apache.httpcomponents:httpclient": {
"4.3.6": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"httpclient-4.3.6.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpclient/4.3.6/httpclient-4.3.6.jar"
@@ -117,13 +94,9 @@
"hash": "sha256-0CY09hMekUlhwCqoNnEeuscnBLJ+JsW9Iju62JsbZMM="
}
}
}
},
"org.apache.httpcomponents:httpcore": {
"4.3.3": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"httpcore-4.3.3.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/apache/httpcomponents/httpcore/4.3.3/httpcore-4.3.3.jar"
@@ -137,13 +110,9 @@
"hash": "sha256-tCf3z2fHWk4/niEI01v0UwNXPBRex3j8rc/6zvF6EmQ="
}
}
}
},
"org.eclipse.jgit:org.eclipse.jgit": {
"4.8.0.201706111038-r": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"org.eclipse.jgit-4.8.0.201706111038-r.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/eclipse/jgit/org.eclipse.jgit/4.8.0.201706111038-r/org.eclipse.jgit-4.8.0.201706111038-r.jar"
@@ -157,13 +126,9 @@
"hash": "sha256-pVap9a38avSbKhLnLcPNfkPbj9whbA81iFlyovWton0="
}
}
}
},
"org.slf4j:slf4j-api": {
"1.7.2": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"slf4j-api-1.7.2.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/slf4j/slf4j-api/1.7.2/slf4j-api-1.7.2.jar"
@@ -178,5 +143,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.opendof.core-java:dof-cipher-sms4": {
"1.0": {
"needsPomRedirect": false,
"needsIvyRedirect": true,
"files": {
"dof-cipher-sms4-1.0.jar": {
"urls": [
"https://asset.opendof.org/artifact/org.opendof.core-java/dof-cipher-sms4/1.0/dof-cipher-sms4-1.0.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-rh+pQpXqPP/cmBD8slvwMrKlWCUb3JNzW3l58hd7oJ8="
}
}
}
},
"org.opendof.core-java:dof-oal": {
"7.0.2": {
"needsPomRedirect": false,
"needsIvyRedirect": true,
"files": {
"dof-oal-7.0.2.jar": {
"urls": [
"https://asset.opendof.org/artifact/org.opendof.core-java/dof-oal/7.0.2/dof-oal-7.0.2.jar"
@@ -38,5 +31,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"net.java.dev.jna:jna": {
"5.6.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"jna-5.6.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
@@ -19,13 +16,9 @@
"hash": "sha256-X+gbAlWXjyRhbTexBgi3lJil8wc+HZsgONhzaoMfJgg="
}
}
}
},
"org.jetbrains.intellij.deps:trove4j": {
"1.0.20200330": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"trove4j-1.0.20200330.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
@@ -41,13 +34,9 @@
"hash": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k="
}
}
}
},
"org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"org.jetbrains.kotlin.jvm.gradle.plugin-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.7.21/org.jetbrains.kotlin.jvm.gradle.plugin-1.7.21.pom"
@@ -55,13 +44,9 @@
"hash": "sha256-18S+c5nTziimR77ivh3nCwUdpLqoz9X4KYNDJ2UKD30="
}
}
}
},
"org.jetbrains.kotlin:kotlin-android-extensions": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-android-extensions-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.7.21/kotlin-android-extensions-1.7.21.jar"
@@ -75,13 +60,9 @@
"hash": "sha256-8pic3UN0A8hyZc/K8GHSFOaGlVyX40ntFWa6FqouDI0="
}
}
}
},
"org.jetbrains.kotlin:kotlin-annotation-processing-gradle": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-annotation-processing-gradle-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-annotation-processing-gradle/1.7.21/kotlin-annotation-processing-gradle-1.7.21.jar"
@@ -95,13 +76,9 @@
"hash": "sha256-r2JZxfjfTezw8FXmZcTLaP8TtK9c1HfuHTO/7gAaFr4="
}
}
}
},
"org.jetbrains.kotlin:kotlin-build-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-build-common-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-build-common/1.7.21/kotlin-build-common-1.7.21.jar"
@@ -115,13 +92,9 @@
"hash": "sha256-msmBVHbIUfFKH3QeG46CJRxyepVGgMdXT4owUn2z718="
}
}
}
},
"org.jetbrains.kotlin:kotlin-compiler-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-compiler-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar",
@@ -137,13 +110,9 @@
"hash": "sha256-CwIzMip2MO/eEzUmjkYSPw1tNjg5gg/TfE7Lbv+njjs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-compiler-runner": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-compiler-runner-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-runner/1.7.21/kotlin-compiler-runner-1.7.21.jar"
@@ -157,13 +126,9 @@
"hash": "sha256-+JDieVykDuyu+jpdjkOND3C7YCo5SUe7rOp2Quqy+Tw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-daemon-client": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-daemon-client-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-client/1.7.21/kotlin-daemon-client-1.7.21.jar"
@@ -177,13 +142,9 @@
"hash": "sha256-Be4Gj7v3IvWRSlqiWO6KKLZChF9B1/+bVGhtXKJbvxk="
}
}
}
},
"org.jetbrains.kotlin:kotlin-daemon-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-daemon-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar",
@@ -199,13 +160,9 @@
"hash": "sha256-vB3pwgh7ouTlQQF6i66PQF7IAKGK5MJH6R8rVedh5kk="
}
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-1.7.21-gradle71.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21-gradle71.jar"
@@ -217,15 +174,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21.module"
],
"hash": "sha256-j6I2KYtJBynes0XjG8ZPKSj3wbXxwjH8ZtvINlnBZ+E="
}
},
"kotlin-gradle-plugin-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21.pom"
],
"hash": "sha256-0gTXpKcf6Scv44M9x0IAkan/EJaky6JfcnihlUI1BGk="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-api": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-api-1.7.21-gradle71.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21-gradle71.jar"
@@ -243,15 +202,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21.module"
],
"hash": "sha256-zGXnGhweng0JaG9cpJGORShIY1q7VCl15HwYlnw6A10="
}
},
"kotlin-gradle-plugin-api-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21.pom"
],
"hash": "sha256-89unBFqYcdah5QnkF+tjQa3bmHFaL409ZnJlAdq0s0Y="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-idea-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.jar"
@@ -263,15 +224,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.module"
],
"hash": "sha256-ygHy2JJMcpaXMax+oVbwi7GP60LDEAClIj2dwW1ZuTg="
}
},
"kotlin-gradle-plugin-idea-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.pom"
],
"hash": "sha256-Flz/idoRsXIpiJPHg0sNQadm1/PdIPoIvfiJxlXD5zc="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-idea-proto-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.7.21/kotlin-gradle-plugin-idea-proto-1.7.21.jar"
@@ -285,13 +248,9 @@
"hash": "sha256-PRwDYK9odF8qAyoMAYR//Pnriq1wa/ZZydhAoYTsXyM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-model": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-model-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.jar"
@@ -303,15 +262,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.module"
],
"hash": "sha256-kCJoZCp1guVF4xgQnjdIw3WxOLCKFVuBX2yAi7vuR7U="
}
},
"kotlin-gradle-plugin-model-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.pom"
],
"hash": "sha256-y2vKOdHhBWBXcMCj3ubUXw58XtPFNGiZ9ycQsf//HaY="
}
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-api": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-klib-commonizer-api-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.7.21/kotlin-klib-commonizer-api-1.7.21.jar"
@@ -325,13 +286,9 @@
"hash": "sha256-so6g3vy5lNH7U6e7olh9J0DG0mAXk2UglP1ox0Ul0CA="
}
}
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-klib-commonizer-embeddable-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.7.21/kotlin-klib-commonizer-embeddable-1.7.21.jar"
@@ -345,13 +302,9 @@
"hash": "sha256-bOmRoyzYOdq3wbf88+1xbr6XgbRgg3ViDC9fH8RwjrA="
}
}
}
},
"org.jetbrains.kotlin:kotlin-native-utils": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-native-utils-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.7.21/kotlin-native-utils-1.7.21.jar"
@@ -365,13 +318,9 @@
"hash": "sha256-CEYFdUhagoAZC0g8H3fyCk063IegIXTzDuxVdNm65FY="
}
}
}
},
"org.jetbrains.kotlin:kotlin-project-model": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-project-model-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.7.21/kotlin-project-model-1.7.21.jar"
@@ -385,13 +334,9 @@
"hash": "sha256-JQfT7SKoHyssNSxMUOY1MivHEQClFQJN0NtQRifJ8Bs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-reflect": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-reflect-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.7.21/kotlin-reflect-1.7.21.jar"
@@ -405,13 +350,9 @@
"hash": "sha256-Xn69/iAG9vHksPORwbqBhTmKj2NF2xpStYTx40Cz8EM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-script-runtime": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-script-runtime-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.7.21/kotlin-script-runtime-1.7.21.jar"
@@ -425,13 +366,9 @@
"hash": "sha256-LuSdd/3Dw6l0akiYCbfGQ3fh2NnEXCDZI+MXI5sicwQ="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-common-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar",
@@ -447,13 +384,9 @@
"hash": "sha256-2xzYRWGPDLQXOK3H72jZ+NIjZ1sFg+NbsMCEA30AWe4="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-compiler-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar",
@@ -469,13 +402,9 @@
"hash": "sha256-xHXL2+0BepcMD9y46qu1UNc9E6T+a4e3efxM9S148JM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-compiler-impl-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar",
@@ -491,13 +420,9 @@
"hash": "sha256-5c0+HEj+qhC1YVqidOFh5/dcFijcJhZ1ALZ0b4gfweM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-jvm": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-jvm-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar",
@@ -513,13 +438,9 @@
"hash": "sha256-cnwtOnluoiOWPu7P7kHvKygsVbZ+V8O0mgFwpMSbfGE="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.21/kotlin-stdlib-1.7.21.jar"
@@ -533,13 +454,9 @@
"hash": "sha256-mzkq1D4vQhJp9jxiBz+ulCN9LjHe7o9msZzBkbTaBqw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.21/kotlin-stdlib-common-1.7.21.jar"
@@ -553,13 +470,9 @@
"hash": "sha256-LuberkeOGLGvushzHFvxoUe1dWiT1Z7b+nEWBcNDX4Q="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk7": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-jdk7-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.21/kotlin-stdlib-jdk7-1.7.21.jar"
@@ -573,13 +486,9 @@
"hash": "sha256-vy6yU9onofKT0RRpMpRBeF26xRceWB8v7Z1aKm2YaZw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk8": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-jdk8-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.21/kotlin-stdlib-jdk8-1.7.21.jar"
@@ -593,13 +502,9 @@
"hash": "sha256-bzuTQ8QS1q5ApMePuKcJhklkUKlSjNusdimojhqlg4k="
}
}
}
},
"org.jetbrains.kotlin:kotlin-tooling-core": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-tooling-core-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.7.21/kotlin-tooling-core-1.7.21.jar"
@@ -613,13 +518,9 @@
"hash": "sha256-tw2g1Eorhw7Lz85ZcMMOOOLs3htfQqHdRC0TA5gSKUY="
}
}
}
},
"org.jetbrains.kotlin:kotlin-util-io": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-util-io-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.7.21/kotlin-util-io-1.7.21.jar"
@@ -633,13 +534,9 @@
"hash": "sha256-ziTM1kPWW+8Cey9uINCnkhdq29ug2eVVmS5CR6Y3Ne8="
}
}
}
},
"org.jetbrains.kotlin:kotlin-util-klib": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-util-klib-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.7.21/kotlin-util-klib-1.7.21.jar"
@@ -653,13 +550,9 @@
"hash": "sha256-D8d7J3Rc+kzuX+AA5tEpmtSUT3rMB4A7u8ws0rAT3oU="
}
}
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm": {
"1.5.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlinx-coroutines-core-jvm-1.5.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.jar"
@@ -671,15 +564,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.module"
],
"hash": "sha256-yIXdAoEHbFhDgm3jF+PLzcPYhZ2+71OuHPrNG5xg+W4="
}
},
"kotlinx-coroutines-core-jvm-1.5.0.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.pom"
],
"hash": "sha256-U2IuA3eN+EQPwBIgGjW7S9/kAWTv7GErvvze7LL/wqs="
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -694,5 +589,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"net.java.dev.jna:jna": {
"5.6.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"jna-5.6.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
@@ -19,13 +16,9 @@
"hash": "sha256-X+gbAlWXjyRhbTexBgi3lJil8wc+HZsgONhzaoMfJgg="
}
}
}
},
"org.jetbrains.intellij.deps:trove4j": {
"1.0.20200330": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"trove4j-1.0.20200330.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
@@ -41,13 +34,9 @@
"hash": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k="
}
}
}
},
"org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"org.jetbrains.kotlin.jvm.gradle.plugin-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/jvm/org.jetbrains.kotlin.jvm.gradle.plugin/1.7.21/org.jetbrains.kotlin.jvm.gradle.plugin-1.7.21.pom"
@@ -55,13 +44,9 @@
"hash": "sha256-18S+c5nTziimR77ivh3nCwUdpLqoz9X4KYNDJ2UKD30="
}
}
}
},
"org.jetbrains.kotlin:kotlin-android-extensions": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-android-extensions-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-android-extensions/1.7.21/kotlin-android-extensions-1.7.21.jar"
@@ -75,13 +60,9 @@
"hash": "sha256-8pic3UN0A8hyZc/K8GHSFOaGlVyX40ntFWa6FqouDI0="
}
}
}
},
"org.jetbrains.kotlin:kotlin-annotation-processing-gradle": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-annotation-processing-gradle-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-annotation-processing-gradle/1.7.21/kotlin-annotation-processing-gradle-1.7.21.jar"
@@ -95,13 +76,9 @@
"hash": "sha256-r2JZxfjfTezw8FXmZcTLaP8TtK9c1HfuHTO/7gAaFr4="
}
}
}
},
"org.jetbrains.kotlin:kotlin-build-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-build-common-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-build-common/1.7.21/kotlin-build-common-1.7.21.jar"
@@ -115,13 +92,9 @@
"hash": "sha256-msmBVHbIUfFKH3QeG46CJRxyepVGgMdXT4owUn2z718="
}
}
}
},
"org.jetbrains.kotlin:kotlin-compiler-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-compiler-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar",
@@ -137,13 +110,9 @@
"hash": "sha256-CwIzMip2MO/eEzUmjkYSPw1tNjg5gg/TfE7Lbv+njjs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-compiler-runner": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-compiler-runner-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-runner/1.7.21/kotlin-compiler-runner-1.7.21.jar"
@@ -157,13 +126,9 @@
"hash": "sha256-+JDieVykDuyu+jpdjkOND3C7YCo5SUe7rOp2Quqy+Tw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-daemon-client": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-daemon-client-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-client/1.7.21/kotlin-daemon-client-1.7.21.jar"
@@ -177,13 +142,9 @@
"hash": "sha256-Be4Gj7v3IvWRSlqiWO6KKLZChF9B1/+bVGhtXKJbvxk="
}
}
}
},
"org.jetbrains.kotlin:kotlin-daemon-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-daemon-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar",
@@ -199,13 +160,9 @@
"hash": "sha256-vB3pwgh7ouTlQQF6i66PQF7IAKGK5MJH6R8rVedh5kk="
}
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-1.7.21-gradle71.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21-gradle71.jar"
@@ -217,15 +174,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21.module"
],
"hash": "sha256-j6I2KYtJBynes0XjG8ZPKSj3wbXxwjH8ZtvINlnBZ+E="
}
},
"kotlin-gradle-plugin-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin/1.7.21/kotlin-gradle-plugin-1.7.21.pom"
],
"hash": "sha256-0gTXpKcf6Scv44M9x0IAkan/EJaky6JfcnihlUI1BGk="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-api": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-api-1.7.21-gradle71.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21-gradle71.jar"
@@ -243,15 +202,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21.module"
],
"hash": "sha256-zGXnGhweng0JaG9cpJGORShIY1q7VCl15HwYlnw6A10="
}
},
"kotlin-gradle-plugin-api-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-api/1.7.21/kotlin-gradle-plugin-api-1.7.21.pom"
],
"hash": "sha256-89unBFqYcdah5QnkF+tjQa3bmHFaL409ZnJlAdq0s0Y="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-idea-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.jar"
@@ -263,15 +224,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.module"
],
"hash": "sha256-ygHy2JJMcpaXMax+oVbwi7GP60LDEAClIj2dwW1ZuTg="
}
},
"kotlin-gradle-plugin-idea-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea/1.7.21/kotlin-gradle-plugin-idea-1.7.21.pom"
],
"hash": "sha256-Flz/idoRsXIpiJPHg0sNQadm1/PdIPoIvfiJxlXD5zc="
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-idea-proto-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-idea-proto/1.7.21/kotlin-gradle-plugin-idea-proto-1.7.21.jar"
@@ -285,13 +248,9 @@
"hash": "sha256-PRwDYK9odF8qAyoMAYR//Pnriq1wa/ZZydhAoYTsXyM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-gradle-plugin-model": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-gradle-plugin-model-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.jar"
@@ -303,15 +262,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.module"
],
"hash": "sha256-kCJoZCp1guVF4xgQnjdIw3WxOLCKFVuBX2yAi7vuR7U="
}
},
"kotlin-gradle-plugin-model-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-gradle-plugin-model/1.7.21/kotlin-gradle-plugin-model-1.7.21.pom"
],
"hash": "sha256-y2vKOdHhBWBXcMCj3ubUXw58XtPFNGiZ9ycQsf//HaY="
}
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-api": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-klib-commonizer-api-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-klib-commonizer-api/1.7.21/kotlin-klib-commonizer-api-1.7.21.jar"
@@ -325,13 +286,9 @@
"hash": "sha256-so6g3vy5lNH7U6e7olh9J0DG0mAXk2UglP1ox0Ul0CA="
}
}
}
},
"org.jetbrains.kotlin:kotlin-klib-commonizer-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-klib-commonizer-embeddable-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-klib-commonizer-embeddable/1.7.21/kotlin-klib-commonizer-embeddable-1.7.21.jar"
@@ -345,13 +302,9 @@
"hash": "sha256-bOmRoyzYOdq3wbf88+1xbr6XgbRgg3ViDC9fH8RwjrA="
}
}
}
},
"org.jetbrains.kotlin:kotlin-native-utils": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-native-utils-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-native-utils/1.7.21/kotlin-native-utils-1.7.21.jar"
@@ -365,13 +318,9 @@
"hash": "sha256-CEYFdUhagoAZC0g8H3fyCk063IegIXTzDuxVdNm65FY="
}
}
}
},
"org.jetbrains.kotlin:kotlin-project-model": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-project-model-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-project-model/1.7.21/kotlin-project-model-1.7.21.jar"
@@ -385,13 +334,9 @@
"hash": "sha256-JQfT7SKoHyssNSxMUOY1MivHEQClFQJN0NtQRifJ8Bs="
}
}
}
},
"org.jetbrains.kotlin:kotlin-reflect": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-reflect-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-reflect/1.7.21/kotlin-reflect-1.7.21.jar"
@@ -405,13 +350,9 @@
"hash": "sha256-Xn69/iAG9vHksPORwbqBhTmKj2NF2xpStYTx40Cz8EM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-script-runtime": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-script-runtime-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-script-runtime/1.7.21/kotlin-script-runtime-1.7.21.jar"
@@ -425,13 +366,9 @@
"hash": "sha256-LuSdd/3Dw6l0akiYCbfGQ3fh2NnEXCDZI+MXI5sicwQ="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-common-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar",
@@ -447,13 +384,9 @@
"hash": "sha256-2xzYRWGPDLQXOK3H72jZ+NIjZ1sFg+NbsMCEA30AWe4="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-compiler-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar",
@@ -469,13 +402,9 @@
"hash": "sha256-xHXL2+0BepcMD9y46qu1UNc9E6T+a4e3efxM9S148JM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-compiler-impl-embeddable-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar",
@@ -491,13 +420,9 @@
"hash": "sha256-5c0+HEj+qhC1YVqidOFh5/dcFijcJhZ1ALZ0b4gfweM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-scripting-jvm": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-scripting-jvm-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar",
@@ -513,13 +438,9 @@
"hash": "sha256-cnwtOnluoiOWPu7P7kHvKygsVbZ+V8O0mgFwpMSbfGE="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.7.21/kotlin-stdlib-1.7.21.jar"
@@ -533,13 +454,9 @@
"hash": "sha256-mzkq1D4vQhJp9jxiBz+ulCN9LjHe7o9msZzBkbTaBqw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.7.21/kotlin-stdlib-common-1.7.21.jar"
@@ -553,13 +470,9 @@
"hash": "sha256-LuberkeOGLGvushzHFvxoUe1dWiT1Z7b+nEWBcNDX4Q="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk7": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-jdk7-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.7.21/kotlin-stdlib-jdk7-1.7.21.jar"
@@ -573,13 +486,9 @@
"hash": "sha256-vy6yU9onofKT0RRpMpRBeF26xRceWB8v7Z1aKm2YaZw="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-jdk8": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-jdk8-1.7.21.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk8/1.7.21/kotlin-stdlib-jdk8-1.7.21.jar"
@@ -593,13 +502,9 @@
"hash": "sha256-bzuTQ8QS1q5ApMePuKcJhklkUKlSjNusdimojhqlg4k="
}
}
}
},
"org.jetbrains.kotlin:kotlin-tooling-core": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-tooling-core-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-tooling-core/1.7.21/kotlin-tooling-core-1.7.21.jar"
@@ -613,13 +518,9 @@
"hash": "sha256-tw2g1Eorhw7Lz85ZcMMOOOLs3htfQqHdRC0TA5gSKUY="
}
}
}
},
"org.jetbrains.kotlin:kotlin-util-io": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-util-io-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-io/1.7.21/kotlin-util-io-1.7.21.jar"
@@ -633,13 +534,9 @@
"hash": "sha256-ziTM1kPWW+8Cey9uINCnkhdq29ug2eVVmS5CR6Y3Ne8="
}
}
}
},
"org.jetbrains.kotlin:kotlin-util-klib": {
"1.7.21": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-util-klib-1.7.21.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-util-klib/1.7.21/kotlin-util-klib-1.7.21.jar"
@@ -653,13 +550,9 @@
"hash": "sha256-D8d7J3Rc+kzuX+AA5tEpmtSUT3rMB4A7u8ws0rAT3oU="
}
}
}
},
"org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm": {
"1.5.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlinx-coroutines-core-jvm-1.5.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.jar"
@@ -671,15 +564,17 @@
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.module"
],
"hash": "sha256-yIXdAoEHbFhDgm3jF+PLzcPYhZ2+71OuHPrNG5xg+W4="
}
},
"kotlinx-coroutines-core-jvm-1.5.0.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlinx/kotlinx-coroutines-core-jvm/1.5.0/kotlinx-coroutines-core-jvm-1.5.0.pom"
],
"hash": "sha256-U2IuA3eN+EQPwBIgGjW7S9/kAWTv7GErvvze7LL/wqs="
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -694,5 +589,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test": {
"1.0.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-1.0.0.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test/1.0.0/test-1.0.0.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"org.apache:test": {
"1.0.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"test-1.0.0.jar": {
"urls": [
"file:/home/tad/proj/gradle2nix/fixtures/repositories/m2/org/apache/test/1.0.0/test-1.0.0.jar"
@@ -18,5 +15,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.squareup.moshi:moshi": {
"1.8.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"moshi-1.8.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/moshi/moshi/1.8.0/moshi-1.8.0.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-FLuAWbnddiACWSkN+IfjfmaaB0qsnImUAePIEC/lII8="
}
}
}
},
"com.squareup.okio:okio": {
"2.2.2": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-2.2.2.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
@@ -36,12 +29,8 @@
],
"hash": "sha256-/WIZiPf2lXAlc13G3QkLAKIPOju413ynkDYHf2KbFAs="
}
}
},
"1.16.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-1.16.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.16.0/okio-1.16.0.jar"
@@ -55,13 +44,9 @@
"hash": "sha256-HSUhYhwIdRI6qRMRsv6O3v0O2T9mvm3+oYzGG8XJnjY="
}
}
}
},
"junit:junit": {
"4.12": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"junit-4.12.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.jar"
@@ -75,13 +60,9 @@
"hash": "sha256-kPFj944/+28cetl96efrpO6iWAcUG4XW0SvmfKJUScQ="
}
}
}
},
"org.hamcrest:hamcrest-core": {
"1.3": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"hamcrest-core-1.3.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar"
@@ -95,13 +76,9 @@
"hash": "sha256-/eOGp5BRc6GxA95quCBydYS1DQ4yKC4nl3h8IKZP+pM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.60/kotlin-stdlib-1.2.60.jar"
@@ -115,13 +92,9 @@
"hash": "sha256-5jKJkgnmtMqrlA/YLk7GOjLjJkP4Fff6cJdkeJDXnxg="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.60/kotlin-stdlib-common-1.2.60.jar"
@@ -135,13 +108,9 @@
"hash": "sha256-gwwnrx4c8k8PUm6kV5AcQ/OMGbtvfl03Y8PSU98bjaE="
}
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -156,5 +125,4 @@
}
}
}
}
}

View File

@@ -1,9 +1,6 @@
{
"com.squareup.moshi:moshi": {
"1.8.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"moshi-1.8.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/moshi/moshi/1.8.0/moshi-1.8.0.jar"
@@ -17,13 +14,9 @@
"hash": "sha256-FLuAWbnddiACWSkN+IfjfmaaB0qsnImUAePIEC/lII8="
}
}
}
},
"com.squareup.okio:okio": {
"2.2.2": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-2.2.2.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.2.2/okio-2.2.2.jar"
@@ -36,12 +29,8 @@
],
"hash": "sha256-/WIZiPf2lXAlc13G3QkLAKIPOju413ynkDYHf2KbFAs="
}
}
},
"1.16.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"okio-1.16.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.16.0/okio-1.16.0.jar"
@@ -55,13 +44,9 @@
"hash": "sha256-HSUhYhwIdRI6qRMRsv6O3v0O2T9mvm3+oYzGG8XJnjY="
}
}
}
},
"junit:junit": {
"4.12": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"junit-4.12.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/junit/junit/4.12/junit-4.12.jar"
@@ -75,13 +60,9 @@
"hash": "sha256-kPFj944/+28cetl96efrpO6iWAcUG4XW0SvmfKJUScQ="
}
}
}
},
"org.hamcrest:hamcrest-core": {
"1.3": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"hamcrest-core-1.3.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar"
@@ -95,13 +76,9 @@
"hash": "sha256-/eOGp5BRc6GxA95quCBydYS1DQ4yKC4nl3h8IKZP+pM="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.2.60/kotlin-stdlib-1.2.60.jar"
@@ -115,13 +92,9 @@
"hash": "sha256-5jKJkgnmtMqrlA/YLk7GOjLjJkP4Fff6cJdkeJDXnxg="
}
}
}
},
"org.jetbrains.kotlin:kotlin-stdlib-common": {
"1.2.60": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"kotlin-stdlib-common-1.2.60.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.2.60/kotlin-stdlib-common-1.2.60.jar"
@@ -135,13 +108,9 @@
"hash": "sha256-gwwnrx4c8k8PUm6kV5AcQ/OMGbtvfl03Y8PSU98bjaE="
}
}
}
},
"org.jetbrains:annotations": {
"13.0": {
"needsPomRedirect": true,
"needsIvyRedirect": false,
"files": {
"annotations-13.0.jar": {
"urls": [
"https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.jar"
@@ -156,5 +125,4 @@
}
}
}
}
}

View File

@@ -0,0 +1,10 @@
apply plugin: 'java'
repositories {
maven { url = uri(System.getProperty("org.nixos.gradle2nix.m2")) }
}
dependencies {
implementation 'org.test.included:included-child'
implementation 'org.apache:test:1.0.0'
}

View File

@@ -0,0 +1,11 @@
apply plugin: 'java-library'
group = 'org.test.included'
version = '1.0'
repositories {
maven { url = uri(System.getProperty("org.nixos.gradle2nix.m2")) }
}
dependencies {
implementation 'org.apache:foo:1.0.0'
}

View File

@@ -0,0 +1,10 @@
buildscript {
repositories {
maven { url = uri(System.getProperty("org.nixos.gradle2nix.m2")) }
}
dependencies {
classpath 'org.apache:foo:2.0.0'
}
}
rootProject.name = 'included-child'

View File

@@ -0,0 +1 @@
includeBuild 'included-child'

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>foo</artifactId>
<version>1.0.0</version>
<name>foo</name>
<description>
foo
</description>
</project>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>foo</artifactId>
<version>2.0.0</version>
<name>foo</name>
<description>
foo
</description>
</project>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<metadata>
<groupId>org.apache</groupId>
<artifactId>foo</artifactId>
<versioning>
<latest>2.0.0</latest>
<release>2.0.0</release>
<versions>
<version>1.0.0</version>
<version>2.0.0</version>
</versions>
</versioning>
</metadata>

View File

@@ -1 +0,0 @@
88e79ca0e696263e63bc9dc759a2e9c0d66e36d9

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.apache</groupId>
<artifactId>test</artifactId>
<version>2.0.0</version>
<name>test</name>
<description>
test
</description>
</project>

View File

@@ -20,5 +20,12 @@
<metadata>
<groupId>org.apache</groupId>
<artifactId>test</artifactId>
<versioning>
<latest>2.0.0</latest>
<release>2.0.0</release>
<versions>
<version>1.0.0</version>
<version>2.0.0</version>
</versions>
</versioning>
</metadata>

12
flake.lock generated
View File

@@ -5,11 +5,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1694529238,
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
"lastModified": 1701680307,
"narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
"rev": "4022d587cbbfd70fe950c1e2083a02621806a725",
"type": "github"
},
"original": {
@@ -20,11 +20,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1696589439,
"narHash": "sha256-Ye+flokLfswVz9PZEyJ5yGJ1VqmJe3bDgwWt9Z4MuqQ=",
"lastModified": 1702855317,
"narHash": "sha256-5EXeUkoWvrfbZQQLVRn7Ebb9LOt3DkVm6T0M31/VhtM=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "e462c9172c685f0839baaa54bb5b49276a23dab7",
"rev": "3a16c6447466f4034c2d75fe7014477142c9513e",
"type": "github"
},
"original": {

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,8 @@
, fetchs3
, fetchurl
, gradleGen
, runCommandLocal
, symlinkJoin
, writeText
, writeTextDir
}:
@@ -32,7 +34,7 @@
{
# Path to the environment spec generated by gradle2nix (e.g. gradle-env.json).
envSpec
, pname ? null
, pname ? "project"
, version ? null
, enableParallelBuilding ? true
# Arguments to Gradle used to build the project in buildPhase.
@@ -52,9 +54,10 @@
# `{ urls, sha256 }` and fetch into the Nix store. For example:
#
# {
# s3 = { urls, sha256 }: fetchs3 {
# s3 = { name, urls, hash }: fetchs3 {
# s3url = builtins.head urls;
# inherit sha256;
# # TODO This doesn't work without patching fetchs3 to accept SRI hashes
# inherit name hash;
# region = "us-west-2";
# credentials = {
# access_key_id = "foo";
@@ -67,7 +70,7 @@
let
inherit (builtins)
attrValues concatStringsSep filter fromJSON getAttr head match
attrValues concatStringsSep elemAt filter fromJSON getAttr head match
replaceStrings sort;
inherit (lib)
@@ -75,47 +78,69 @@ let
mapAttrsToList optionalString readFile removeSuffix unique versionAtLeast
versionOlder;
inherit (lib.strings) sanitizeDerivationName;
toCoordinates = id:
let
coords = builtins.split ":" id;
in {
group = elemAt coords 0;
module = elemAt coords 2;
};
fetchers' = {
http = fetchurl;
https = fetchurl;
s3 = { urls, sha256 }: fetchs3 {
s3url = head urls;
inherit sha256;
};
} // fetchers;
# 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 = { urls, sha256 }:
fetch = _: { urls, hash }:
let
first = head urls;
scheme = head (builtins.match "([a-z0-9+.-]+)://.*" first);
fetch' = getAttr scheme fetchers';
urls' = filter (hasPrefix scheme) urls;
in
fetch' { urls = urls'; inherit sha256; };
fetch' { urls = urls'; inherit hash; };
mkDep = { name, path, urls, sha256, ... }: stdenv.mkDerivation {
inherit name;
src = fetch {
inherit urls sha256;
};
phases = "installPhase";
installPhase = ''
mkdir -p $out/${path}
ln -s $src $out/${path}/${name}
'';
};
mkModuleMetadata = deps:
mkDep = id: version: artifacts:
let
coords = toCoordinates id;
modulePath = "${replaceStrings ["."] ["/"] coords.group}/${coords.module}/${version}";
in
stdenv.mkDerivation {
pname = "${coords.group}-${coords.module}";
version = version;
srcs = mapAttrsToList fetch artifacts;
dontPatch = true;
dontConfigure = true;
dontBuild = true;
dontFixup = true;
dontInstall = true;
preUnpack = ''
mkdir -p "$out/${modulePath}"
'';
unpackCmd = ''
cp "$curSrc" "$out/${modulePath}/$(stripHash "$curSrc")"
'';
sourceRoot = ".";
preferLocalBuild = true;
allowSubstitutes = false;
};
mkModule = id: versions:
mapAttrsToList (version: artifacts: mkDep id version artifacts) versions;
mkModuleMetadata = id: versions:
let
ids = filter
(id: id.type == "pom")
(map (dep: dep.id) deps);
modules = groupBy'
(meta: id:
@@ -161,76 +186,77 @@ let
''
) modules);
mkSnapshotMetadata = deps:
let
snapshotDeps = filter (dep: dep ? build && dep ? timestamp) 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;
}];
}
)
{
timestamp = "";
buildNumber = -1;
lastUpdated = "";
}
(dep: "${replaceStrings ["."] ["/"] dep.id.group}/${dep.id.name}/${dep.id.version}/maven-metadata.xml")
snapshotDeps;
# 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 = "";
# }
# (dep: "${replaceStrings ["."] ["/"] dep.id.group}/${dep.id.name}/${dep.id.version}/maven-metadata.xml")
# snapshotDeps;
mkSnapshotVersion = version: ''
<snapshotVersion>
${optionalString (version.classifier != "") "<classifier>${version.classifier}</classifier>"}
<extension>${version.extension}</extension>
<value>${version.value}</value>
${optionalString (version.updated != "") "<updated>${version.updated}</updated>"}
</snapshotVersion>
'';
# mkSnapshotVersion = version: ''
# <snapshotVersion>
# ${optionalString (version.classifier != "") "<classifier>${version.classifier}</classifier>"}
# <extension>${version.extension}</extension>
# <value>${version.value}</value>
# ${optionalString (version.updated != "") "<updated>${version.updated}</updated>"}
# </snapshotVersion>
# '';
in
attrValues (mapAttrs (path: meta:
with meta; writeTextDir path ''
<?xml version="1.0" encoding="UTF-8"?>
<metadata modelVersion="1.1">
<groupId>${groupId}</groupId>
<artifactId>${artifactId}</artifactId>
<version>${version}</version>
<versioning>
<snapshot>
${optionalString (timestamp != "") "<timestamp>${timestamp}</timestamp>"}
${optionalString (buildNumber != -1) "<buildNumber>${toString buildNumber}</buildNumber>"}
</snapshot>
${optionalString (lastUpdated != "") "<lastUpdated>${lastUpdated}</lastUpdated>"}
<snapshotVersions>
${concatMapStringsSep "\n " mkSnapshotVersion versions}
</snapshotVersions>
</versioning>
</metadata>
''
) modules);
# in
# attrValues (mapAttrs (path: meta:
# with meta; writeTextDir path ''
# <?xml version="1.0" encoding="UTF-8"?>
# <metadata modelVersion="1.1">
# <groupId>${groupId}</groupId>
# <artifactId>${artifactId}</artifactId>
# <version>${version}</version>
# <versioning>
# <snapshot>
# ${optionalString (timestamp != "") "<timestamp>${timestamp}</timestamp>"}
# ${optionalString (buildNumber != -1) "<buildNumber>${toString buildNumber}</buildNumber>"}
# </snapshot>
# ${optionalString (lastUpdated != "") "<lastUpdated>${lastUpdated}</lastUpdated>"}
# <snapshotVersions>
# ${concatMapStringsSep "\n " mkSnapshotVersion versions}
# </snapshotVersions>
# </versioning>
# </metadata>
# ''
# ) modules);
mkRepo = project: type: deps: buildEnv {
name = "${project}-gradle-${type}-env";
paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
mkRepo = name: deps: symlinkJoin {
name = "${name}-gradle-env";
# paths = map mkDep deps ++ mkModuleMetadata deps ++ mkSnapshotMetadata deps;
paths = mapAttrsToList mkModule deps;
};
mkInitScript = projectSpec: gradle:
@@ -264,12 +290,12 @@ let
static def offlineRepo(RepositoryHandler repositories, String env, String path) {
repositories.clear()
repositories.maven {
name "Nix''${env.capitalize()}MavenOffline"
name "Nix''${env.capitalize()}Offline"
url path
metadataSources {
it.gradleMetadata()
it.mavenPom()
it.artifact()
it.
}
}
repositories.ivy {
@@ -279,7 +305,6 @@ let
metadataSources {
it.gradleMetadata()
it.ivyDescriptor()
it.artifact()
}
}
}
@@ -371,29 +396,31 @@ let
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 -eux
# (
# set -eux
# Work around https://github.com/gradle/gradle/issues/1055
TMPHOME="$(mktemp -d)"
mkdir -p "$TMPHOME/init.d"
export GRADLE_USER_HOME="$TMPHOME"
# # Work around https://github.com/gradle/gradle/issues/1055
# TMPHOME="$(mktemp -d)"
# mkdir -p "$TMPHOME/init.d"
# export GRADLE_USER_HOME="$TMPHOME"
${buildIncludedProjects}
${buildRootProject}
)
# ${buildIncludedProjects}
# ${buildRootProject}
# )
runHook postBuild
'';
# runHook postBuild
# '';
dontStrip = true;
})
# dontStrip = true;
# })
in mkRepo pname (fromJSON (readFile envSpec))

View File

@@ -1,6 +1,6 @@
[versions]
gradle = "8.3"
kotlin = "1.9.20-Beta2"
gradle = "8.5"
kotlin = "1.9.21"
[libraries]
clikt = "com.github.ajalt:clikt:+"

Binary file not shown.

View File

@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

15
gradlew vendored
View File

@@ -83,10 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -133,10 +131,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -197,6 +198,10 @@ if "$cygwin" || "$msys" ; then
done
fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in

View File

@@ -1,8 +0,0 @@
package org.nixos.gradle2nix
import kotlinx.serialization.Serializable
@Serializable
data class DependencyCoordinates(val group: String, val module: String, val version: String) {
override fun toString(): String = "$group:$module:$version"
}

View File

@@ -0,0 +1,35 @@
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable
@Serializable
data class DependencyCoordinates(
val group: String,
val module: String,
val version: String,
val timestamp: String? = null
) {
override fun toString(): String = if (timestamp != null) {
"$group:$module:$version:$timestamp"
} else {
"$group:$module:$version"
}
val isSnapshot: Boolean get() = timestamp != null
val moduleVersion: String get() = version
val artifactVersion: String get() =
timestamp?.let { version.replace("SNAPSHOT", it) } ?: version
companion object {
fun parse(id: String): DependencyCoordinates {
val parts = id.split(":")
return when (parts.size) {
3 -> DependencyCoordinates(parts[0], parts[1], parts[2])
4 -> DependencyCoordinates(parts[0], parts[1], parts[2], parts[3])
else -> throw IllegalStateException(
"couldn't parse dependency coordinates: '$id'"
)
}
}
}
}

View File

@@ -1,5 +1,6 @@
package org.nixos.gradle2nix.dependencygraph.model
package org.nixos.gradle2nix.model
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
@@ -10,4 +11,16 @@ import kotlinx.serialization.Serializable
* We attempt to map this to an actual source file location when building a dependency report.
*/
@Serializable
data class DependencySource(val id: String, val path: String)
data class DependencySource(
val targetType: ConfigurationTarget,
val targetPath: String,
val buildPath: String,
)
@Serializable
enum class ConfigurationTarget {
@SerialName("gradle") GRADLE,
@SerialName("settings") SETTINGS,
@SerialName("buildscript") BUILDSCRIPT,
@SerialName("project") PROJECT,
}

View File

@@ -1,4 +1,4 @@
package org.nixos.gradle2nix
package org.nixos.gradle2nix.model
const val PARAM_INCLUDE_PROJECTS = "NIX_INCLUDE_PROJECTS"
const val PARAM_INCLUDE_CONFIGURATIONS = "NIX_INCLUDE_CONFIGURATIONS"

View File

@@ -1,4 +1,4 @@
package org.nixos.gradle2nix.dependencygraph.model
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable

View File

@@ -0,0 +1,16 @@
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable
@Serializable
data class ResolvedArtifact(
val type: Type?,
val file: String,
) {
enum class Type {
SOURCES,
JAVADOC,
IVY_DESCRIPTOR,
MAVEN_POM,
}
}

View File

@@ -1,4 +1,4 @@
package org.nixos.gradle2nix.dependencygraph.model
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable

View File

@@ -1,7 +1,6 @@
package org.nixos.gradle2nix.dependencygraph.model
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable
import org.nixos.gradle2nix.DependencyCoordinates
@Serializable
data class ResolvedDependency(
@@ -10,5 +9,5 @@ data class ResolvedDependency(
val direct: Boolean,
val coordinates: DependencyCoordinates,
val repository: String?,
val dependencies: List<String>
val dependencies: List<String> = emptyList(),
)

View File

@@ -0,0 +1,9 @@
package org.nixos.gradle2nix.model
import kotlinx.serialization.Serializable
@Serializable
data class ResolvedMetadata(
val moduleId: String,
val uri: String
)

View File

@@ -5,7 +5,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.nixos.gradle2nix.dependencygraph.DependencyGraphRenderer
import org.nixos.gradle2nix.dependencygraph.model.ResolvedConfiguration
import org.nixos.gradle2nix.model.ResolvedConfiguration
@OptIn(ExperimentalSerializationApi::class)
private val json = Json {

View File

@@ -1,15 +1,26 @@
package org.nixos.gradle2nix.dependencygraph
import org.gradle.api.Plugin
import org.gradle.api.internal.GradleInternal
import org.gradle.api.internal.project.DefaultProjectRegistry
import org.gradle.api.internal.project.ProjectInternal
import org.gradle.api.internal.project.ProjectRegistry
import org.gradle.api.invocation.Gradle
import org.gradle.api.logging.Logging
import org.gradle.api.provider.Provider
import org.gradle.api.services.internal.RegisteredBuildServiceProvider
import org.gradle.internal.build.BuildProjectRegistry
import org.gradle.internal.build.event.BuildEventListenerRegistryInternal
import org.gradle.internal.composite.IncludedBuildInternal
import org.gradle.internal.operations.BuildOperationAncestryTracker
import org.gradle.internal.operations.BuildOperationListenerManager
import org.gradle.util.GradleVersion
import org.nixos.gradle2nix.dependencygraph.extractor.DependencyExtractor
import org.nixos.gradle2nix.dependencygraph.extractor.DependencyExtractorBuildService
import org.nixos.gradle2nix.dependencygraph.extractor.LegacyDependencyExtractor
import org.nixos.gradle2nix.dependencygraph.util.buildDirCompat
import org.nixos.gradle2nix.dependencygraph.util.service
import org.nixos.gradle2nix.model.ConfigurationTarget
abstract class AbstractDependencyExtractorPlugin : Plugin<Gradle> {
// Register extension functions on `Gradle` type
@@ -39,6 +50,15 @@ abstract class AbstractDependencyExtractorPlugin : Plugin<Gradle> {
.rootProjectBuildDirectory = project.buildDirCompat
}
val logger = Logging.getLogger(AbstractDependencyExtractorPlugin::class.java.name)
gradle.projectsLoaded {
(gradle as GradleInternal).let { g ->
logger.lifecycle("all projects: ${g.owner.projects.allProjects}")
logger.lifecycle("included projects: ${g.includedBuilds().flatMap { it.target.projects.allProjects }.joinToString { it.identityPath.path }}")
}
}
// Register the service to listen for Build Events
applicatorStrategy.registerExtractorListener(gradle, dependencyExtractorProvider)
@@ -122,7 +142,6 @@ abstract class AbstractDependencyExtractorPlugin : Plugin<Gradle> {
gradle: Gradle,
extractorServiceProvider: Provider<out DependencyExtractor>
) {
// No-op as DependencyExtractorService is Auto-Closable
}
}
}

View File

@@ -1,7 +1,7 @@
package org.nixos.gradle2nix.dependencygraph
import java.io.File
import org.nixos.gradle2nix.dependencygraph.model.ResolvedConfiguration
import org.nixos.gradle2nix.model.ResolvedConfiguration
interface DependencyGraphRenderer {
fun outputDependencyGraph(

View File

@@ -3,12 +3,27 @@ package org.nixos.gradle2nix.dependencygraph.extractor
import java.io.File
import java.net.URI
import java.util.Collections
import java.util.concurrent.ConcurrentHashMap
import org.gradle.api.GradleException
import org.gradle.api.artifacts.DependencyResolutionListener
import org.gradle.api.artifacts.ResolvableDependencies
import org.gradle.api.artifacts.component.BuildIdentifier
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.query.ArtifactResolutionQuery
import org.gradle.api.artifacts.result.ResolvedArtifactResult
import org.gradle.api.artifacts.result.ResolvedComponentResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.component.Artifact
import org.gradle.api.internal.artifacts.DefaultModuleVersionIdentifier
import org.gradle.api.internal.artifacts.DefaultProjectComponentIdentifier
import org.gradle.api.internal.artifacts.configurations.ResolveConfigurationDependenciesBuildOperationType
import org.gradle.api.internal.artifacts.repositories.resolver.MavenUniqueSnapshotComponentIdentifier
import org.gradle.api.logging.Logging
import org.gradle.configuration.ApplyScriptPluginBuildOperationType
import org.gradle.configuration.ConfigurationTargetIdentifier
import org.gradle.initialization.LoadBuildBuildOperationType
import org.gradle.internal.component.external.model.DefaultModuleComponentIdentifier
import org.gradle.internal.component.external.model.ModuleComponentArtifactIdentifier
import org.gradle.internal.exceptions.DefaultMultiCauseException
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
@@ -16,27 +31,44 @@ import org.gradle.internal.operations.OperationFinishEvent
import org.gradle.internal.operations.OperationIdentifier
import org.gradle.internal.operations.OperationProgressEvent
import org.gradle.internal.operations.OperationStartEvent
import org.nixos.gradle2nix.PARAM_INCLUDE_CONFIGURATIONS
import org.nixos.gradle2nix.PARAM_INCLUDE_PROJECTS
import org.nixos.gradle2nix.PARAM_REPORT_DIR
import org.gradle.ivy.IvyDescriptorArtifact
import org.gradle.jvm.JvmLibrary
import org.gradle.language.base.artifact.SourcesArtifact
import org.gradle.language.java.artifact.JavadocArtifact
import org.gradle.maven.MavenPomArtifact
import org.gradle.util.GradleVersion
import org.nixos.gradle2nix.dependencygraph.DependencyGraphRenderer
import org.nixos.gradle2nix.DependencyCoordinates
import org.nixos.gradle2nix.dependencygraph.model.DependencySource
import org.nixos.gradle2nix.dependencygraph.model.Repository
import org.nixos.gradle2nix.dependencygraph.model.ResolvedConfiguration
import org.nixos.gradle2nix.dependencygraph.model.ResolvedDependency
import org.nixos.gradle2nix.dependencygraph.util.BuildOperationTracker
import org.nixos.gradle2nix.dependencygraph.util.loadOptionalParam
import org.nixos.gradle2nix.model.ConfigurationTarget
import org.nixos.gradle2nix.model.DependencyCoordinates
import org.nixos.gradle2nix.model.DependencySource
import org.nixos.gradle2nix.model.PARAM_INCLUDE_CONFIGURATIONS
import org.nixos.gradle2nix.model.PARAM_INCLUDE_PROJECTS
import org.nixos.gradle2nix.model.PARAM_REPORT_DIR
import org.nixos.gradle2nix.model.Repository
import org.nixos.gradle2nix.model.ResolvedArtifact
import org.nixos.gradle2nix.model.ResolvedConfiguration
import org.nixos.gradle2nix.model.ResolvedDependency
abstract class DependencyExtractor :
BuildOperationListener,
AutoCloseable {
private val configurations =
ConcurrentHashMap<
OperationIdentifier,
Pair<ResolveConfigurationDependenciesBuildOperationType.Details,
ResolveConfigurationDependenciesBuildOperationType.Result>>()
private val resolvedConfigurations = Collections.synchronizedList(mutableListOf<ResolvedConfiguration>())
private val thrownExceptions = Collections.synchronizedList(mutableListOf<Throwable>())
var rootProjectBuildDirectory: File? = null
private val operationTracker = BuildOperationTracker()
// Properties are lazily initialized so that System Properties are initialized by the time
// the values are used. This is required due to a bug in older Gradle versions. (https://github.com/gradle/gradle/issues/6825)
private val configurationFilter by lazy {
@@ -52,37 +84,37 @@ abstract class DependencyExtractor :
abstract fun getRendererClassName(): String
override fun started(buildOperation: BuildOperationDescriptor, startEvent: OperationStartEvent) {
// This method will never be called when registered in a `BuildServiceRegistry` (ie. Gradle 6.1 & higher)
// No-op
}
override fun started(buildOperation: BuildOperationDescriptor, startEvent: OperationStartEvent) {}
override fun progress(operationIdentifier: OperationIdentifier, progressEvent: OperationProgressEvent) {
// This method will never be called when registered in a `BuildServiceRegistry` (ie. Gradle 6.1 & higher)
// No-op
}
override fun progress(operationIdentifier: OperationIdentifier, progressEvent: OperationProgressEvent) {}
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
handleBuildOperationType<
operationTracker.finished(buildOperation, finishEvent)
handleFinishBuildOperationType<
ResolveConfigurationDependenciesBuildOperationType.Details,
ResolveConfigurationDependenciesBuildOperationType.Result
>(buildOperation, finishEvent) { details, result -> extractConfigurationDependencies(details, result) }
>(buildOperation, finishEvent) { details, result ->
buildOperation.id?.let { operationId ->
configurations[operationId] = details to result
}
}
}
private inline fun <reified D, reified R> handleBuildOperationType(
private inline fun <reified D, reified R> handleFinishBuildOperationType(
buildOperation: BuildOperationDescriptor,
finishEvent: OperationFinishEvent,
handler: (details: D, result: R) -> Unit
) {
try {
handleBuildOperationTypeRaw<D, R>(buildOperation, finishEvent, handler)
handleFinishBuildOperationTypeRaw<D, R>(buildOperation, finishEvent, handler)
} catch (e: Throwable) {
thrownExceptions.add(e)
throw e
}
}
private inline fun <reified D, reified R> handleBuildOperationTypeRaw(
private inline fun <reified D, reified R> handleFinishBuildOperationTypeRaw(
buildOperation: BuildOperationDescriptor,
finishEvent: OperationFinishEvent,
handler: (details: D, result: R) -> Unit
@@ -101,13 +133,28 @@ abstract class DependencyExtractor :
handler(details, result)
}
// This returns null for the root build, because the build operation won't complete until after close() is called.
private fun findBuildDetails(buildOperationId: OperationIdentifier?): LoadBuildBuildOperationType.Details? {
return operationTracker.findParent(buildOperationId) {
it.details as? LoadBuildBuildOperationType.Details
}
}
private fun processConfigurations() {
for ((operationId, data) in configurations) {
val (details, result) = data
extractConfigurationDependencies(operationId, details, result)
}
}
private fun extractConfigurationDependencies(
operationId: OperationIdentifier,
details: ResolveConfigurationDependenciesBuildOperationType.Details,
result: ResolveConfigurationDependenciesBuildOperationType.Result
) {
val repositories = details.repositories?.mapNotNull {
@Suppress("UNCHECKED_CAST")
Repository(
(Repository(
id = it.id,
type = enumValueOf(it.type),
name = it.name,
@@ -115,35 +162,53 @@ abstract class DependencyExtractor :
metadataSources = (it.properties["METADATA_SOURCES"] as? List<String>) ?: emptyList(),
metadataResources = metadataResources(it),
artifactResources = artifactResources(it),
)
))
} ?: emptyList()
if (repositories.isEmpty()) {
return
}
val rootComponent = result.rootComponent
if (rootComponent.dependencies.isEmpty()) {
// No dependencies to extract: can safely ignore
return
}
val projectIdentityPath = (rootComponent.id as? DefaultProjectComponentIdentifier)?.identityPath?.path
// TODO: At this point, any resolution not bound to a particular project will be assigned to the root "build :"
// This is because `details.buildPath` is always ':', which isn't correct in a composite build.
// It is possible to do better. By tracking the current build operation context, we can assign more precisely.
// See the Gradle Enterprise Build Scan Plugin: `ConfigurationResolutionCapturer_5_0`
val rootPath = projectIdentityPath ?: details.buildPath
if (!configurationFilter.include(rootPath, details.configurationName)) {
LOGGER.debug("Ignoring resolved configuration: $rootPath - ${details.configurationName}")
return
val source: DependencySource = when {
details.isScriptConfiguration -> {
val parent = operationTracker.findParent(operationId) {
it.details as? ApplyScriptPluginBuildOperationType.Details
} ?: throw IllegalStateException("Couldn't find parent script operation for ${details.configurationName}")
DependencySource(
targetType = when (parent.targetType) {
ConfigurationTargetIdentifier.Type.GRADLE.label -> ConfigurationTarget.GRADLE
ConfigurationTargetIdentifier.Type.SETTINGS.label -> ConfigurationTarget.SETTINGS
ConfigurationTargetIdentifier.Type.PROJECT.label -> ConfigurationTarget.BUILDSCRIPT
else -> throw IllegalStateException("Unknown configuration target type: ${parent.targetType}")
},
targetPath = parent.targetPath ?: ":",
buildPath = parent.buildPath!!
)
}
else -> {
DependencySource(
targetType = ConfigurationTarget.PROJECT,
targetPath = details.projectPath!!,
buildPath = details.buildPath
)
}
}
val rootId = if (projectIdentityPath == null) "build $rootPath" else componentId(rootComponent)
val rootSource = DependencySource(rootId, rootPath)
val resolvedConfiguration = ResolvedConfiguration(rootSource, details.configurationName, repositories)
val resolvedConfiguration = ResolvedConfiguration(source, details.configurationName, repositories)
for (directDependency in getResolvedDependencies(rootComponent)) {
val moduleComponentId = directDependency.id as? ModuleComponentIdentifier ?: continue
val directDep = createComponentNode(
componentId(directDependency),
rootSource,
moduleComponentId,
source,
true,
directDependency,
result.getRepositoryId(directDependency)
@@ -167,16 +232,18 @@ abstract class DependencyExtractor :
val dependencyComponents = getResolvedDependencies(component)
for (dependencyComponent in dependencyComponents) {
val dependencyId = componentId(dependencyComponent)
if (!resolvedConfiguration.hasDependency(dependencyId)) {
if (!resolvedConfiguration.hasDependency(componentId(dependencyComponent))) {
val moduleComponentId = dependencyComponent.id as? ModuleComponentIdentifier
if (moduleComponentId != null) {
val dependencyNode = createComponentNode(
dependencyId,
moduleComponentId,
componentSource,
direct,
dependencyComponent,
result.getRepositoryId(component)
)
resolvedConfiguration.addDependency(dependencyNode)
}
walkComponentDependencies(result, dependencyComponent, componentSource, resolvedConfiguration)
}
@@ -186,24 +253,40 @@ abstract class DependencyExtractor :
private fun getSource(component: ResolvedComponentResult, source: DependencySource): DependencySource {
val componentId = component.id
if (componentId is DefaultProjectComponentIdentifier) {
return DependencySource(componentId(component), componentId.identityPath.path)
return DependencySource(
ConfigurationTarget.PROJECT,
componentId.projectPath,
componentId.build.buildPathCompat
)
}
return source
}
private val BuildIdentifier.buildPathCompat: String
@Suppress("DEPRECATION")
get() = if (GradleVersion.current() < GradleVersion.version("8.2")) name else buildPath
private fun getResolvedDependencies(component: ResolvedComponentResult): List<ResolvedComponentResult> {
return component.dependencies.filterIsInstance<ResolvedDependencyResult>().map { it.selected }.filter { it != component }
}
private fun createComponentNode(componentId: String, source: DependencySource, direct: Boolean, component: ResolvedComponentResult, repositoryId: String?): ResolvedDependency {
val componentDependencies = component.dependencies.filterIsInstance<ResolvedDependencyResult>().map { componentId(it.selected) }
private fun createComponentNode(
componentId: ModuleComponentIdentifier,
source: DependencySource,
direct: Boolean,
component: ResolvedComponentResult,
repositoryId: String?
): ResolvedDependency {
val componentDependencies =
component.dependencies.filterIsInstance<ResolvedDependencyResult>().map { componentId(it.selected) }
val coordinates = coordinates(componentId)
return ResolvedDependency(
componentId,
componentId.displayName,
source,
direct,
coordinates(component),
coordinates,
repositoryId,
componentDependencies
componentDependencies,
)
}
@@ -211,16 +294,25 @@ abstract class DependencyExtractor :
return component.id.displayName
}
private fun coordinates(component: ResolvedComponentResult): DependencyCoordinates {
// TODO: Consider and handle null moduleVersion
val moduleVersionIdentifier = component.moduleVersion!!
private fun coordinates(componentId: ModuleComponentIdentifier): DependencyCoordinates {
return DependencyCoordinates(
moduleVersionIdentifier.group,
moduleVersionIdentifier.name,
moduleVersionIdentifier.version
componentId.group,
componentId.module,
componentId.version,
(componentId as? MavenUniqueSnapshotComponentIdentifier)?.timestamp
)
}
private fun artifactType(type: Class<out Artifact>): ResolvedArtifact.Type? {
return when (type) {
SourcesArtifact::class.java -> ResolvedArtifact.Type.SOURCES
JavadocArtifact::class.java -> ResolvedArtifact.Type.JAVADOC
IvyDescriptorArtifact::class.java -> ResolvedArtifact.Type.IVY_DESCRIPTOR
MavenPomArtifact::class.java -> ResolvedArtifact.Type.MAVEN_POM
else -> null
}
}
private fun writeDependencyGraph() {
val outputDirectory = getOutputDir()
outputDirectory.mkdirs()
@@ -248,6 +340,8 @@ abstract class DependencyExtractor :
}
override fun close() {
LOGGER.lifecycle("DependencyExtractor: CLOSE")
if (thrownExceptions.isNotEmpty()) {
throw DefaultMultiCauseException(
"The Gradle2Nix plugin encountered errors while extracting dependencies. " +
@@ -256,6 +350,10 @@ abstract class DependencyExtractor :
)
}
try {
processConfigurations()
LOGGER.lifecycle("Resolved ${resolvedConfigurations.size} configurations.")
writeDependencyGraph()
} catch (e: RuntimeException) {
throw GradleException(

View File

@@ -8,7 +8,6 @@ abstract class DependencyExtractorBuildService :
DependencyExtractor(),
BuildService<DependencyExtractorBuildService.Params>
{
// Some parameters for the web server
internal interface Params : BuildServiceParameters {
val rendererClassName: Property<String>
}

View File

@@ -0,0 +1,64 @@
package org.nixos.gradle2nix.dependencygraph.util
import java.util.concurrent.ConcurrentHashMap
import org.gradle.api.logging.Logging
import org.gradle.internal.operations.BuildOperation
import org.gradle.internal.operations.BuildOperationDescriptor
import org.gradle.internal.operations.BuildOperationListener
import org.gradle.internal.operations.OperationFinishEvent
import org.gradle.internal.operations.OperationIdentifier
import org.gradle.internal.operations.OperationProgressEvent
import org.gradle.internal.operations.OperationStartEvent
class BuildOperationTracker : BuildOperationListener {
private val _parents: MutableMap<OperationIdentifier, OperationIdentifier?> = ConcurrentHashMap()
private val _operations: MutableMap<OperationIdentifier, BuildOperationDescriptor> = ConcurrentHashMap()
private val _results: MutableMap<OperationIdentifier, Any> = ConcurrentHashMap()
val parents: Map<OperationIdentifier, OperationIdentifier?> get() = _parents
val operations: Map<OperationIdentifier, BuildOperationDescriptor> get() = _operations
val results: Map<OperationIdentifier, Any> get() = _results
override fun started(buildOperation: BuildOperationDescriptor, startEvent: OperationStartEvent) {
}
override fun progress(operationIdentifier: OperationIdentifier, progressEvent: OperationProgressEvent) {
}
override fun finished(buildOperation: BuildOperationDescriptor, finishEvent: OperationFinishEvent) {
val id = buildOperation.id ?: return
_parents[id] = buildOperation.parentId
_operations[id] = buildOperation
}
tailrec fun <T> findParent(id: OperationIdentifier?, block: (BuildOperationDescriptor) -> T?): T? {
if (id == null) return null
val operation = _operations[id] ?: return null.also {
LOGGER.lifecycle("no operation for $id")
}
return block(operation) ?: findParent(operation.parentId, block)
}
fun <T> findChild(id: OperationIdentifier?, block: (BuildOperationDescriptor) -> T?): T? {
if (id == null) return null
val operation = operations[id] ?: return null
block(operation)?.let { return it }
return children(id).firstNotNullOfOrNull { findChild(it, block) }
}
fun children(id: OperationIdentifier): Set<OperationIdentifier> {
return parents.filterValues { it == id }.keys
}
inline fun <reified T> getDetails(id: OperationIdentifier): T? {
return operations[id]?.details as? T
}
inline fun <reified T> getResult(id: OperationIdentifier): T? {
return results[id] as? T
}
companion object {
private val LOGGER = Logging.getLogger(BuildOperationTracker::class.qualifiedName!!)
}
}

View File

@@ -6,8 +6,8 @@ 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.RESOLVE_ALL_TASK
import org.nixos.gradle2nix.RESOLVE_PROJECT_TASK
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import org.nixos.gradle2nix.model.RESOLVE_PROJECT_TASK
// TODO: Rename these