Fix ivy descriptor and snapshot artifacts

This commit is contained in:
Tad Fisher
2023-12-19 17:40:34 -08:00
parent 8ceeeb9611
commit e83e42f9d4
11 changed files with 382 additions and 365 deletions

View File

@@ -21,8 +21,6 @@ import org.nixos.gradle2nix.env.ArtifactSet
import org.nixos.gradle2nix.env.Env
import org.nixos.gradle2nix.env.Module
import org.nixos.gradle2nix.env.ModuleId
import org.nixos.gradle2nix.env.ModuleVersionId
import org.nixos.gradle2nix.env.Version
import org.nixos.gradle2nix.metadata.Checksum
import org.nixos.gradle2nix.metadata.Component
import org.nixos.gradle2nix.metadata.Md5
@@ -31,6 +29,8 @@ import org.nixos.gradle2nix.metadata.Sha256
import org.nixos.gradle2nix.metadata.Sha512
import org.nixos.gradle2nix.metadata.VerificationMetadata
import org.nixos.gradle2nix.metadata.parseVerificationMetadata
import org.nixos.gradle2nix.model.DependencyCoordinates
import org.nixos.gradle2nix.model.Version
import org.nixos.gradle2nix.module.GradleModule
import org.nixos.gradle2nix.module.Variant
@@ -44,12 +44,10 @@ private fun shouldSkipRepository(repository: Repository): Boolean {
fun processDependencies(config: Config): Env {
val verificationMetadata = readVerificationMetadata(config)
val verificationComponents = verificationMetadata?.components?.associateBy {
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 verificationComponents = verificationMetadata?.components?.associateBy { it.id } ?: emptyMap()
val moduleCache = mutableMapOf<DependencyCoordinates, GradleModule?>()
val pomCache = mutableMapOf<DependencyCoordinates, Pair<String, ArtifactFile>?>()
val ivyCache = mutableMapOf<DependencyCoordinates, Pair<String, ArtifactFile>?>()
val configurations = readDependencyGraph(config)
val repositories = configurations
@@ -71,15 +69,14 @@ fun processDependencies(config: Config): Env {
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) }
.mapValues { (id, deps) ->
val versions = deps.groupBy { Version(it.coordinates.version) }
.mapValues { (version, deps) ->
val componentId = ModuleVersionId(id, version)
.filterNot { it.repository == null || it.repository !in repositories }
.groupBy { ModuleId(it.id.group, it.id.module) }
.mapValues { (_, deps) ->
val byVersion = deps.groupBy { it.id }
.mapValues { (componentId, deps) ->
val dep = MergedDependency(
id = componentId,
repositories = deps.mapNotNull { repositories[it.repository] }
repositories = deps.mapNotNull { repositories[it.repository] }.distinct()
)
val component = verificationComponents[componentId]
?: verifyComponentFilesInCache(config, componentId)
@@ -93,7 +90,7 @@ fun processDependencies(config: Config): Env {
maybeDownloadMavenPom(config.logger, component, dep.repositories, gradleModule)
}
val ivyArtifact = ivyCache.getOrPut(componentId) {
maybeDownloadIvyDescriptor(config.logger, component, dep.repositories, gradleModule)
maybeDownloadIvyDescriptor(config.logger, component, dep.repositories)
}
val files = buildMap {
@@ -104,7 +101,7 @@ fun processDependencies(config: Config): Env {
artifact.name,
ArtifactFile(
urls = dep.repositories.flatMap { repo ->
artifactUrls(componentId, artifact.name, repo, gradleModule)
artifactUrls(config.logger, componentId, artifact.name, repo, gradleModule)
}.distinct(),
hash = artifact.checksums.first().toSri()
)
@@ -114,8 +111,9 @@ fun processDependencies(config: Config): Env {
ArtifactSet(files)
}
.mapKeys { Version(it.key.version) }
.toSortedMap(Version.Comparator.reversed())
Module(versions)
Module(byVersion)
}
.toSortedMap(compareBy(ModuleId::toString))
}
@@ -134,9 +132,9 @@ private fun readDependencyGraph(config: Config): List<ResolvedConfiguration> {
private fun verifyComponentFilesInCache(
config: Config,
id: ModuleVersionId,
id: DependencyCoordinates,
): Component? {
val cacheDir = with(id) { config.gradleHome.resolve("caches/modules-2/files-2.1/$group/$name/$version") }
val cacheDir = with(id) { config.gradleHome.resolve("caches/modules-2/files-2.1/$group/$module/$version") }
if (!cacheDir.exists()) {
return null
}
@@ -149,17 +147,17 @@ private fun verifyComponentFilesInCache(
private fun verifyComponentFilesInTestRepository(
config: Config,
id: ModuleVersionId
id: DependencyCoordinates
): Component? {
if (m2 == null) return null
val dir = with(id) {
File(URI.create(m2)).resolve("${group.replace(".", "/")}/$name/$version")
File(URI.create(m2)).resolve("${group.replace(".", "/")}/$module/$version")
}
if (!dir.exists()) {
config.logger.log("$id: not found in m2 repository; tried $dir")
return null
}
val verifications = dir.walk().filter { it.isFile && it.name.startsWith(id.name) }.map { f ->
val verifications = dir.walk().filter { it.isFile && it.name.startsWith(id.module) }.map { f ->
ArtifactMetadata(
f.name,
sha256 = Sha256(f.sha256())
@@ -175,7 +173,7 @@ private fun maybeDownloadGradleModule(
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" }
val filename = with(component.id) { "$module-$version.module" }
return maybeDownloadArtifact(logger, component.id, filename, repos)?.let { artifact ->
try {
ArtifactDownload(
@@ -199,12 +197,12 @@ private fun maybeDownloadMavenPom(
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" }
val filename = with(component.id) { "$module-$version.pom" }
return maybeDownloadArtifact(logger, component.id, filename, pomRepos)?.let { artifact ->
filename to ArtifactFile(
urls = pomRepos.flatMap { repo ->
artifactUrls(component.id, filename, repo, gradleModule)
artifactUrls(logger, component.id, filename, repo, gradleModule)
}.distinct(),
hash = artifact.hash.toSri()
)
@@ -215,28 +213,52 @@ 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()
)
val urls = ivyRepos
.flatMap { repo ->
val attributes = attributes(component.id, repo)
repo.metadataResources.mapNotNull { fill(it, attributes).takeIf(::isUrlComplete) }
}
.filter { url ->
component.artifacts.none { url.substringAfterLast('/') == it.name }
}
var artifact: ArtifactDownload<String>? = null
for (url in urls) {
try {
val source = HashingSource.sha256(URL(url).openStream().source())
val text = source.buffer().readUtf8()
val hash = source.hash
artifact = ArtifactDownload(text, url, Sha256(hash.hex()))
break
} catch (e: IOException) {
// Pass
}
}
if (artifact == null) {
logger.debug("ivy descriptor not found in urls: $urls")
return null
}
return artifact.artifact to ArtifactFile(
urls = urls,
hash = artifact.hash.toSri()
)
}
private fun maybeDownloadArtifact(
logger: Logger,
id: ModuleVersionId,
id: DependencyCoordinates,
filename: String,
repos: List<Repository>
): ArtifactDownload<String>? {
val urls = repos.flatMap { artifactUrls(id, filename, it, null)}
val urls = repos.flatMap { artifactUrls(logger, id, filename, it, null)}
logger.debug("artifact $filename: $urls")
for (url in urls) {
try {
@@ -270,10 +292,11 @@ private fun Checksum.toSri(): String {
}
private fun artifactUrls(
id: ModuleVersionId,
logger: Logger,
id: DependencyCoordinates,
filename: String,
repository: Repository,
module: GradleModule?
module: GradleModule?,
): List<String> {
val groupAsPath = id.group.replace(".", "/")
@@ -286,8 +309,8 @@ private fun artifactUrls(
val attributes = mutableMapOf(
"organisation" to if (repository.m2Compatible) groupAsPath else id.group,
"module" to id.name,
"revision" to id.version.toString(),
"module" to id.module,
"revision" to id.version,
) + fileAttributes(repoFilename, id.version)
val resources = when (attributes["ext"]) {
@@ -299,7 +322,7 @@ private fun artifactUrls(
repository.artifactResources
}
else -> repository.artifactResources
}
}.map { it.replaceFirst("-[revision]", "-${id.artifactVersion}") }
val urls = mutableListOf<String>()
@@ -309,10 +332,12 @@ private fun artifactUrls(
}
if (location.none { it == '[' || it == ']' }) {
urls.add(location)
} else {
logger.warn("failed to construct artifact URL: $location")
}
}
return urls
return urls.distinct()
}
private val optionalRegex = Regex("\\(([^)]+)\\)")
@@ -328,8 +353,16 @@ private fun fill(template: String, attributes: Map<String, String>): String {
}
}
private fun isUrlComplete(url: String): Boolean = !url.contains("[")
private fun attributes(id: DependencyCoordinates, repository: Repository): Map<String, String> = buildMap {
put("organisation", if (repository.m2Compatible) id.group.replace(".", "/") else id.group)
put("module", id.module)
put("revision", id.version)
}
// Gradle persists artifacts with the Maven artifact pattern, which may not match the repository's pattern.
private fun fileAttributes(file: String, version: Version): Map<String, String> {
private fun fileAttributes(file: String, version: String): Map<String, String> {
val parts = Regex("(.+)-$version(-([^.]+))?(\\.(.+))?").matchEntire(file) ?: return emptyMap()
val (artifact, _, classifier, _, ext) = parts.destructured
@@ -342,7 +375,7 @@ private fun fileAttributes(file: String, version: Version): Map<String, String>
}
private data class MergedDependency(
val id: ModuleVersionId,
val id: DependencyCoordinates,
val repositories: List<Repository>
)

View File

@@ -1,6 +1,5 @@
package org.nixos.gradle2nix.env
import java.util.concurrent.ConcurrentHashMap
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
@@ -9,8 +8,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
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
import org.nixos.gradle2nix.model.Version
typealias Env = Map<ModuleId, Module>
@@ -68,204 +66,3 @@ 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 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> {
private val base: Version
val numericParts: List<Long?>
init {
this.base = base ?: this
this.numericParts = parts.map(Longs::tryParse)
}
override fun compareTo(other: Version): Int = compare(this, other)
override fun toString(): String = source
override fun equals(other: Any?): Boolean = when {
other === this -> true
other == null || other !is Version -> false
else -> source == other.source
}
override fun hashCode(): Int = source.hashCode()
object Comparator : kotlin.Comparator<Version> {
override fun compare(o1: Version, o2: Version): Int =
Version.compare(o1, o2)
}
internal object Serializer : KSerializer<Version> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
Version::class.qualifiedName!!,
PrimitiveKind.STRING
)
override fun serialize(encoder: Encoder, value: Version) {
encoder.encodeString(value.source)
}
override fun deserialize(decoder: Decoder): Version {
return Version(decoder.decodeString())
}
}
companion object {
private val SPECIAL_MEANINGS: Map<String, Int> = ImmutableMap.builderWithExpectedSize<String, Int>(7)
.put("dev", -1)
.put("rc", 1)
.put("snapshot", 2)
.put("final", 3).put("ga", 4).put("release", 5)
.put("sp", 6).build()
private val cache = ConcurrentHashMap<String, Version>()
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser
operator fun invoke(original: String): Version = cache.getOrPut(original) {
val parts = mutableListOf<String>()
var digit = false
var startPart = 0
var pos = 0
var endBase = 0
var endBaseStr = 0
while (pos < original.length) {
val ch = original[pos]
if (ch == '.' || ch == '_' || ch == '-' || ch == '+') {
parts.add(original.substring(startPart, pos))
startPart = pos + 1
digit = false
if (ch != '.' && endBaseStr == 0) {
endBase = parts.size
endBaseStr = pos
}
} else if (ch in '0'..'9') {
if (!digit && pos > startPart) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = true
} else {
if (digit) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = false
}
pos++
}
if (pos > startPart) {
parts.add(original.substring(startPart, pos))
}
var base: Version? = null
if (endBaseStr > 0) {
base = Version(original.substring(0, endBaseStr), parts.subList(0, endBase), null)
}
Version(original, parts, base)
}
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.StaticVersionComparator
private fun compare(version1: Version, version2: Version): Int {
if (version1 == version2) {
return 0
}
val parts1 = version1.parts
val parts2 = version2.parts
val numericParts1 = version1.numericParts
val numericParts2 = version2.numericParts
var lastIndex = -1
for (i in 0..<(minOf(parts1.size, parts2.size))) {
lastIndex = i
val part1 = parts1[i]
val part2 = parts2[i]
val numericPart1 = numericParts1[i]
val numericPart2 = numericParts2[i]
when {
part1 == part2 -> continue
numericPart1 != null && numericPart2 == null -> return 1
numericPart2 != null && numericPart1 == null -> return -1
numericPart1 != null && numericPart2 != null -> {
val result = numericPart1.compareTo(numericPart2)
if (result == 0) continue
return result
}
else -> {
// both are strings, we compare them taking into account special meaning
val sm1 = SPECIAL_MEANINGS[part1.lowercase()]
val sm2 = SPECIAL_MEANINGS[part2.lowercase()]
if (sm1 != null) return sm1 - (sm2 ?: 0)
if (sm2 != null) return -sm2
return part1.compareTo(part2)
}
}
}
if (lastIndex < parts1.size) {
return if (numericParts1[lastIndex] == null) -1 else 1
}
if (lastIndex < parts2.size) {
return if (numericParts2[lastIndex] == null) 1 else -1
}
return 0
}
}
}

View File

@@ -9,8 +9,7 @@ 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.env.ModuleVersionId
import org.nixos.gradle2nix.env.Version
import org.nixos.gradle2nix.model.DependencyCoordinates
sealed interface Coordinates {
val group: String?
@@ -104,15 +103,17 @@ data class Artifact(
data class Component(
val group: String,
val name: String,
val version: Version,
val version: String,
val timestamp: String? = null,
val artifacts: List<Artifact> = emptyList(),
) {
val id: ModuleVersionId get() = ModuleVersionId(group, name, version)
val id: DependencyCoordinates get() = DependencyCoordinates(group, name, version, timestamp)
constructor(id: ModuleVersionId, artifacts: List<Artifact>) : this(
constructor(id: DependencyCoordinates, artifacts: List<Artifact>) : this(
id.group,
id.name,
id.module,
id.version,
id.timestamp,
artifacts
)
}

View File

@@ -3,13 +3,13 @@
"-SNAPSHOT": {
"packr--SNAPSHOT.jar": {
"urls": [
"https://jitpack.io/com/github/anuken/packr/-SNAPSHOT/packr--SNAPSHOT.jar"
"https://jitpack.io/com/github/anuken/packr/-SNAPSHOT/packr--packr-1.2-g034efe5-114.jar"
],
"hash": "sha256-XrfVZLc7efr2n3Bz6mOw8DkRI0T8rU8B/MKUMVDl71w="
},
"packr--SNAPSHOT.pom": {
"urls": [
"https://jitpack.io/com/github/anuken/packr/-SNAPSHOT/packr--SNAPSHOT.pom"
"https://jitpack.io/com/github/anuken/packr/-SNAPSHOT/packr--packr-1.2-g034efe5-114.pom"
],
"hash": "sha256-xP28J7blX1IzuJxD4u/wy1ZbwAT5RAajBcpBWs1fAxU="
}

View File

@@ -3,15 +3,15 @@
"5.6.0": {
"jna-5.6.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar"
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar"
],
"hash": "sha256-VVfiNaiqL5dm1dxgnWeUjyqIMsLXls6p7x1svgs7fq8="
},
"jna-5.6.0.pom": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom",
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom"
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom",
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom"
],
"hash": "sha256-X+gbAlWXjyRhbTexBgi3lJil8wc+HZsgONhzaoMfJgg="
}
@@ -21,15 +21,15 @@
"1.0.20200330": {
"trove4j-1.0.20200330.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar"
],
"hash": "sha256-xf1yW/+rUYRr88d9sTg8YKquv+G3/i8A0j/ht98KQ50="
},
"trove4j-1.0.20200330.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom",
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom"
],
"hash": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k="
}
@@ -97,15 +97,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar"
],
"hash": "sha256-Ty5JK8x5XgaA4/h67qGtrp8wbK9SBAuUpvoPiP2skvk="
},
"kotlin-compiler-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom"
],
"hash": "sha256-CwIzMip2MO/eEzUmjkYSPw1tNjg5gg/TfE7Lbv+njjs="
}
@@ -147,15 +147,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar"
],
"hash": "sha256-A+bwJUNSJIlOSe5e2EfLCwtKh540z6uQ1wzakmKnV00="
},
"kotlin-daemon-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom"
],
"hash": "sha256-vB3pwgh7ouTlQQF6i66PQF7IAKGK5MJH6R8rVedh5kk="
}
@@ -371,15 +371,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar"
],
"hash": "sha256-0ZLMLNlDFecijrkTZqNpdmpoIrPOvKwUwR1MSXM2y6Q="
},
"kotlin-scripting-common-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom"
],
"hash": "sha256-2xzYRWGPDLQXOK3H72jZ+NIjZ1sFg+NbsMCEA30AWe4="
}
@@ -389,15 +389,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar"
],
"hash": "sha256-qu9jHwICEl2ZHZgjRxn4ZK1anW40m/DtRGsTd9gXGKE="
},
"kotlin-scripting-compiler-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom"
],
"hash": "sha256-xHXL2+0BepcMD9y46qu1UNc9E6T+a4e3efxM9S148JM="
}
@@ -407,15 +407,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar",
"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"
],
"hash": "sha256-ZOK9uuvzgJSzwh5nCX5Qe4NoTaQTi6h6CwmhMgOXVCg="
},
"kotlin-scripting-compiler-impl-embeddable-1.7.21.pom": {
"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.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom"
],
"hash": "sha256-5c0+HEj+qhC1YVqidOFh5/dcFijcJhZ1ALZ0b4gfweM="
}
@@ -425,15 +425,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar"
],
"hash": "sha256-Uz441a1oFCoFE0HyK8cO113IUGSxk3rPBRN1XMPwSF4="
},
"kotlin-scripting-jvm-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom"
],
"hash": "sha256-cnwtOnluoiOWPu7P7kHvKygsVbZ+V8O0mgFwpMSbfGE="
}

