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.Env
import org.nixos.gradle2nix.env.Module import org.nixos.gradle2nix.env.Module
import org.nixos.gradle2nix.env.ModuleId 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.Checksum
import org.nixos.gradle2nix.metadata.Component import org.nixos.gradle2nix.metadata.Component
import org.nixos.gradle2nix.metadata.Md5 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.Sha512
import org.nixos.gradle2nix.metadata.VerificationMetadata import org.nixos.gradle2nix.metadata.VerificationMetadata
import org.nixos.gradle2nix.metadata.parseVerificationMetadata 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.GradleModule
import org.nixos.gradle2nix.module.Variant import org.nixos.gradle2nix.module.Variant
@@ -44,12 +44,10 @@ private fun shouldSkipRepository(repository: Repository): Boolean {
fun processDependencies(config: Config): Env { fun processDependencies(config: Config): Env {
val verificationMetadata = readVerificationMetadata(config) val verificationMetadata = readVerificationMetadata(config)
val verificationComponents = verificationMetadata?.components?.associateBy { val verificationComponents = verificationMetadata?.components?.associateBy { it.id } ?: emptyMap()
ModuleVersionId(ModuleId(it.group, it.name), it.version) val moduleCache = mutableMapOf<DependencyCoordinates, GradleModule?>()
} ?: emptyMap() val pomCache = mutableMapOf<DependencyCoordinates, Pair<String, ArtifactFile>?>()
val moduleCache = mutableMapOf<ModuleVersionId, GradleModule?>() val ivyCache = mutableMapOf<DependencyCoordinates, Pair<String, ArtifactFile>?>()
val pomCache = mutableMapOf<ModuleVersionId, Pair<String, ArtifactFile>?>()
val ivyCache = mutableMapOf<ModuleVersionId, Pair<String, ArtifactFile>?>()
val configurations = readDependencyGraph(config) val configurations = readDependencyGraph(config)
val repositories = configurations val repositories = configurations
@@ -71,15 +69,14 @@ fun processDependencies(config: Config): Env {
return configurations.asSequence() return configurations.asSequence()
.flatMap { it.allDependencies.asSequence() } .flatMap { it.allDependencies.asSequence() }
.filterNot { it.id.startsWith("project ") || it.repository == null || it.repository !in repositories } .filterNot { it.repository == null || it.repository !in repositories }
.groupBy { ModuleId(it.coordinates.group, it.coordinates.module) } .groupBy { ModuleId(it.id.group, it.id.module) }
.mapValues { (id, deps) -> .mapValues { (_, deps) ->
val versions = deps.groupBy { Version(it.coordinates.version) } val byVersion = deps.groupBy { it.id }
.mapValues { (version, deps) -> .mapValues { (componentId, deps) ->
val componentId = ModuleVersionId(id, version)
val dep = MergedDependency( val dep = MergedDependency(
id = componentId, id = componentId,
repositories = deps.mapNotNull { repositories[it.repository] } repositories = deps.mapNotNull { repositories[it.repository] }.distinct()
) )
val component = verificationComponents[componentId] val component = verificationComponents[componentId]
?: verifyComponentFilesInCache(config, componentId) ?: verifyComponentFilesInCache(config, componentId)
@@ -93,7 +90,7 @@ fun processDependencies(config: Config): Env {
maybeDownloadMavenPom(config.logger, component, dep.repositories, gradleModule) maybeDownloadMavenPom(config.logger, component, dep.repositories, gradleModule)
} }
val ivyArtifact = ivyCache.getOrPut(componentId) { val ivyArtifact = ivyCache.getOrPut(componentId) {
maybeDownloadIvyDescriptor(config.logger, component, dep.repositories, gradleModule) maybeDownloadIvyDescriptor(config.logger, component, dep.repositories)
} }
val files = buildMap { val files = buildMap {
@@ -104,7 +101,7 @@ fun processDependencies(config: Config): Env {
artifact.name, artifact.name,
ArtifactFile( ArtifactFile(
urls = dep.repositories.flatMap { repo -> urls = dep.repositories.flatMap { repo ->
artifactUrls(componentId, artifact.name, repo, gradleModule) artifactUrls(config.logger, componentId, artifact.name, repo, gradleModule)
}.distinct(), }.distinct(),
hash = artifact.checksums.first().toSri() hash = artifact.checksums.first().toSri()
) )
@@ -114,8 +111,9 @@ fun processDependencies(config: Config): Env {
ArtifactSet(files) ArtifactSet(files)
} }
.mapKeys { Version(it.key.version) }
.toSortedMap(Version.Comparator.reversed()) .toSortedMap(Version.Comparator.reversed())
Module(versions) Module(byVersion)
} }
.toSortedMap(compareBy(ModuleId::toString)) .toSortedMap(compareBy(ModuleId::toString))
} }
@@ -134,9 +132,9 @@ private fun readDependencyGraph(config: Config): List<ResolvedConfiguration> {
private fun verifyComponentFilesInCache( private fun verifyComponentFilesInCache(
config: Config, config: Config,
id: ModuleVersionId, id: DependencyCoordinates,
): Component? { ): 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()) { if (!cacheDir.exists()) {
return null return null
} }
@@ -149,17 +147,17 @@ private fun verifyComponentFilesInCache(
private fun verifyComponentFilesInTestRepository( private fun verifyComponentFilesInTestRepository(
config: Config, config: Config,
id: ModuleVersionId id: DependencyCoordinates
): Component? { ): Component? {
if (m2 == null) return null if (m2 == null) return null
val dir = with(id) { 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()) { if (!dir.exists()) {
config.logger.log("$id: not found in m2 repository; tried $dir") config.logger.log("$id: not found in m2 repository; tried $dir")
return null 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( ArtifactMetadata(
f.name, f.name,
sha256 = Sha256(f.sha256()) sha256 = Sha256(f.sha256())
@@ -175,7 +173,7 @@ private fun maybeDownloadGradleModule(
repos: List<Repository> repos: List<Repository>
): ArtifactDownload<Pair<String, GradleModule>>? { ): ArtifactDownload<Pair<String, GradleModule>>? {
if (component.artifacts.none { it.name.endsWith(".module") }) return null 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 -> return maybeDownloadArtifact(logger, component.id, filename, repos)?.let { artifact ->
try { try {
ArtifactDownload( ArtifactDownload(
@@ -199,12 +197,12 @@ private fun maybeDownloadMavenPom(
if (component.artifacts.any { it.name.endsWith(".pom") }) return null if (component.artifacts.any { it.name.endsWith(".pom") }) return null
val pomRepos = repos.filter { "mavenPom" in it.metadataSources } val pomRepos = repos.filter { "mavenPom" in it.metadataSources }
if (pomRepos.isEmpty()) return null 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 -> return maybeDownloadArtifact(logger, component.id, filename, pomRepos)?.let { artifact ->
filename to ArtifactFile( filename to ArtifactFile(
urls = pomRepos.flatMap { repo -> urls = pomRepos.flatMap { repo ->
artifactUrls(component.id, filename, repo, gradleModule) artifactUrls(logger, component.id, filename, repo, gradleModule)
}.distinct(), }.distinct(),
hash = artifact.hash.toSri() hash = artifact.hash.toSri()
) )
@@ -215,28 +213,52 @@ private fun maybeDownloadIvyDescriptor(
logger: Logger, logger: Logger,
component: Component, component: Component,
repos: List<Repository>, repos: List<Repository>,
gradleModule: GradleModule?
): Pair<String, ArtifactFile>? { ): Pair<String, ArtifactFile>? {
if (component.artifacts.any { it.name == "ivy.xml" }) return null
val ivyRepos = repos.filter { "ivyDescriptor" in it.metadataSources } val ivyRepos = repos.filter { "ivyDescriptor" in it.metadataSources }
if (ivyRepos.isEmpty()) return null if (ivyRepos.isEmpty()) return null
return maybeDownloadArtifact(logger, component.id, "ivy.xml", ivyRepos)?.let { artifact ->
"ivy.xml" to ArtifactFile( val urls = ivyRepos
urls = ivyRepos.flatMap { repo -> .flatMap { repo ->
artifactUrls(component.id, "ivy.xml", repo, gradleModule) val attributes = attributes(component.id, repo)
}.distinct(), 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() hash = artifact.hash.toSri()
) )
} }
}
private fun maybeDownloadArtifact( private fun maybeDownloadArtifact(
logger: Logger, logger: Logger,
id: ModuleVersionId, id: DependencyCoordinates,
filename: String, filename: String,
repos: List<Repository> repos: List<Repository>
): ArtifactDownload<String>? { ): 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) { for (url in urls) {
try { try {
@@ -270,10 +292,11 @@ private fun Checksum.toSri(): String {
} }
private fun artifactUrls( private fun artifactUrls(
id: ModuleVersionId, logger: Logger,
id: DependencyCoordinates,
filename: String, filename: String,
repository: Repository, repository: Repository,
module: GradleModule? module: GradleModule?,
): List<String> { ): List<String> {
val groupAsPath = id.group.replace(".", "/") val groupAsPath = id.group.replace(".", "/")
@@ -286,8 +309,8 @@ private fun artifactUrls(
val attributes = mutableMapOf( val attributes = mutableMapOf(
"organisation" to if (repository.m2Compatible) groupAsPath else id.group, "organisation" to if (repository.m2Compatible) groupAsPath else id.group,
"module" to id.name, "module" to id.module,
"revision" to id.version.toString(), "revision" to id.version,
) + fileAttributes(repoFilename, id.version) ) + fileAttributes(repoFilename, id.version)
val resources = when (attributes["ext"]) { val resources = when (attributes["ext"]) {
@@ -299,7 +322,7 @@ private fun artifactUrls(
repository.artifactResources repository.artifactResources
} }
else -> repository.artifactResources else -> repository.artifactResources
} }.map { it.replaceFirst("-[revision]", "-${id.artifactVersion}") }
val urls = mutableListOf<String>() val urls = mutableListOf<String>()
@@ -309,10 +332,12 @@ private fun artifactUrls(
} }
if (location.none { it == '[' || it == ']' }) { if (location.none { it == '[' || it == ']' }) {
urls.add(location) urls.add(location)
} else {
logger.warn("failed to construct artifact URL: $location")
} }
} }
return urls return urls.distinct()
} }
private val optionalRegex = Regex("\\(([^)]+)\\)") 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. // 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 parts = Regex("(.+)-$version(-([^.]+))?(\\.(.+))?").matchEntire(file) ?: return emptyMap()
val (artifact, _, classifier, _, ext) = parts.destructured val (artifact, _, classifier, _, ext) = parts.destructured
@@ -342,7 +375,7 @@ private fun fileAttributes(file: String, version: Version): Map<String, String>
} }
private data class MergedDependency( private data class MergedDependency(
val id: ModuleVersionId, val id: DependencyCoordinates,
val repositories: List<Repository> val repositories: List<Repository>
) )

View File

@@ -1,6 +1,5 @@
package org.nixos.gradle2nix.env package org.nixos.gradle2nix.env
import java.util.concurrent.ConcurrentHashMap
import kotlinx.serialization.KSerializer import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException import kotlinx.serialization.SerializationException
@@ -9,8 +8,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder import kotlinx.serialization.encoding.Encoder
import org.gradle.internal.impldep.com.google.common.collect.ImmutableMap import org.nixos.gradle2nix.model.Version
import org.gradle.internal.impldep.com.google.common.primitives.Longs
typealias Env = Map<ModuleId, Module> 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.serialization.XmlSerialName
import nl.adaptivity.xmlutil.xmlStreaming import nl.adaptivity.xmlutil.xmlStreaming
import org.nixos.gradle2nix.Logger import org.nixos.gradle2nix.Logger
import org.nixos.gradle2nix.env.ModuleVersionId import org.nixos.gradle2nix.model.DependencyCoordinates
import org.nixos.gradle2nix.env.Version
sealed interface Coordinates { sealed interface Coordinates {
val group: String? val group: String?
@@ -104,15 +103,17 @@ data class Artifact(
data class Component( data class Component(
val group: String, val group: String,
val name: String, val name: String,
val version: Version, val version: String,
val timestamp: String? = null,
val artifacts: List<Artifact> = emptyList(), 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.group,
id.name, id.module,
id.version, id.version,
id.timestamp,
artifacts artifacts
) )
} }

View File

@@ -3,13 +3,13 @@
"-SNAPSHOT": { "-SNAPSHOT": {
"packr--SNAPSHOT.jar": { "packr--SNAPSHOT.jar": {
"urls": [ "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=" "hash": "sha256-XrfVZLc7efr2n3Bz6mOw8DkRI0T8rU8B/MKUMVDl71w="
}, },
"packr--SNAPSHOT.pom": { "packr--SNAPSHOT.pom": {
"urls": [ "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=" "hash": "sha256-xP28J7blX1IzuJxD4u/wy1ZbwAT5RAajBcpBWs1fAxU="
} }

View File

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

View File

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

View File

@@ -1,26 +1,53 @@
package org.nixos.gradle2nix.model package org.nixos.gradle2nix.model
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable 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( data class DependencyCoordinates(
val group: String, val group: String,
val module: String, val module: String,
val version: String, val version: String,
val timestamp: String? = null val timestamp: String? = null
) { ) : Comparable<DependencyCoordinates> {
override fun toString(): String = if (timestamp != null) { override fun toString(): String = if (timestamp != null) {
"$group:$module:$version:$timestamp" "$group:$module:$version:$timestamp"
} else { } else {
"$group:$module:$version" "$group:$module:$version"
} }
val isSnapshot: Boolean get() = timestamp != null
val moduleVersion: String get() = version
val artifactVersion: String get() = val artifactVersion: String get() =
timestamp?.let { version.replace("SNAPSHOT", it) } ?: version 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 { companion object {
val comparator = compareBy<DependencyCoordinates> { it.group }
.thenBy { it.module }
.thenByDescending { it.artifactVersion }
fun parse(id: String): DependencyCoordinates { fun parse(id: String): DependencyCoordinates {
val parts = id.split(":") val parts = id.split(":")
return when (parts.size) { return when (parts.size) {

View File

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

View File

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