mirror of
https://github.com/tadfisher/gradle2nix.git
synced 2026-01-11 23:40:37 -05:00
Update build; improve caching; improve tests
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
import dev.minutest.Tests
|
||||
import dev.minutest.experimental.minus
|
||||
import dev.minutest.junit.JUnit5Minutests
|
||||
import dev.minutest.rootContext
|
||||
import org.gradle.api.internal.artifacts.dsl.DefaultRepositoryHandler.BINTRAY_JCENTER_URL
|
||||
@@ -18,7 +19,7 @@ import strikt.assertions.startsWith
|
||||
|
||||
class BasicTest : JUnit5Minutests {
|
||||
@Tests
|
||||
fun tests() = rootContext<Fixture>("basic tests") {
|
||||
fun tests() = rootContext("basic tests") {
|
||||
withFixture("basic/basic-java-project") {
|
||||
test("builds basic java project") {
|
||||
expectThat(build()) {
|
||||
@@ -57,12 +58,13 @@ class BasicTest : JUnit5Minutests {
|
||||
}
|
||||
|
||||
withFixture("basic/basic-kotlin-project") {
|
||||
test("excludes embedded kotlin repo") {
|
||||
GRADLE_MIN("4.9") - test("excludes embedded kotlin repo") {
|
||||
|
||||
expectThat(build()) {
|
||||
get("all dependencies") {
|
||||
pluginDependencies +
|
||||
rootProject.buildscriptDependencies +
|
||||
rootProject.projectDependencies
|
||||
rootProject.buildscriptDependencies +
|
||||
rootProject.projectDependencies
|
||||
}.flatMap { it.urls }.all { not { startsWith("file:") } }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +1,99 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
import dev.minutest.Tests
|
||||
import dev.minutest.experimental.minus
|
||||
import dev.minutest.junit.JUnit5Minutests
|
||||
import dev.minutest.rootContext
|
||||
import strikt.api.expectThat
|
||||
import strikt.assertions.all
|
||||
import strikt.assertions.contains
|
||||
import strikt.assertions.containsExactly
|
||||
import strikt.assertions.filter
|
||||
import strikt.assertions.isEqualTo
|
||||
import strikt.assertions.isNotEqualTo
|
||||
import strikt.assertions.isNotNull
|
||||
import strikt.assertions.single
|
||||
import strikt.assertions.startsWith
|
||||
import strikt.assertions.isNull
|
||||
|
||||
class DependencyTest : JUnit5Minutests {
|
||||
@Tests
|
||||
fun tests() = rootContext<Fixture>("dependency tests") {
|
||||
fun tests() = rootContext("dependency tests") {
|
||||
|
||||
withFixture("dependency/classifier") {
|
||||
test("resolves dependency with classifier") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }.ids.containsExactly(
|
||||
"com.badlogicgames.gdx:gdx-parent:1.9.9@pom",
|
||||
"com.badlogicgames.gdx:gdx-platform:1.9.9:natives-desktop@jar",
|
||||
"com.badlogicgames.gdx:gdx-platform:1.9.9@pom",
|
||||
"org.sonatype.oss:oss-parent:5@pom"
|
||||
)
|
||||
withRepository("m2") {
|
||||
|
||||
withFixture("dependency/classifier") {
|
||||
test("resolves dependency with classifier") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }.ids.containsExactly(
|
||||
"com.badlogicgames.gdx:gdx-parent:1.9.9@pom",
|
||||
"com.badlogicgames.gdx:gdx-platform:1.9.9:natives-desktop@jar",
|
||||
"com.badlogicgames.gdx:gdx-platform:1.9.9@pom",
|
||||
"org.sonatype.oss:oss-parent:5@pom"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withFixture("dependency/dynamic-snapshot") {
|
||||
test("resolves snapshot dependency with dynamic version") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.filter { it.id.name == "packr" }
|
||||
.all {
|
||||
get("id.version") { id.version }.isEqualTo("-SNAPSHOT")
|
||||
get("timestamp") { timestamp }.isNotNull()
|
||||
get("build") { build }.isNotNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withFixture("dependency/snapshot") {
|
||||
test("resolves snapshot dependency") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.filter { it.id.name == "okio" }
|
||||
.and {
|
||||
ids.containsExactly(
|
||||
"com.squareup.okio:okio:2.5.0-SNAPSHOT@jar",
|
||||
"com.squareup.okio:okio:2.5.0-SNAPSHOT@module",
|
||||
"com.squareup.okio:okio:2.5.0-SNAPSHOT@pom"
|
||||
withFixture("dependency/maven-bom") {
|
||||
GRADLE_MIN("5.0") - test("resolves dependencies from maven bom platform") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.ids
|
||||
.containsExactly(
|
||||
"io.micrometer:micrometer-bom:1.5.1@pom",
|
||||
"io.micrometer:micrometer-core:1.5.1@jar",
|
||||
"io.micrometer:micrometer-core:1.5.1@pom",
|
||||
"org.hdrhistogram:HdrHistogram:2.1.12@jar",
|
||||
"org.hdrhistogram:HdrHistogram:2.1.12@pom"
|
||||
)
|
||||
all {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withFixture("dependency/snapshot") {
|
||||
test("resolves snapshot dependency") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.and {
|
||||
ids.containsExactly(
|
||||
"org.apache:test-SNAPSHOT2:2.0.2-SNAPSHOT@jar",
|
||||
"org.apache:test-SNAPSHOT2:2.0.2-SNAPSHOT@pom"
|
||||
)
|
||||
all {
|
||||
get("timestamp") { timestamp }.isNull()
|
||||
get("build") { build }.isNotNull()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withFixture("dependency/snapshot-dynamic") {
|
||||
test("resolves snapshot dependency with dynamic version") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.and {
|
||||
ids.containsExactly(
|
||||
"org.apache:test-SNAPSHOT1:2.0.2-SNAPSHOT@jar",
|
||||
"org.apache:test-SNAPSHOT1:2.0.2-SNAPSHOT@pom"
|
||||
)
|
||||
all {
|
||||
get("timestamp") { timestamp }.isEqualTo("20070310.181613")
|
||||
get("build") { build }.isEqualTo(3)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
withFixture("dependency/snapshot-redirect") {
|
||||
test("resolves snapshot dependency with redirect") {
|
||||
expectThat(build()) {
|
||||
get("root project dependencies") { rootProject.projectDependencies }
|
||||
.filter { it.id.name == "packr" }
|
||||
.all {
|
||||
get("id.version") { id.version }.isEqualTo("-SNAPSHOT")
|
||||
get("timestamp") { timestamp }.isNotNull()
|
||||
get("build") { build }.isNotNull()
|
||||
get("urls") { urls }.single().startsWith(SONATYPE_OSS_URL)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import strikt.assertions.startsWith
|
||||
|
||||
class IvyTest : JUnit5Minutests {
|
||||
@Tests
|
||||
fun tests() = rootContext<Fixture>("ivy tests") {
|
||||
fun tests() = rootContext("ivy tests") {
|
||||
withFixture("ivy/basic") {
|
||||
test("resolves ivy dependencies") {
|
||||
expectThat(build()) {
|
||||
|
||||
@@ -8,7 +8,7 @@ import strikt.assertions.contains
|
||||
|
||||
class PluginTest : JUnit5Minutests {
|
||||
@Tests
|
||||
fun tests() = rootContext<Fixture>("plugin tests") {
|
||||
fun tests() = rootContext("plugin tests") {
|
||||
withFixture("plugin/resolves-from-default-repo") {
|
||||
test("resolves plugin from default repo") {
|
||||
expectThat(build()) {
|
||||
|
||||
@@ -17,7 +17,7 @@ import strikt.assertions.startsWith
|
||||
|
||||
class SubprojectsTest : JUnit5Minutests {
|
||||
@Tests
|
||||
fun tests() = rootContext<Fixture>("subproject tests") {
|
||||
fun tests() = rootContext("subproject tests") {
|
||||
withFixture("subprojects/multi-module") {
|
||||
test("builds multi-module project") {
|
||||
expectThat(build().rootProject) {
|
||||
|
||||
@@ -3,7 +3,12 @@ package org.nixos.gradle2nix
|
||||
import com.squareup.moshi.Moshi
|
||||
import dev.minutest.ContextBuilder
|
||||
import dev.minutest.MinutestFixture
|
||||
import dev.minutest.Node
|
||||
import dev.minutest.TestContextBuilder
|
||||
import dev.minutest.closeableFixture
|
||||
import dev.minutest.experimental.SKIP
|
||||
import dev.minutest.experimental.TransformingAnnotation
|
||||
import io.javalin.Javalin
|
||||
import okio.buffer
|
||||
import okio.source
|
||||
import org.gradle.internal.classpath.DefaultClassPath
|
||||
@@ -13,26 +18,29 @@ import org.gradle.util.GradleVersion
|
||||
import org.junit.jupiter.api.Assumptions.assumeTrue
|
||||
import strikt.api.Assertion
|
||||
import strikt.assertions.map
|
||||
import java.io.Closeable
|
||||
import java.io.File
|
||||
import java.io.StringWriter
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.streams.toList
|
||||
|
||||
const val SONATYPE_OSS_URL = "https://oss.sonatype.org/content/repositories/snapshots/"
|
||||
|
||||
private val moshi = Moshi.Builder().build()
|
||||
|
||||
private val gradleVersion = GradleVersion.version(System.getProperty("compat.gradle.version"))
|
||||
val gradleVersion = System.getProperty("compat.gradle.version")
|
||||
?.let(GradleVersion::version)
|
||||
?: GradleVersion.current()
|
||||
|
||||
val GRADLE_4_5 = GradleVersion.version("4.5")
|
||||
|
||||
fun GRADLE_MIN(version: String) = object : TransformingAnnotation() {
|
||||
override fun <F> transform(node: Node<F>): Node<F> =
|
||||
if (gradleVersion < GradleVersion.version(version)) SKIP.transform(node) else node
|
||||
}
|
||||
|
||||
private fun File.initscript() = resolve("init.gradle").also {
|
||||
it.writer().use { out ->
|
||||
val classpath = DefaultClassPath.of(PluginUnderTestMetadataReading.readImplementationClasspath())
|
||||
.asFiles.joinToString { n -> "'$n'" }
|
||||
out.appendln("""
|
||||
out.append("""
|
||||
initscript {
|
||||
dependencies {
|
||||
classpath files($classpath)
|
||||
@@ -40,6 +48,7 @@ private fun File.initscript() = resolve("init.gradle").also {
|
||||
}
|
||||
|
||||
apply plugin: org.nixos.gradle2nix.Gradle2NixPlugin
|
||||
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
@@ -78,6 +87,9 @@ private fun File.build(
|
||||
System.err.print(log)
|
||||
throw error
|
||||
}
|
||||
|
||||
print(log)
|
||||
|
||||
return resolve("build/nix/model.json").run {
|
||||
println(readText())
|
||||
source().buffer().use { src ->
|
||||
@@ -89,44 +101,96 @@ private fun File.build(
|
||||
val <T : Iterable<Artifact>> Assertion.Builder<T>.ids: Assertion.Builder<Iterable<String>>
|
||||
get() = map { it.id.toString() }
|
||||
|
||||
@MinutestFixture
|
||||
class Fixture(val testRoots: List<Path>)
|
||||
private fun File.parents() = generateSequence(parentFile) { it.parentFile }
|
||||
|
||||
@MinutestFixture
|
||||
class ProjectFixture(val testRoot: Path) {
|
||||
class RepositoryFixture(private val server: Javalin) : Closeable {
|
||||
override fun close() {
|
||||
server.stop()
|
||||
}
|
||||
}
|
||||
|
||||
@MinutestFixture
|
||||
class TestFixture(val name: String, val source: File) : Closeable {
|
||||
val dest: File
|
||||
|
||||
init {
|
||||
require(source.exists() && source.isDirectory) {
|
||||
"$name: Test fixture not found: $source}"
|
||||
}
|
||||
dest = createTempDir(prefix = name, suffix = "")
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
dest.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
@MinutestFixture
|
||||
class ProjectFixture(private val parent: TestFixture, private val source: File) : Closeable {
|
||||
private val dest: File
|
||||
|
||||
init {
|
||||
require(source.exists() && source.isDirectory && parent.source in source.parents()) {
|
||||
"${parent.name}: Test project not found: $source"
|
||||
}
|
||||
val rel = source.toRelativeString(parent.source)
|
||||
dest = parent.dest.resolve(rel)
|
||||
}
|
||||
|
||||
fun copy() {
|
||||
source.copyRecursively(dest, true)
|
||||
}
|
||||
|
||||
fun build(
|
||||
configurations: List<String> = emptyList(),
|
||||
subprojects: List<String> = emptyList()
|
||||
) = testRoot.toFile().build(configurations, subprojects)
|
||||
) = dest.build(configurations, subprojects)
|
||||
|
||||
override fun close() {
|
||||
dest.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
fun ContextBuilder<Fixture>.withFixture(
|
||||
fun ContextBuilder<*>.withRepository(
|
||||
name: String,
|
||||
block: TestContextBuilder<Fixture, ProjectFixture>.() -> Unit
|
||||
) = context(name) {
|
||||
val url = checkNotNull(Thread.currentThread().contextClassLoader.getResource(name)?.toURI()) {
|
||||
"$name: No test fixture found"
|
||||
}
|
||||
val fixtureRoot = Paths.get(url)
|
||||
val dest = createTempDir("gradle2nix").toPath()
|
||||
val src = checkNotNull(fixtureRoot.takeIf(Files::exists)) {
|
||||
"$name: Test fixture not found: $fixtureRoot}"
|
||||
}
|
||||
src.toFile().copyRecursively(dest.toFile())
|
||||
val testRoots = Files.list(dest).filter { Files.isDirectory(it) }.toList()
|
||||
|
||||
fixture {
|
||||
Fixture(testRoots)
|
||||
block: TestContextBuilder<*, RepositoryFixture>.() -> Unit
|
||||
) = derivedContext<RepositoryFixture>("with repository: ${name}") {
|
||||
closeableFixture {
|
||||
RepositoryFixture(Javalin.create { config ->
|
||||
config.addStaticFiles("/repositories/$name")
|
||||
}.start(9999))
|
||||
}
|
||||
|
||||
afterAll {
|
||||
dest.toFile().deleteRecursively()
|
||||
}
|
||||
block()
|
||||
}
|
||||
|
||||
testRoots.forEach { testRoot ->
|
||||
derivedContext<ProjectFixture>(testRoot.fileName.toString()) {
|
||||
deriveFixture { ProjectFixture(testRoot) }
|
||||
block()
|
||||
fun ContextBuilder<*>.withFixture(
|
||||
name: String,
|
||||
block: TestContextBuilder<*, ProjectFixture>.() -> Unit
|
||||
) {
|
||||
derivedContext<TestFixture>(name) {
|
||||
val url = checkNotNull(Thread.currentThread().contextClassLoader.getResource(name)?.toURI()) {
|
||||
"$name: No test fixture found"
|
||||
}
|
||||
val fixtureRoot = Paths.get(url).toFile().absoluteFile
|
||||
|
||||
deriveFixture {
|
||||
TestFixture(name, fixtureRoot)
|
||||
}
|
||||
|
||||
val testRoots = fixtureRoot.listFiles()!!
|
||||
.filter { it.isDirectory }
|
||||
.map { it.absoluteFile }
|
||||
.toList()
|
||||
|
||||
testRoots.forEach { testRoot ->
|
||||
derivedContext<ProjectFixture>(testRoot.name) {
|
||||
deriveFixture { ProjectFixture(this, testRoot) }
|
||||
before { copy() }
|
||||
after { close() }
|
||||
block()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
plugin/src/main/java/org/nixos/gradle2nix/ApiHack.java
Normal file
15
plugin/src/main/java/org/nixos/gradle2nix/ApiHack.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.nixos.gradle2nix;
|
||||
|
||||
import org.gradle.api.artifacts.Dependency;
|
||||
import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Workarounds for APIs improperly marked with @NonNullApi.
|
||||
*/
|
||||
interface ApiHack {
|
||||
static Dependency defaultExternalModuleDependency(String group, String name, @Nullable String version) {
|
||||
return new DefaultExternalModuleDependency(group, name, version);
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import org.apache.ivy.plugins.parser.m2.PomReader
|
||||
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser
|
||||
import org.apache.ivy.plugins.repository.url.URLResource
|
||||
import org.apache.ivy.plugins.resolver.ChainResolver
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ModuleIdentifier
|
||||
import org.gradle.api.artifacts.ResolvedArtifact
|
||||
@@ -23,12 +24,21 @@ import org.gradle.kotlin.dsl.withArtifacts
|
||||
import org.gradle.maven.MavenModule
|
||||
import org.gradle.maven.MavenPomArtifact
|
||||
import org.gradle.util.GradleVersion
|
||||
import java.io.File
|
||||
|
||||
internal class ConfigurationResolverFactory(repositories: RepositoryHandler) {
|
||||
enum class ConfigurationScope {
|
||||
BUILDSCRIPT,
|
||||
PLUGIN,
|
||||
PROJECT
|
||||
}
|
||||
|
||||
internal class ConfigurationResolverFactory(
|
||||
project: Project,
|
||||
scope: ConfigurationScope,
|
||||
repositories: RepositoryHandler
|
||||
) {
|
||||
private val ivySettings = IvySettings().apply {
|
||||
defaultInit()
|
||||
setDefaultRepositoryCacheBasedir(createTempDir("gradle2nix-cache").apply(File::deleteOnExit).absolutePath)
|
||||
defaultRepositoryCacheManager = null
|
||||
setDictatorResolver(ChainResolver().also { chain ->
|
||||
chain.settings = this@apply
|
||||
for (resolver in resolvers) chain.add(resolver)
|
||||
@@ -38,7 +48,7 @@ internal class ConfigurationResolverFactory(repositories: RepositoryHandler) {
|
||||
private val resolvers = repositories
|
||||
.filterIsInstance<ResolutionAwareRepository>()
|
||||
.filterNot { it.createResolver().isLocal }
|
||||
.mapNotNull { it.repositoryResolver(ivySettings) }
|
||||
.mapNotNull { it.repositoryResolver(project, scope, ivySettings) }
|
||||
|
||||
fun create(dependencies: DependencyHandler): ConfigurationResolver =
|
||||
ConfigurationResolver(ivySettings, resolvers, dependencies)
|
||||
@@ -49,11 +59,23 @@ internal class ConfigurationResolver(
|
||||
private val resolvers: List<RepositoryResolver>,
|
||||
private val dependencies: DependencyHandler
|
||||
) {
|
||||
private val failed = mutableListOf<ArtifactIdentifier>()
|
||||
private val ivy = Ivy.newInstance(ivySettings)
|
||||
|
||||
val unresolved: List<ArtifactIdentifier> = failed.toList()
|
||||
|
||||
fun resolve(configuration: Configuration): List<DefaultArtifact> {
|
||||
val resolved = configuration.resolvedConfiguration.lenientConfiguration
|
||||
|
||||
failed.addAll(resolved.unresolvedModuleDependencies.map {
|
||||
DefaultArtifactIdentifier(
|
||||
group = it.selector.group,
|
||||
name = it.selector.name,
|
||||
version = it.selector.version ?: "",
|
||||
type = "module"
|
||||
)
|
||||
})
|
||||
|
||||
val topLevelMetadata = resolved.firstLevelModuleDependencies
|
||||
.flatMap { resolveMetadata(it.moduleGroup, it.moduleName, it.moduleVersion) }
|
||||
|
||||
@@ -78,6 +100,7 @@ internal class ConfigurationResolver(
|
||||
|
||||
val sha256 = resolvedArtifact.file.sha256()
|
||||
val artifacts = resolvers.mapNotNull { it.resolve(artifactId, sha256) }.merge()
|
||||
if (artifacts.isEmpty()) failed.add(artifactId)
|
||||
return artifacts + componentId.run { resolveMetadata(group, module, version) }
|
||||
}
|
||||
|
||||
@@ -113,7 +136,9 @@ internal class ConfigurationResolver(
|
||||
type = "pom"
|
||||
)
|
||||
val sha256 = resolvedPom.file.sha256()
|
||||
resolvers.mapNotNull { it.resolve(artifactId, sha256) }.merge()
|
||||
val artifacts = resolvers.mapNotNull { it.resolve(artifactId, sha256) }.merge()
|
||||
if (artifacts.isEmpty()) failed.add(artifactId)
|
||||
artifacts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +165,9 @@ internal class ConfigurationResolver(
|
||||
extension = "xml"
|
||||
)
|
||||
val sha256 = resolvedDesc.file.sha256()
|
||||
resolvers.mapNotNull { it.resolve(artifactId, sha256) }.merge()
|
||||
val artifacts = resolvers.mapNotNull { it.resolve(artifactId, sha256) }.merge()
|
||||
if (artifacts.isEmpty()) failed.add(artifactId)
|
||||
artifacts
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,7 +182,9 @@ internal class ConfigurationResolver(
|
||||
version = version,
|
||||
type = "module"
|
||||
)
|
||||
return resolvers.mapNotNull { it.resolve(artifactId) }.merge()
|
||||
val artifacts = resolvers.mapNotNull { it.resolve(artifactId) }.merge()
|
||||
if (artifacts.isEmpty()) failed.add(artifactId)
|
||||
return artifacts
|
||||
}
|
||||
|
||||
private fun ResolvedArtifactResult.parentPom(): ResolvedArtifactResult? {
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder
|
||||
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
|
||||
import org.gradle.util.GradleVersion
|
||||
import java.net.URL
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
|
||||
@Suppress("unused")
|
||||
open class Gradle2NixPlugin : Plugin<Gradle> {
|
||||
@@ -127,7 +127,7 @@ private fun Project.buildGradle(): DefaultGradle =
|
||||
}
|
||||
|
||||
private fun Project.buildPlugins(pluginRequests: List<PluginRequest>): List<DefaultArtifact> {
|
||||
return objects.newInstance<PluginResolver>().resolve(pluginRequests).distinct().sorted()
|
||||
return objects.newInstance<PluginResolver>(this).resolve(pluginRequests).distinct().sorted()
|
||||
}
|
||||
|
||||
private fun Project.includedBuilds(): List<DefaultIncludedBuild> =
|
||||
@@ -141,37 +141,64 @@ private fun Project.buildProject(
|
||||
pluginArtifacts: List<DefaultArtifact>
|
||||
): DefaultProject {
|
||||
logger.lifecycle(" Subproject: $path")
|
||||
|
||||
val (buildscriptDependencies, buildscriptUnresolved) = buildscriptDependencies(pluginArtifacts)
|
||||
|
||||
if (buildscriptUnresolved.isNotEmpty()) {
|
||||
logger.warn(buildString {
|
||||
append(" Failed to resolve buildscript dependencies:\n")
|
||||
for (id in buildscriptUnresolved) {
|
||||
append(" - $id\n")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
val (projectDependencies, projectUnresolved) = projectDependencies(explicitConfigurations)
|
||||
|
||||
if (projectUnresolved.isNotEmpty()) {
|
||||
logger.warn(buildString {
|
||||
append(" Failed to resolve project dependencies:\n")
|
||||
for (id in projectUnresolved) {
|
||||
append(" - $id\n")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return DefaultProject(
|
||||
name = name,
|
||||
version = version.toString(),
|
||||
path = path,
|
||||
projectDir = projectDir.toRelativeString(rootProject.projectDir),
|
||||
buildscriptDependencies = buildscriptDependencies(pluginArtifacts),
|
||||
projectDependencies = projectDependencies(explicitConfigurations),
|
||||
buildscriptDependencies = buildscriptDependencies,
|
||||
projectDependencies = projectDependencies,
|
||||
children = explicitSubprojects.map {
|
||||
it.buildProject(explicitConfigurations, emptyList(), pluginArtifacts)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private fun Project.buildscriptDependencies(pluginArtifacts: List<DefaultArtifact>): List<DefaultArtifact> {
|
||||
val resolverFactory = ConfigurationResolverFactory(buildscript.repositories)
|
||||
private fun Project.buildscriptDependencies(
|
||||
pluginArtifacts: List<DefaultArtifact>
|
||||
): Pair<List<DefaultArtifact>, List<ArtifactIdentifier>> {
|
||||
val resolverFactory = ConfigurationResolverFactory(this, ConfigurationScope.BUILDSCRIPT, buildscript.repositories)
|
||||
val resolver = resolverFactory.create(buildscript.dependencies)
|
||||
val pluginIds = pluginArtifacts.map(DefaultArtifact::id)
|
||||
return buildscript.configurations
|
||||
.flatMap(resolver::resolve)
|
||||
.distinct()
|
||||
.filter { it.id !in pluginIds }
|
||||
.sorted()
|
||||
.sorted() to resolver.unresolved
|
||||
}
|
||||
|
||||
private fun Project.projectDependencies(explicitConfigurations: List<String>): List<DefaultArtifact> {
|
||||
val resolverFactory = ConfigurationResolverFactory(repositories)
|
||||
private fun Project.projectDependencies(
|
||||
explicitConfigurations: List<String>
|
||||
): Pair<List<DefaultArtifact>, List<ArtifactIdentifier>> {
|
||||
val resolverFactory = ConfigurationResolverFactory(this, ConfigurationScope.PROJECT, repositories)
|
||||
val resolver = resolverFactory.create(dependencies)
|
||||
return collectConfigurations(explicitConfigurations)
|
||||
.flatMap(resolver::resolve)
|
||||
.distinct()
|
||||
.sorted()
|
||||
.sorted() to resolver.unresolved
|
||||
}
|
||||
|
||||
private fun Project.dependentSubprojects(explicitConfigurations: List<String>): Set<Project> {
|
||||
|
||||
@@ -1,25 +1,28 @@
|
||||
package org.nixos.gradle2nix
|
||||
|
||||
import org.gradle.api.internal.artifacts.dependencies.DefaultExternalModuleDependency
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.plugin.management.PluginRequest
|
||||
import org.gradle.plugin.use.internal.PluginDependencyResolutionServices
|
||||
import javax.inject.Inject
|
||||
|
||||
internal open class PluginResolver @Inject constructor(
|
||||
project: Project,
|
||||
pluginDependencyResolutionServices: PluginDependencyResolutionServices
|
||||
) {
|
||||
private val configurations = pluginDependencyResolutionServices.configurationContainer
|
||||
|
||||
private val resolver = ConfigurationResolverFactory(
|
||||
project,
|
||||
ConfigurationScope.PLUGIN,
|
||||
pluginDependencyResolutionServices.resolveRepositoryHandler
|
||||
).create(pluginDependencyResolutionServices.dependencyHandler)
|
||||
|
||||
fun resolve(pluginRequests: List<PluginRequest>): List<DefaultArtifact> {
|
||||
val markerDependencies = pluginRequests.map {
|
||||
it.module?.let { selector ->
|
||||
DefaultExternalModuleDependency(selector.group, selector.name, selector.version)
|
||||
} ?: it.id.run {
|
||||
DefaultExternalModuleDependency(id, "$id.gradle.plugin", it.version)
|
||||
val markerDependencies = pluginRequests.map { request ->
|
||||
request.module?.let { module ->
|
||||
ApiHack.defaultExternalModuleDependency(module.group, module.name, module.version)
|
||||
} ?: request.id.id.let { id ->
|
||||
ApiHack.defaultExternalModuleDependency(id, "$id.gradle.plugin", request.version)
|
||||
}
|
||||
}
|
||||
return resolver.resolve(configurations.detachedConfiguration(*markerDependencies.toTypedArray()))
|
||||
|
||||
@@ -15,6 +15,7 @@ import org.apache.ivy.plugins.resolver.URLResolver
|
||||
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader
|
||||
import org.codehaus.plexus.util.ReaderFactory
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.artifacts.repositories.ArtifactRepository
|
||||
import org.gradle.api.artifacts.repositories.IvyArtifactRepository
|
||||
import org.gradle.api.artifacts.repositories.MavenArtifactRepository
|
||||
@@ -27,10 +28,14 @@ import org.apache.ivy.core.module.descriptor.Artifact as IvyArtifact
|
||||
import org.apache.ivy.core.module.descriptor.DefaultArtifact as IvyDefaultArtifact
|
||||
import org.apache.ivy.plugins.resolver.RepositoryResolver as IvyRepositoryResolver
|
||||
|
||||
internal fun ResolutionAwareRepository.repositoryResolver(ivySettings: IvySettings): RepositoryResolver? =
|
||||
internal fun ResolutionAwareRepository.repositoryResolver(
|
||||
project: Project,
|
||||
scope: ConfigurationScope,
|
||||
ivySettings: IvySettings
|
||||
): RepositoryResolver? =
|
||||
when(this) {
|
||||
is MavenArtifactRepository -> MavenResolver(ivySettings, this)
|
||||
is IvyArtifactRepository -> IvyResolver(ivySettings, this)
|
||||
is MavenArtifactRepository -> MavenResolver(project, scope, ivySettings, this)
|
||||
is IvyArtifactRepository -> IvyResolver(project, scope, ivySettings, this)
|
||||
else -> null
|
||||
}
|
||||
|
||||
@@ -49,6 +54,8 @@ internal sealed class RepositoryResolver {
|
||||
}
|
||||
|
||||
internal class MavenResolver(
|
||||
project: Project,
|
||||
scope: ConfigurationScope,
|
||||
ivySettings: IvySettings,
|
||||
repository: MavenArtifactRepository
|
||||
) : RepositoryResolver() {
|
||||
@@ -58,7 +65,7 @@ internal class MavenResolver(
|
||||
root = repository.url.toString()
|
||||
isM2compatible = true
|
||||
settings = ivySettings
|
||||
setCache(cacheManager(ivySettings, repository).name)
|
||||
setCache(cacheManager(project, scope, ivySettings, repository).name)
|
||||
}
|
||||
|
||||
override fun resolve(artifactId: DefaultArtifactIdentifier, sha256: String?): DefaultArtifact? {
|
||||
@@ -121,6 +128,8 @@ internal class MavenResolver(
|
||||
}
|
||||
|
||||
internal class IvyResolver(
|
||||
project: Project,
|
||||
scope: ConfigurationScope,
|
||||
ivySettings: IvySettings,
|
||||
repository: IvyArtifactRepository
|
||||
) : RepositoryResolver() {
|
||||
@@ -132,7 +141,7 @@ internal class IvyResolver(
|
||||
for (p in ivyResolver.ivyPatterns) addIvyPattern(p)
|
||||
for (p in ivyResolver.artifactPatterns) addArtifactPattern(p)
|
||||
settings = ivySettings
|
||||
setCache(cacheManager(ivySettings, repository).name)
|
||||
setCache(cacheManager(project, scope, ivySettings, repository).name)
|
||||
}
|
||||
|
||||
override fun resolve(artifactId: DefaultArtifactIdentifier, sha256: String?): DefaultArtifact? {
|
||||
@@ -149,11 +158,16 @@ internal class IvyResolver(
|
||||
}
|
||||
}
|
||||
|
||||
private fun cacheManager(ivySettings: IvySettings, repository: ArtifactRepository): RepositoryCacheManager {
|
||||
private fun cacheManager(
|
||||
project: Project,
|
||||
scope: ConfigurationScope,
|
||||
ivySettings: IvySettings,
|
||||
repository: ArtifactRepository
|
||||
): RepositoryCacheManager {
|
||||
return DefaultRepositoryCacheManager(
|
||||
"${repository.name}-cache",
|
||||
"${scope.name.toLowerCase()}-${repository.name}-cache",
|
||||
ivySettings,
|
||||
createTempDir("gradle2nix-${repository.name}-cache")
|
||||
project.buildDir.resolve("tmp/gradle2nix/${scope.name.toLowerCase()}/${repository.name}")
|
||||
).also {
|
||||
ivySettings.addRepositoryCacheManager(it)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user