View File

@@ -3,15 +3,15 @@
"5.6.0": {
"jna-5.6.0.jar": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar"
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar",
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.jar"
],
"hash": "sha256-VVfiNaiqL5dm1dxgnWeUjyqIMsLXls6p7x1svgs7fq8="
},
"jna-5.6.0.pom": {
"urls": [
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom",
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom"
"https://repo.maven.apache.org/maven2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom",
"https://plugins.gradle.org/m2/net/java/dev/jna/jna/5.6.0/jna-5.6.0.pom"
],
"hash": "sha256-X+gbAlWXjyRhbTexBgi3lJil8wc+HZsgONhzaoMfJgg="
}
@@ -21,15 +21,15 @@
"1.0.20200330": {
"trove4j-1.0.20200330.jar": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar",
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.jar"
],
"hash": "sha256-xf1yW/+rUYRr88d9sTg8YKquv+G3/i8A0j/ht98KQ50="
},
"trove4j-1.0.20200330.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom",
"https://plugins.gradle.org/m2/org/jetbrains/intellij/deps/trove4j/1.0.20200330/trove4j-1.0.20200330.pom"
],
"hash": "sha256-h3IcuqZaPJfYsbqdIHhA8WTJ/jh1n8nqEP/iZWX40+k="
}
@@ -97,15 +97,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.jar"
],
"hash": "sha256-Ty5JK8x5XgaA4/h67qGtrp8wbK9SBAuUpvoPiP2skvk="
},
"kotlin-compiler-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-compiler-embeddable/1.7.21/kotlin-compiler-embeddable-1.7.21.pom"
],
"hash": "sha256-CwIzMip2MO/eEzUmjkYSPw1tNjg5gg/TfE7Lbv+njjs="
}
@@ -147,15 +147,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.jar"
],
"hash": "sha256-A+bwJUNSJIlOSe5e2EfLCwtKh540z6uQ1wzakmKnV00="
},
"kotlin-daemon-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-daemon-embeddable/1.7.21/kotlin-daemon-embeddable-1.7.21.pom"
],
"hash": "sha256-vB3pwgh7ouTlQQF6i66PQF7IAKGK5MJH6R8rVedh5kk="
}
@@ -371,15 +371,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.jar"
],
"hash": "sha256-0ZLMLNlDFecijrkTZqNpdmpoIrPOvKwUwR1MSXM2y6Q="
},
"kotlin-scripting-common-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-common/1.7.21/kotlin-scripting-common-1.7.21.pom"
],
"hash": "sha256-2xzYRWGPDLQXOK3H72jZ+NIjZ1sFg+NbsMCEA30AWe4="
}
@@ -389,15 +389,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.jar"
],
"hash": "sha256-qu9jHwICEl2ZHZgjRxn4ZK1anW40m/DtRGsTd9gXGKE="
},
"kotlin-scripting-compiler-embeddable-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-embeddable/1.7.21/kotlin-scripting-compiler-embeddable-1.7.21.pom"
],
"hash": "sha256-xHXL2+0BepcMD9y46qu1UNc9E6T+a4e3efxM9S148JM="
}
@@ -407,15 +407,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.jar",
"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"
],
"hash": "sha256-ZOK9uuvzgJSzwh5nCX5Qe4NoTaQTi6h6CwmhMgOXVCg="
},
"kotlin-scripting-compiler-impl-embeddable-1.7.21.pom": {
"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.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-compiler-impl-embeddable/1.7.21/kotlin-scripting-compiler-impl-embeddable-1.7.21.pom"
],
"hash": "sha256-5c0+HEj+qhC1YVqidOFh5/dcFijcJhZ1ALZ0b4gfweM="
}
@@ -425,15 +425,15 @@
"1.7.21": {
"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",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.jar"
],
"hash": "sha256-Uz441a1oFCoFE0HyK8cO113IUGSxk3rPBRN1XMPwSF4="
},
"kotlin-scripting-jvm-1.7.21.pom": {
"urls": [
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom",
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom"
"https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom",
"https://plugins.gradle.org/m2/org/jetbrains/kotlin/kotlin-scripting-jvm/1.7.21/kotlin-scripting-jvm-1.7.21.pom"
],
"hash": "sha256-cnwtOnluoiOWPu7P7kHvKygsVbZ+V8O0mgFwpMSbfGE="
}

