mirror of
https://github.com/tadfisher/gradle2nix.git
synced 2026-01-11 23:40:37 -05:00
Rewrite plugin, use filenames in lockfile
This commit is contained in:
@@ -2,11 +2,6 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
id("org.jetbrains.kotlin.jvm")
|
||||
id("org.jetbrains.kotlin.plugin.serialization")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.serialization.json)
|
||||
}
|
||||
|
||||
java {
|
||||
|
||||
@@ -1,62 +1,33 @@
|
||||
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
|
||||
import java.io.Serializable
|
||||
|
||||
@Serializable(DependencyCoordinates.Serializer::class)
|
||||
data class DependencyCoordinates(
|
||||
val group: String,
|
||||
val module: String,
|
||||
val version: String,
|
||||
val timestamp: String? = null
|
||||
) : Comparable<DependencyCoordinates> {
|
||||
interface DependencyCoordinates : Serializable {
|
||||
val group: String
|
||||
val artifact: String
|
||||
|
||||
override fun toString(): String = if (timestamp != null) {
|
||||
"$group:$module:$version:$timestamp"
|
||||
/**
|
||||
* For normal dependencies, the dependency version (e.g. "2.0.2").
|
||||
*
|
||||
* For Maven snapshot dependencies, the snapshot version (e.g. "2.0.2-SNAPSHOT").
|
||||
*/
|
||||
val version: String
|
||||
|
||||
/**
|
||||
* For Maven snapshot dependencies, the snapshot timestamp (e.g. "20070310.18163-3").
|
||||
*
|
||||
* For normal dependencies, this is null.
|
||||
*/
|
||||
val timestamp: String?
|
||||
|
||||
val id: String get() = if (timestamp != null) {
|
||||
"$group:$artifact:$version:$timestamp"
|
||||
} else {
|
||||
"$group:$module:$version"
|
||||
"$group:$artifact:$version"
|
||||
}
|
||||
|
||||
val artifactVersion: String get() =
|
||||
timestamp?.let { version.replace("SNAPSHOT", it) } ?: version
|
||||
val timestampedCoordinates: DependencyCoordinates
|
||||
|
||||
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) {
|
||||
3 -> DependencyCoordinates(parts[0], parts[1], parts[2])
|
||||
4 -> DependencyCoordinates(parts[0], parts[1], parts[2], parts[3])
|
||||
else -> throw IllegalStateException(
|
||||
"couldn't parse dependency coordinates: '$id'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
val timestampedVersion: String get() =
|
||||
timestamp?.let { version.replace("-SNAPSHOT", "-$it") } ?: version
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import java.io.Serializable
|
||||
import org.nixos.gradle2nix.model.impl.DefaultRepository
|
||||
|
||||
interface DependencySet : Serializable {
|
||||
val dependencies: List<ResolvedDependency>
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* The source of a dependency declaration, representing where the direct dependency is declared,
|
||||
* or where the parent dependency is declared for transitive dependencies.
|
||||
* In most cases, this will be the project component that declares the dependency,
|
||||
* but may also be a Version Catalog or the build as a whole.
|
||||
* We attempt to map this to an actual source file location when building a dependency report.
|
||||
*/
|
||||
@Serializable
|
||||
data class DependencySource(
|
||||
val targetType: ConfigurationTarget,
|
||||
val targetPath: String,
|
||||
val buildPath: String,
|
||||
)
|
||||
|
||||
@Serializable
|
||||
enum class ConfigurationTarget {
|
||||
@SerialName("gradle") GRADLE,
|
||||
@SerialName("settings") SETTINGS,
|
||||
@SerialName("buildscript") BUILDSCRIPT,
|
||||
@SerialName("project") PROJECT,
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
const val PARAM_INCLUDE_PROJECTS = "NIX_INCLUDE_PROJECTS"
|
||||
const val PARAM_INCLUDE_CONFIGURATIONS = "NIX_INCLUDE_CONFIGURATIONS"
|
||||
const val PARAM_REPORT_DIR = "NIX_REPORT_DIR"
|
||||
const val RESOLVE_PROJECT_TASK = "resolveProjectDependencies"
|
||||
const val RESOLVE_ALL_TASK = "resolveAllDependencies"
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.io.Serializable
|
||||
|
||||
interface Repository : Serializable {
|
||||
val id: String
|
||||
val type: Type
|
||||
val metadataSources: List<String>
|
||||
val metadataResources: List<String>
|
||||
val artifactResources: List<String>
|
||||
|
||||
@Serializable
|
||||
data class Repository(
|
||||
val id: String,
|
||||
val type: Type,
|
||||
val name: String,
|
||||
val m2Compatible: Boolean,
|
||||
val metadataSources: List<String>,
|
||||
val metadataResources: List<String>,
|
||||
val artifactResources: List<String>,
|
||||
) {
|
||||
enum class Type {
|
||||
MAVEN,
|
||||
IVY,
|
||||
FLAT_DIR
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ResolvedArtifact(
|
||||
val type: Type?,
|
||||
val file: String,
|
||||
) {
|
||||
enum class Type {
|
||||
SOURCES,
|
||||
JAVADOC,
|
||||
IVY_DESCRIPTOR,
|
||||
MAVEN_POM,
|
||||
}
|
||||
interface ResolvedArtifact : Serializable {
|
||||
val name: String
|
||||
val filename: String
|
||||
val urls: List<String>
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ResolvedConfiguration(
|
||||
val rootSource: DependencySource,
|
||||
val configurationName: String,
|
||||
val repositories: List<Repository> = emptyList(),
|
||||
val allDependencies: MutableList<ResolvedDependency> = mutableListOf()
|
||||
) {
|
||||
fun addDependency(component: ResolvedDependency) {
|
||||
allDependencies.add(component)
|
||||
}
|
||||
|
||||
fun hasDependency(componentId: DependencyCoordinates): Boolean {
|
||||
return allDependencies.any { it.id == componentId }
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,8 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import java.io.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ResolvedDependency(
|
||||
val id: DependencyCoordinates,
|
||||
val source: DependencySource,
|
||||
val direct: Boolean,
|
||||
val repository: String?,
|
||||
val dependencies: List<String> = emptyList(),
|
||||
)
|
||||
interface ResolvedDependency : Serializable {
|
||||
val coordinates: DependencyCoordinates
|
||||
val artifacts: List<ResolvedArtifact>
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.nixos.gradle2nix.model
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@Serializable
|
||||
data class ResolvedMetadata(
|
||||
val moduleId: String,
|
||||
val uri: String
|
||||
)
|
||||
@@ -1,172 +0,0 @@
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.nixos.gradle2nix.model.impl
|
||||
|
||||
import org.nixos.gradle2nix.model.DependencyCoordinates
|
||||
|
||||
data class DefaultDependencyCoordinates(
|
||||
override val group: String,
|
||||
override val artifact: String,
|
||||
override val version: String,
|
||||
override val timestamp: String? = null
|
||||
) : DependencyCoordinates {
|
||||
|
||||
override val timestampedCoordinates: DependencyCoordinates
|
||||
get() = DefaultDependencyCoordinates(group, artifact, timestampedVersion)
|
||||
|
||||
override fun toString(): String = id
|
||||
|
||||
companion object {
|
||||
fun parse(id: String): DependencyCoordinates {
|
||||
val parts = id.split(":")
|
||||
return when (parts.size) {
|
||||
3 -> DefaultDependencyCoordinates(parts[0], parts[1], parts[2])
|
||||
4 -> DefaultDependencyCoordinates(parts[0], parts[1], parts[2], parts[3])
|
||||
else -> throw IllegalStateException(
|
||||
"couldn't parse dependency coordinates: '$id'"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.nixos.gradle2nix.model.impl
|
||||
|
||||
import org.nixos.gradle2nix.model.DependencySet
|
||||
import org.nixos.gradle2nix.model.ResolvedDependency
|
||||
|
||||
data class DefaultDependencySet(
|
||||
override val dependencies: List<ResolvedDependency>
|
||||
) : DependencySet
|
||||
@@ -0,0 +1,11 @@
|
||||
package org.nixos.gradle2nix.model.impl
|
||||
|
||||
import org.nixos.gradle2nix.model.Repository
|
||||
|
||||
data class DefaultRepository(
|
||||
override val id: String,
|
||||
override val type: Repository.Type,
|
||||
override val metadataSources: List<String>,
|
||||
override val metadataResources: List<String>,
|
||||
override val artifactResources: List<String>,
|
||||
) : Repository
|
||||
@@ -0,0 +1,9 @@
|
||||
package org.nixos.gradle2nix.model.impl
|
||||
|
||||
import org.nixos.gradle2nix.model.ResolvedArtifact
|
||||
|
||||
data class DefaultResolvedArtifact(
|
||||
override val name: String,
|
||||
override val filename: String,
|
||||
override val urls: List<String>
|
||||
) : ResolvedArtifact
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.nixos.gradle2nix.model.impl
|
||||
|
||||
import org.nixos.gradle2nix.model.DependencyCoordinates
|
||||
import org.nixos.gradle2nix.model.ResolvedArtifact
|
||||
import org.nixos.gradle2nix.model.ResolvedDependency
|
||||
|
||||
data class DefaultResolvedDependency(
|
||||
override val coordinates: DependencyCoordinates,
|
||||
override val artifacts: List<ResolvedArtifact>,
|
||||
) : ResolvedDependency
|
||||
Reference in New Issue
Block a user