Support downloading additional artifacts (sources, javadoc, etc.)

This commit is contained in:
Tad Fisher
2025-01-17 11:44:31 -08:00
committed by Tad Fisher
parent f8c0afcd29
commit 96a444c22b
30 changed files with 1985 additions and 366 deletions

View File

@@ -81,6 +81,7 @@ tasks {
// TODO Find out why this fails the configuration cache
test {
notCompatibleWithConfigurationCache("contains a Task reference")
dependsOn(installDist)
val shareDir = layout.dir(installDist.map { it.destinationDir.resolve("share") })
doFirst {
if (updateGolden.isPresent) {

View File

@@ -6,6 +6,8 @@ initscript {
classpath files("plugin-gradle81.jar")
} else if (GradleVersion.current() >= GradleVersion.version("8.0")) {
classpath files("plugin-gradle80.jar")
} else if (GradleVersion.current() >= GradleVersion.version("7.5")) {
classpath files("plugin-gradle75.jar")
} else {
classpath files("plugin-base.jar")
}

View File

@@ -6,6 +6,7 @@ import org.gradle.tooling.GradleConnector
import org.gradle.tooling.ProjectConnection
import org.gradle.tooling.ResultHandler
import org.gradle.tooling.model.gradle.GradleBuild
import org.nixos.gradle2nix.model.ARTIFACTS_PROPERTY
import org.nixos.gradle2nix.model.DependencySet
import java.io.File
import kotlin.coroutines.resume
@@ -50,14 +51,34 @@ suspend fun ProjectConnection.buildModel(): GradleBuild =
}
suspend fun ProjectConnection.build(
name: String,
config: Config,
tasks: List<String>,
tasks: List<String> = config.tasks,
): DependencySet =
suspendCancellableCoroutine { continuation ->
val cancellationTokenSource = GradleConnector.newCancellationTokenSource()
continuation.invokeOnCancellation { cancellationTokenSource.cancel() }
val systemProperties =
buildMap {
if (config.dumpEvents) {
put(
"org.gradle.internal.operations.trace",
config.outDir
.toPath()
.resolve(name)
.absolutePathString(),
)
}
if (config.artifacts.isNotEmpty()) {
put(
ARTIFACTS_PROPERTY,
config.artifacts.joinToString(",") { it.name.lowercase() },
)
}
}
action { controller -> controller.getModel(DependencySet::class.java) }
.withCancellationToken(cancellationTokenSource.token())
.forTasks(*tasks.toTypedArray())
@@ -75,16 +96,8 @@ suspend fun ProjectConnection.build(
setStandardOutput(System.err)
setStandardError(System.err)
}
if (config.dumpEvents) {
withSystemProperties(
mapOf(
"org.gradle.internal.operations.trace" to
config.outDir
.toPath()
.resolve("debug")
.absolutePathString(),
),
)
if (systemProperties.isNotEmpty()) {
withSystemProperties(systemProperties)
}
}.run(
object : ResultHandler<DependencySet> {

View File

@@ -12,8 +12,8 @@ import com.github.ajalt.clikt.parameters.options.convert
import com.github.ajalt.clikt.parameters.options.default
import com.github.ajalt.clikt.parameters.options.defaultLazy
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.clikt.parameters.options.split
import com.github.ajalt.clikt.parameters.types.enum
import com.github.ajalt.clikt.parameters.types.file
import kotlinx.coroutines.runBlocking
@@ -21,6 +21,7 @@ import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.encodeToStream
import org.gradle.tooling.model.gradle.GradleBuild
import org.nixos.gradle2nix.model.ArtifactType
import org.nixos.gradle2nix.model.DependencySet
import org.nixos.gradle2nix.model.RESOLVE_ALL_TASK
import java.io.File
@@ -35,6 +36,7 @@ data class Config(
val outDir: File,
val projectDir: File,
val tasks: List<String>,
val artifacts: List<ArtifactType>,
val logger: Logger,
val dumpEvents: Boolean,
)
@@ -79,7 +81,15 @@ class Gradle2Nix :
"-t",
metavar = "TASK",
help = "Gradle tasks to run",
).multiple(default = listOf(RESOLVE_ALL_TASK))
).split(",").default(listOf(RESOLVE_ALL_TASK))
private val artifacts: List<ArtifactType> by option(
"--artifacts",
"-a",
metavar = "ARTIFACTS",
help = "Comma-separated list of artifacts to download",
helpTags = mapOf("artifacts" to "doxygen,javadoc,samples,sources,usermanual"),
).enum<ArtifactType>(key = { it.name.lowercase() }).split(",").default(emptyList())
private val projectDir: File by option(
"--project",
@@ -184,6 +194,7 @@ class Gradle2Nix :
outDir ?: projectDir,
projectDir,
tasks,
artifacts,
logger,
dumpEvents,
)
@@ -206,12 +217,20 @@ class Gradle2Nix :
val dependencySets = mutableListOf<DependencySet>()
connect(config).use { connection ->
dependencySets.add(runBlocking { connection.build(config, config.tasks) })
dependencySets.add(runBlocking { connection.build("project", config) })
}
for (buildSrc in buildSrcs) {
connect(config, buildSrc).use { connection ->
dependencySets.add(runBlocking { connection.build(config, listOf(RESOLVE_ALL_TASK)) })
dependencySets.add(
runBlocking {
connection.build(
buildSrc.toRelativeString(projectDir.absoluteFile).replace('/', '_'),
config,
listOf(RESOLVE_ALL_TASK),
)
},
)
}
}

View File

@@ -7,6 +7,9 @@ class GoldenTest :
FunSpec({
install(MavenRepo)
context("artifacts") {
golden("artifacts/sources-javadoc", "-a", "sources,javadoc")
}
context("basic") {
golden("basic/basic-java-project")
golden("basic/basic-kotlin-project")

View File

@@ -11,9 +11,8 @@ import io.kotest.core.spec.Spec
import io.kotest.core.test.NestedTest
import io.kotest.core.test.TestScope
import io.kotest.core.test.TestType
import io.kotest.matchers.equals.beEqual
import io.kotest.matchers.file.shouldBeAFile
import io.kotest.matchers.should
import io.kotest.matchers.shouldBe
import io.ktor.http.ContentType
import io.ktor.http.Url
import io.ktor.server.engine.embeddedServer
@@ -88,17 +87,18 @@ suspend fun TestScope.fixture(
Files.createFile(tempDir.resolve("settings.gradle").toPath())
}
app.main(
listOf(
"-p",
tempDir.toString(),
"--log",
"debug",
"--stacktrace",
"--dump-events",
"--",
"-Dorg.nixos.gradle2nix.m2=$m2",
"--info",
) + args,
args.toList() +
listOf(
"-p",
tempDir.toString(),
"--log",
"debug",
"--stacktrace",
"--dump-events",
"--",
"-Dorg.nixos.gradle2nix.m2=$m2",
"--info",
),
)
val file = tempDir.resolve(app.lockFile)
file.shouldBeAFile()
@@ -137,7 +137,7 @@ suspend fun TestScope.golden(
} catch (e: SerializationException) {
fail("Failed to load golden data from '$filename'. Run with --update-golden to regenerate.")
}
json.encodeToString(env) should beEqual(goldenData)
json.encodeToString(env) shouldBe goldenData
}
}
}
@@ -197,7 +197,7 @@ object MavenRepo : MountableExtension<MavenRepo.Config, NettyApplicationEngine>,
}
}
coroutineScope.launch { s.start(wait = true) }
s
s.engine
} catch (e: Throwable) {
if (config.port == null && attempts > 0) tryStart(attempts - 1) else throw e
}