View File

@@ -1,26 +1,53 @@
package org.nixos.gradle2nix.model
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable
@Serializable(DependencyCoordinates.Serializer::class)
data class DependencyCoordinates(
val group: String,
val module: String,
val version: String,
val timestamp: String? = null
) {
) : Comparable<DependencyCoordinates> {
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
override fun compareTo(other: DependencyCoordinates): Int = comparator.compare(this, other)
object Serializer : KSerializer<DependencyCoordinates> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
DependencyCoordinates::class.qualifiedName!!,
PrimitiveKind.STRING
)
override fun deserialize(decoder: Decoder): DependencyCoordinates {
val encoded = decoder.decodeString()
return parse(encoded)
}
override fun serialize(encoder: Encoder, value: DependencyCoordinates) {
encoder.encodeString(value.toString())
}
}
companion object {
val comparator = compareBy<DependencyCoordinates> { it.group }
.thenBy { it.module }
.thenByDescending { it.artifactVersion }
fun parse(id: String): DependencyCoordinates {
val parts = id.split(":")
return when (parts.size) {

View File

@@ -13,7 +13,7 @@ data class ResolvedConfiguration(
allDependencies.add(component)
}
fun hasDependency(componentId: String): Boolean {
fun hasDependency(componentId: DependencyCoordinates): Boolean {
return allDependencies.any { it.id == componentId }
}
}

View File

@@ -4,10 +4,9 @@ import kotlinx.serialization.Serializable
@Serializable
data class ResolvedDependency(
val id: String,
val id: DependencyCoordinates,
val source: DependencySource,
val direct: Boolean,
val coordinates: DependencyCoordinates,
val repository: String?,
val dependencies: List<String> = emptyList(),
)

View File

@@ -0,0 +1,172 @@
package org.nixos.gradle2nix.model
import java.util.concurrent.ConcurrentHashMap
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
@Serializable(Version.Serializer::class)
class Version(val source: String, val parts: List<String>, base: Version?) : Comparable<Version> {
private val base: Version
val numericParts: List<Long?>
init {
this.base = base ?: this
this.numericParts = parts.map {
try { it.toLong() } catch (e: NumberFormatException) { null }
}
}
override fun compareTo(other: Version): Int = compare(this, other)
override fun toString(): String = source
override fun equals(other: Any?): Boolean = when {
other === this -> true
other == null || other !is Version -> false
else -> source == other.source
}
override fun hashCode(): Int = source.hashCode()
object Comparator : kotlin.Comparator<Version> {
override fun compare(o1: Version, o2: Version): Int =
Version.compare(o1, o2)
}
internal object Serializer : KSerializer<Version> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor(
Version::class.qualifiedName!!,
PrimitiveKind.STRING
)
override fun serialize(encoder: Encoder, value: Version) {
encoder.encodeString(value.source)
}
override fun deserialize(decoder: Decoder): Version {
return Version(decoder.decodeString())
}
}
companion object {
private val SPECIAL_MEANINGS: Map<String, Int> = mapOf(
"dev" to -1,
"rc" to 1,
"snapshot" to 2,
"final" to 3,
"ga" to 4,
"release" to 5,
"sp" to 6
)
private val cache = ConcurrentHashMap<String, Version>()
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.VersionParser
operator fun invoke(original: String): Version = cache.getOrPut(original) {
val parts = mutableListOf<String>()
var digit = false
var startPart = 0
var pos = 0
var endBase = 0
var endBaseStr = 0
while (pos < original.length) {
val ch = original[pos]
if (ch == '.' || ch == '_' || ch == '-' || ch == '+') {
parts.add(original.substring(startPart, pos))
startPart = pos + 1
digit = false
if (ch != '.' && endBaseStr == 0) {
endBase = parts.size
endBaseStr = pos
}
} else if (ch in '0'..'9') {
if (!digit && pos > startPart) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = true
} else {
if (digit) {
if (endBaseStr == 0) {
endBase = parts.size + 1
endBaseStr = pos
}
parts.add(original.substring(startPart, pos))
startPart = pos
}
digit = false
}
pos++
}
if (pos > startPart) {
parts.add(original.substring(startPart, pos))
}
var base: Version? = null
if (endBaseStr > 0) {
base = Version(original.substring(0, endBaseStr), parts.subList(0, endBase), null)
}
Version(original, parts, base)
}
// From org.gradle.api.internal.artifacts.ivyservice.ivyresolve.strategy.StaticVersionComparator
private fun compare(version1: Version, version2: Version): Int {
if (version1 == version2) {
return 0
}
val parts1 = version1.parts
val parts2 = version2.parts
val numericParts1 = version1.numericParts
val numericParts2 = version2.numericParts
var lastIndex = -1
for (i in 0..<(minOf(parts1.size, parts2.size))) {
lastIndex = i
val part1 = parts1[i]
val part2 = parts2[i]
val numericPart1 = numericParts1[i]
val numericPart2 = numericParts2[i]
when {
part1 == part2 -> continue
numericPart1 != null && numericPart2 == null -> return 1
numericPart2 != null && numericPart1 == null -> return -1
numericPart1 != null && numericPart2 != null -> {
val result = numericPart1.compareTo(numericPart2)
if (result == 0) continue
return result
}
else -> {
// both are strings, we compare them taking into account special meaning
val sm1 = SPECIAL_MEANINGS[part1.lowercase()]
val sm2 = SPECIAL_MEANINGS[part2.lowercase()]
if (sm1 != null) return sm1 - (sm2 ?: 0)
if (sm2 != null) return -sm2
return part1.compareTo(part2)
}
}
}
if (lastIndex < parts1.size) {
return if (numericParts1[lastIndex] == null) -1 else 1
}
if (lastIndex < parts2.size) {
return if (numericParts2[lastIndex] == null) 1 else -1
}
return 0
}
}
}

View File

@@ -205,17 +205,19 @@ abstract class DependencyExtractor :
val resolvedConfiguration = ResolvedConfiguration(source, details.configurationName, repositories)
for (directDependency in getResolvedDependencies(rootComponent)) {
val moduleComponentId = directDependency.id as? ModuleComponentIdentifier ?: continue
val directDep = createComponentNode(
moduleComponentId,
source,
true,
directDependency,
result.getRepositoryId(directDependency)
)
resolvedConfiguration.addDependency(directDep)
val coordinates = (directDependency.id as? ModuleComponentIdentifier)?.let(::coordinates)
if (coordinates != null) {
val directDep = createComponentNode(
coordinates,
source,
true,
directDependency,
result.getRepositoryId(directDependency)
)
resolvedConfiguration.addDependency(directDep)
walkComponentDependencies(result, directDependency, directDep.source, resolvedConfiguration)
walkComponentDependencies(result, directDependency, directDep.source, resolvedConfiguration)
}
}
resolvedConfigurations.add(resolvedConfiguration)
@@ -232,19 +234,17 @@ abstract class DependencyExtractor :
val dependencyComponents = getResolvedDependencies(component)
for (dependencyComponent in dependencyComponents) {
if (!resolvedConfiguration.hasDependency(componentId(dependencyComponent))) {
val moduleComponentId = dependencyComponent.id as? ModuleComponentIdentifier
if (moduleComponentId != null) {
val dependencyNode = createComponentNode(
moduleComponentId,
componentSource,
direct,
dependencyComponent,
result.getRepositoryId(component)
)
resolvedConfiguration.addDependency(dependencyNode)
}
val coordinates = (dependencyComponent.id as? ModuleComponentIdentifier)?.let(::coordinates)
?: continue
if (!resolvedConfiguration.hasDependency(coordinates)) {
val dependencyNode = createComponentNode(
coordinates,
componentSource,
direct,
dependencyComponent,
result.getRepositoryId(component)
)
resolvedConfiguration.addDependency(dependencyNode)
walkComponentDependencies(result, dependencyComponent, componentSource, resolvedConfiguration)
}
}
@@ -271,7 +271,7 @@ abstract class DependencyExtractor :
}
private fun createComponentNode(
componentId: ModuleComponentIdentifier,
coordinates: DependencyCoordinates,
source: DependencySource,
direct: Boolean,
component: ResolvedComponentResult,
@@ -279,12 +279,10 @@ abstract class DependencyExtractor :
): ResolvedDependency {
val componentDependencies =
component.dependencies.filterIsInstance<ResolvedDependencyResult>().map { componentId(it.selected) }
val coordinates = coordinates(componentId)
return ResolvedDependency(
componentId.displayName,
coordinates,
source,
direct,
coordinates,
repositoryId,
componentDependencies,
)
@@ -303,16 +301,6 @@ abstract class DependencyExtractor :
)
}
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()