mirror of
https://github.com/apple/pkl.git
synced 2026-07-10 15:12:43 +02:00
Revert configuration cache (#1659)
This reverts the commits that enabled Gradle's configuration cache feature. IMO: this feature is too hard to use. We don't know if a task is valid for the configuration cache until it runs, and it's very hard to tell if something is safe when authoring Gradle code. For example, our publish tasks are currently failing; I don't know how I would fix this without running the publish task again on my dev machine. Also, some of our build scripts become more brittle because of this; for example, see https://github.com/apple/pkl/blob/bb07589eae0b3195a589559a3245cbc12c29b394/build-logic/src/main/kotlin/BuildInfo.kt#L291-L296
This commit is contained in:
@@ -288,12 +288,7 @@ open class BuildInfo(private val project: Project) {
|
|||||||
classpath = template.classpath
|
classpath = template.classpath
|
||||||
testClassesDirs = template.testClassesDirs
|
testClassesDirs = template.testClassesDirs
|
||||||
jvmArgs.addAll(template.jvmArgs)
|
jvmArgs.addAll(template.jvmArgs)
|
||||||
// jvmArgumentProviders are NOT copied: providers added by plugins (e.g.
|
jvmArgumentProviders.addAll(template.jvmArgumentProviders)
|
||||||
// java-gradle-plugin's GradleJvmCommandLineArgumentProvider) hold a direct
|
|
||||||
// reference to the task they were registered on. Copying them to derived tasks
|
|
||||||
// causes those tasks to capture a foreign task reference, which the
|
|
||||||
// configuration cache cannot serialize. Each derived task receives its own
|
|
||||||
// providers via withType<Test>().configureEach in the subproject.
|
|
||||||
forkEvery = template.forkEvery
|
forkEvery = template.forkEvery
|
||||||
maxParallelForks = template.maxParallelForks
|
maxParallelForks = template.maxParallelForks
|
||||||
minHeapSize = template.minHeapSize
|
minHeapSize = template.minHeapSize
|
||||||
@@ -377,33 +372,35 @@ open class BuildInfo(private val project: Project) {
|
|||||||
org.gradle.internal.os.OperatingSystem.current()
|
org.gradle.internal.os.OperatingSystem.current()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val computedCommitId: Provider<String> =
|
// could be `commitId: Provider<String> = project.provider { ... }`
|
||||||
|
val commitId: String by lazy {
|
||||||
|
// allow -DcommitId=abc123 for build environments that don't have git.
|
||||||
|
System.getProperty("commitId").let { if (it != null) return@lazy it }
|
||||||
// only run command once per build invocation
|
// only run command once per build invocation
|
||||||
if (project.path == project.rootProject.path) {
|
if (project.path == project.rootProject.path) {
|
||||||
project.providers
|
val process =
|
||||||
.exec { commandLine("git", "rev-parse", "--short", "HEAD") }
|
ProcessBuilder()
|
||||||
.standardOutput
|
.command("git", "rev-parse", "--short", "HEAD")
|
||||||
.asText
|
.directory(project.rootDir)
|
||||||
.map { it.trim() }
|
.start()
|
||||||
|
process.waitFor().also { exitCode ->
|
||||||
|
if (exitCode == -1) throw RuntimeException(process.errorStream.reader().readText())
|
||||||
|
}
|
||||||
|
process.inputStream.reader().readText().trim()
|
||||||
} else {
|
} else {
|
||||||
project.rootProject.extensions.getByType(BuildInfo::class.java).commitId
|
project.rootProject.extensions.getByType(BuildInfo::class.java).commitId
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val commitId: Provider<String> =
|
val commitish: String by lazy { if (isReleaseBuild) project.version.toString() else commitId }
|
||||||
// allow -DcommitId=abc123 for build environments that don't have git.
|
|
||||||
System.getProperty("commitId")?.let { project.providers.provider { it } } ?: computedCommitId
|
|
||||||
|
|
||||||
val commitish: Provider<String> =
|
val pklVersion: String by lazy {
|
||||||
if (isReleaseBuild) project.providers.provider { project.version.toString() } else commitId
|
|
||||||
|
|
||||||
val pklVersion: Provider<String> =
|
|
||||||
if (isReleaseBuild) {
|
if (isReleaseBuild) {
|
||||||
project.providers.provider { project.version.toString() }
|
project.version.toString()
|
||||||
} else {
|
} else {
|
||||||
project.providers
|
project.version.toString().replace("-SNAPSHOT", "-dev+$commitId")
|
||||||
.provider { project.version.toString() }
|
|
||||||
.zip(commitId) { version, id -> version.replace("-SNAPSHOT", "-dev+$id") }
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val pklVersionNonUnique: String by lazy {
|
val pklVersionNonUnique: String by lazy {
|
||||||
if (isReleaseBuild) {
|
if (isReleaseBuild) {
|
||||||
|
|||||||
@@ -20,13 +20,9 @@ import java.util.*
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.io.path.createDirectories
|
import kotlin.io.path.createDirectories
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.file.DirectoryProperty
|
|
||||||
import org.gradle.api.file.RegularFileProperty
|
|
||||||
import org.gradle.api.internal.file.FileOperations
|
import org.gradle.api.internal.file.FileOperations
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.tasks.Input
|
||||||
import org.gradle.api.tasks.InputFile
|
|
||||||
import org.gradle.api.tasks.Internal
|
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
import org.gradle.process.ExecOperations
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
@@ -36,32 +32,25 @@ constructor(
|
|||||||
private val fileOperations: FileOperations,
|
private val fileOperations: FileOperations,
|
||||||
private val execOperations: ExecOperations,
|
private val execOperations: ExecOperations,
|
||||||
) : DefaultTask() {
|
) : DefaultTask() {
|
||||||
@get:Input abstract val homeDir: Property<String>
|
@get:Input abstract val graalVm: Property<BuildInfo.GraalVm>
|
||||||
|
|
||||||
@get:InputFile abstract val downloadFile: RegularFileProperty
|
|
||||||
|
|
||||||
@get:Input abstract val version: Property<String>
|
|
||||||
|
|
||||||
@get:Input abstract val graalVmJdkVersion: Property<String>
|
|
||||||
|
|
||||||
@get:Internal abstract val installDir: DirectoryProperty
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !installDir.get().asFile.exists() }
|
@Suppress("LeakingThis") onlyIf("GraalVM not installed") { !graalVm.get().installDir.exists() }
|
||||||
}
|
}
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
fun run() {
|
fun run() {
|
||||||
val distroDir = Paths.get(homeDir.get(), UUID.randomUUID().toString())
|
// minimize chance of corruption by extract-to-random-dir-and-flip-symlink
|
||||||
|
val distroDir = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||||
try {
|
try {
|
||||||
distroDir.createDirectories()
|
distroDir.createDirectories()
|
||||||
println("Extracting ${downloadFile.get().asFile} into $distroDir")
|
println("Extracting ${graalVm.get().downloadFile} into $distroDir")
|
||||||
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
// faster and more reliable than Gradle's `copy { from tarTree() }`
|
||||||
execOperations.exec {
|
execOperations.exec {
|
||||||
workingDir = distroDir.toFile()
|
workingDir = distroDir.toFile()
|
||||||
executable = "tar"
|
executable = "tar"
|
||||||
args("--strip-components=1", "-xzf", downloadFile.get().asFile)
|
args("--strip-components=1", "-xzf", graalVm.get().downloadFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
val os = org.gradle.internal.os.OperatingSystem.current()
|
val os = org.gradle.internal.os.OperatingSystem.current()
|
||||||
@@ -70,8 +59,8 @@ constructor(
|
|||||||
|
|
||||||
println("Installing native-image into $distroDir")
|
println("Installing native-image into $distroDir")
|
||||||
val gvmVersionMajor =
|
val gvmVersionMajor =
|
||||||
requireNotNull(version.get().split(".").first().toIntOrNull()) {
|
requireNotNull(graalVm.get().version.split(".").first().toIntOrNull()) {
|
||||||
"Invalid GraalVM JDK version: ${graalVmJdkVersion.get()}"
|
"Invalid GraalVM JDK version: ${graalVm.get().graalVmJdkVersion}"
|
||||||
}
|
}
|
||||||
if (gvmVersionMajor < 24) {
|
if (gvmVersionMajor < 24) {
|
||||||
execOperations.exec {
|
execOperations.exec {
|
||||||
@@ -81,11 +70,11 @@ constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println("Creating symlink ${installDir.get().asFile} for $distroDir")
|
println("Creating symlink ${graalVm.get().installDir} for $distroDir")
|
||||||
val tempLink = Paths.get(homeDir.get(), UUID.randomUUID().toString())
|
val tempLink = Paths.get(graalVm.get().homeDir, UUID.randomUUID().toString())
|
||||||
Files.createSymbolicLink(tempLink, distroDir)
|
Files.createSymbolicLink(tempLink, distroDir)
|
||||||
try {
|
try {
|
||||||
Files.move(tempLink, installDir.get().asFile.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
Files.move(tempLink, graalVm.get().installDir.toPath(), StandardCopyOption.ATOMIC_MOVE)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
try {
|
try {
|
||||||
fileOperations.delete(tempLink.toFile())
|
fileOperations.delete(tempLink.toFile())
|
||||||
|
|||||||
@@ -16,18 +16,18 @@
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import org.gradle.api.DefaultTask
|
import org.gradle.api.DefaultTask
|
||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.ProjectLayout
|
|
||||||
import org.gradle.api.provider.ListProperty
|
import org.gradle.api.provider.ListProperty
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.provider.Provider
|
||||||
import org.gradle.api.services.BuildService
|
import org.gradle.api.services.BuildService
|
||||||
import org.gradle.api.services.BuildServiceParameters
|
import org.gradle.api.services.BuildServiceParameters
|
||||||
import org.gradle.api.services.ServiceReference
|
|
||||||
import org.gradle.api.tasks.ClasspathNormalizer
|
import org.gradle.api.tasks.ClasspathNormalizer
|
||||||
import org.gradle.api.tasks.Input
|
import org.gradle.api.tasks.Input
|
||||||
import org.gradle.api.tasks.InputFiles
|
import org.gradle.api.tasks.InputFiles
|
||||||
import org.gradle.api.tasks.OutputFile
|
import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.kotlin.dsl.registerIfAbsent
|
||||||
import org.gradle.kotlin.dsl.withNormalizer
|
import org.gradle.kotlin.dsl.withNormalizer
|
||||||
import org.gradle.process.ExecOperations
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
@@ -49,31 +49,25 @@ abstract class NativeImageBuild : DefaultTask() {
|
|||||||
|
|
||||||
@get:InputFiles abstract val classpath: ConfigurableFileCollection
|
@get:InputFiles abstract val classpath: ConfigurableFileCollection
|
||||||
|
|
||||||
/** Path to the `native-image` binary (e.g. `<graalVmBaseDir>/bin/native-image`). */
|
private val outputDir = project.layout.buildDirectory.dir("executable")
|
||||||
@get:Input abstract val nativeImageExecutable: Property<String>
|
|
||||||
|
|
||||||
@get:Input abstract val graalSdkLibraryName: Property<String>
|
@get:OutputFile val outputFile = outputDir.flatMap { it.file(imageName) }
|
||||||
|
|
||||||
@get:Input abstract val releaseBuild: Property<Boolean>
|
|
||||||
|
|
||||||
@get:Input abstract val nativeArch: Property<Boolean>
|
|
||||||
|
|
||||||
/** Divisor applied to `availableProcessors` to throttle native-image CPU usage. */
|
|
||||||
@get:Input abstract val processorDivisor: Property<Int>
|
|
||||||
|
|
||||||
@get:Inject protected abstract val execOperations: ExecOperations
|
@get:Inject protected abstract val execOperations: ExecOperations
|
||||||
|
|
||||||
@get:Inject protected abstract val layout: ProjectLayout
|
private val graalVm: Provider<BuildInfo.GraalVm> = arch.map { a ->
|
||||||
|
when (a) {
|
||||||
|
Architecture.AMD64 -> buildInfo.graalVmAmd64
|
||||||
|
Architecture.AARCH64 -> buildInfo.graalVmAarch64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val outputDir
|
private val buildInfo: BuildInfo = project.extensions.getByType(BuildInfo::class.java)
|
||||||
get() = layout.buildDirectory.dir("executable")
|
|
||||||
|
|
||||||
@get:OutputFile
|
private val nativeImageCommandName =
|
||||||
val outputFile
|
if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
||||||
get() = outputDir.flatMap { it.file(imageName) }
|
|
||||||
|
|
||||||
@get:ServiceReference("nativeImageBuildService")
|
private val nativeImageExecutable = graalVm.map { "${it.baseDir}/bin/$nativeImageCommandName" }
|
||||||
abstract val buildService: Property<NativeImageBuildService>
|
|
||||||
|
|
||||||
private val extraArgsFromProperties by lazy {
|
private val extraArgsFromProperties by lazy {
|
||||||
System.getProperties()
|
System.getProperties()
|
||||||
@@ -81,7 +75,19 @@ abstract class NativeImageBuild : DefaultTask() {
|
|||||||
.map { "${it.key}=${it.value}".substring("pkl.native".length) }
|
.map { "${it.key}=${it.value}".substring("pkl.native".length) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val buildService =
|
||||||
|
project.gradle.sharedServices.registerIfAbsent(
|
||||||
|
"nativeImageBuildService",
|
||||||
|
NativeImageBuildService::class,
|
||||||
|
) {
|
||||||
|
maxParallelUsages.set(1)
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
// ensure native-image builds run in serial (prevent `gw buildNative` from consuming all host
|
||||||
|
// CPU resources).
|
||||||
|
usesService(buildService)
|
||||||
|
|
||||||
group = "build"
|
group = "build"
|
||||||
|
|
||||||
inputs
|
inputs
|
||||||
@@ -98,7 +104,8 @@ abstract class NativeImageBuild : DefaultTask() {
|
|||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
protected fun run() {
|
protected fun run() {
|
||||||
execOperations.exec {
|
execOperations.exec {
|
||||||
val exclusions = listOf(graalSdkLibraryName.get())
|
val exclusions =
|
||||||
|
listOf(buildInfo.libs.findLibrary("graalSdk").get()).map { it.get().module.name }
|
||||||
|
|
||||||
executable = nativeImageExecutable.get()
|
executable = nativeImageExecutable.get()
|
||||||
workingDir(outputDir)
|
workingDir(outputDir)
|
||||||
@@ -133,10 +140,10 @@ abstract class NativeImageBuild : DefaultTask() {
|
|||||||
add("-H:-ParseRuntimeOptions")
|
add("-H:-ParseRuntimeOptions")
|
||||||
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
|
// quick build mode: 40% faster compilation, 20% smaller (but presumably also slower)
|
||||||
// executable
|
// executable
|
||||||
if (!releaseBuild.get()) {
|
if (!buildInfo.isReleaseBuild) {
|
||||||
add("-Ob")
|
add("-Ob")
|
||||||
}
|
}
|
||||||
if (nativeArch.get()) {
|
if (buildInfo.isNativeArch) {
|
||||||
add("-march=native")
|
add("-march=native")
|
||||||
} else {
|
} else {
|
||||||
add("-march=compatibility")
|
add("-march=compatibility")
|
||||||
@@ -148,7 +155,9 @@ abstract class NativeImageBuild : DefaultTask() {
|
|||||||
}
|
}
|
||||||
add(pathInput.asPath)
|
add(pathInput.asPath)
|
||||||
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
// make sure dev machine stays responsive (15% slowdown on my laptop)
|
||||||
val processors = Runtime.getRuntime().availableProcessors() / processorDivisor.get()
|
val processors =
|
||||||
|
Runtime.getRuntime().availableProcessors() /
|
||||||
|
if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
||||||
add("-J-XX:ActiveProcessorCount=${processors}")
|
add("-J-XX:ActiveProcessorCount=${processors}")
|
||||||
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
|
// Pass through all `HOMEBREW_` prefixed environment variables to allow build with shimmed
|
||||||
// tools.
|
// tools.
|
||||||
|
|||||||
@@ -15,10 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
import com.diffplug.spotless.FormatterFunc
|
import com.diffplug.spotless.FormatterFunc
|
||||||
import com.diffplug.spotless.FormatterStep
|
import com.diffplug.spotless.FormatterStep
|
||||||
import java.io.File
|
|
||||||
import java.io.Serial
|
import java.io.Serial
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
import java.lang.reflect.Method
|
|
||||||
import java.net.URLClassLoader
|
import java.net.URLClassLoader
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
|
|
||||||
@@ -28,45 +26,31 @@ class PklFormatterStep(@Transient private val configuration: Configuration) : Se
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun create(): FormatterStep {
|
fun create(): FormatterStep {
|
||||||
val files = configuration.files.toList()
|
|
||||||
return FormatterStep.createLazy(
|
return FormatterStep.createLazy(
|
||||||
"pkl",
|
"pkl",
|
||||||
{ PklFormatterState(files) },
|
{ PklFormatterStep(configuration) },
|
||||||
{ PklFormatterFunc(it.files) },
|
{ PklFormatterFunc(configuration) },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class PklFormatterState(val files: List<File>) : Serializable {
|
class PklFormatterFunc(@Transient private val configuration: Configuration) :
|
||||||
companion object {
|
FormatterFunc, Serializable {
|
||||||
@Serial private const val serialVersionUID: Long = 1L
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class PklFormatterFunc(private val files: List<File>) : FormatterFunc, Serializable {
|
|
||||||
companion object {
|
companion object {
|
||||||
@Serial private const val serialVersionUID: Long = 1L
|
@Serial private const val serialVersionUID: Long = 1L
|
||||||
}
|
}
|
||||||
|
|
||||||
@delegate:Transient
|
private val classLoader by lazy {
|
||||||
private val classLoader: URLClassLoader by lazy {
|
val urls = configuration.files.map { it.toURI().toURL() }
|
||||||
val urls = files.map { it.toURI().toURL() }
|
|
||||||
// Use the platform classloader as parent to isolate from Gradle's classloader
|
// Use the platform classloader as parent to isolate from Gradle's classloader
|
||||||
URLClassLoader(urls.toTypedArray(), ClassLoader.getPlatformClassLoader())
|
URLClassLoader(urls.toTypedArray(), ClassLoader.getPlatformClassLoader())
|
||||||
}
|
}
|
||||||
|
|
||||||
@delegate:Transient
|
private val formatterClass by lazy { classLoader.loadClass("org.pkl.formatter.Formatter") }
|
||||||
private val formatterClass: Class<*> by lazy {
|
|
||||||
classLoader.loadClass("org.pkl.formatter.Formatter")
|
|
||||||
}
|
|
||||||
|
|
||||||
@delegate:Transient
|
private val formatMethod by lazy { formatterClass.getMethod("format", String::class.java) }
|
||||||
private val formatMethod: Method by lazy {
|
|
||||||
formatterClass.getMethod("format", String::class.java)
|
|
||||||
}
|
|
||||||
|
|
||||||
@delegate:Transient
|
private val formatterInstance by lazy { formatterClass.getConstructor().newInstance() }
|
||||||
private val formatterInstance: Any by lazy { formatterClass.getConstructor().newInstance() }
|
|
||||||
|
|
||||||
override fun apply(input: String): String {
|
override fun apply(input: String): String {
|
||||||
return formatMethod(formatterInstance, input) as String
|
return formatMethod(formatterInstance, input) as String
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ fun Project.configurePklPomMetadata() {
|
|||||||
connection.set("scm:git:git://github.com/apple/pkl.git")
|
connection.set("scm:git:git://github.com/apple/pkl.git")
|
||||||
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
|
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
|
||||||
val buildInfo = extensions.getByType<BuildInfo>()
|
val buildInfo = extensions.getByType<BuildInfo>()
|
||||||
url.set(buildInfo.commitish.map { "https://github.com/apple/pkl/tree/$it" })
|
url.set("https://github.com/apple/pkl/tree/${buildInfo.commitish}")
|
||||||
}
|
}
|
||||||
issueManagement {
|
issueManagement {
|
||||||
system.set("GitHub Issues")
|
system.set("GitHub Issues")
|
||||||
|
|||||||
@@ -15,12 +15,10 @@
|
|||||||
*/
|
*/
|
||||||
import org.gradle.api.GradleException
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.file.ArchiveOperations
|
|
||||||
import org.gradle.api.publish.maven.MavenPublication
|
import org.gradle.api.publish.maven.MavenPublication
|
||||||
import org.gradle.api.tasks.bundling.Jar
|
import org.gradle.api.tasks.bundling.Jar
|
||||||
import org.gradle.api.tasks.testing.Test
|
import org.gradle.api.tasks.testing.Test
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.*
|
||||||
import org.gradle.kotlin.dsl.support.serviceOf
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
@@ -152,19 +150,17 @@ tasks.check { dependsOn(testFatJar) }
|
|||||||
|
|
||||||
val validateFatJar by tasks.registering {
|
val validateFatJar by tasks.registering {
|
||||||
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
val outputFile = layout.buildDirectory.file("validateFatJar/result.txt")
|
||||||
val shadowJarFile = tasks.shadowJar.flatMap { it.archiveFile }
|
inputs.files(tasks.shadowJar)
|
||||||
val archiveOps = serviceOf<ArchiveOperations>()
|
|
||||||
inputs.file(shadowJarFile)
|
|
||||||
inputs.property("nonRelocations", nonRelocations)
|
inputs.property("nonRelocations", nonRelocations)
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
val nonRelocations = nonRelocations
|
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val unshadowedFiles = mutableListOf<String>()
|
val unshadowedFiles = mutableListOf<String>()
|
||||||
archiveOps.zipTree(shadowJarFile.get().asFile).visit {
|
zipTree(tasks.shadowJar.get().outputs.files.singleFile).visit {
|
||||||
val path = relativePath.pathString
|
val fileDetails = this
|
||||||
|
val path = fileDetails.relativePath.pathString
|
||||||
if (
|
if (
|
||||||
!(isDirectory ||
|
!(fileDetails.isDirectory ||
|
||||||
path.startsWith("org/pkl/") ||
|
path.startsWith("org/pkl/") ||
|
||||||
path.startsWith("META-INF/") ||
|
path.startsWith("META-INF/") ||
|
||||||
nonRelocations.any { path.startsWith(it) })
|
nonRelocations.any { path.startsWith(it) })
|
||||||
|
|||||||
@@ -28,13 +28,11 @@ val downloadGraalVmAmd64 by
|
|||||||
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
|
tasks.registering(Download::class) { configureDownloadGraalVm(buildInfo.graalVmAmd64) }
|
||||||
|
|
||||||
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
fun Download.configureDownloadGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||||
val installDir = graalvm.installDir
|
onlyIf { !graalvm.installDir.exists() }
|
||||||
val downloadFile = graalvm.downloadFile
|
doLast { println("Downloaded GraalVm to ${graalvm.downloadFile}") }
|
||||||
onlyIf { !installDir.exists() }
|
|
||||||
doLast { println("Downloaded GraalVm to $downloadFile") }
|
|
||||||
|
|
||||||
src(graalvm.downloadUrl)
|
src(graalvm.downloadUrl)
|
||||||
dest(downloadFile)
|
dest(graalvm.downloadFile)
|
||||||
overwrite(false)
|
overwrite(false)
|
||||||
tempAndMove(true)
|
tempAndMove(true)
|
||||||
}
|
}
|
||||||
@@ -52,8 +50,7 @@ val verifyGraalVmAmd64 by
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
||||||
val installDir = graalvm.installDir
|
onlyIf { !graalvm.installDir.exists() }
|
||||||
onlyIf { !installDir.exists() }
|
|
||||||
|
|
||||||
src(graalvm.downloadFile)
|
src(graalvm.downloadFile)
|
||||||
checksum(
|
checksum(
|
||||||
@@ -62,26 +59,16 @@ fun Verify.configureVerifyGraalVm(graalvm: BuildInfo.GraalVm) {
|
|||||||
algorithm("SHA-256")
|
algorithm("SHA-256")
|
||||||
}
|
}
|
||||||
|
|
||||||
// incorrect diagnostic
|
|
||||||
@Suppress("UnusedReceiverParameter")
|
|
||||||
fun InstallGraalVm.configureInstallGraalVm(graalVm: BuildInfo.GraalVm) {
|
|
||||||
homeDir = graalVm.homeDir
|
|
||||||
downloadFile = graalVm.downloadFile
|
|
||||||
version = graalVm.version
|
|
||||||
graalVmJdkVersion = graalVm.graalVmJdkVersion
|
|
||||||
installDir = graalVm.installDir
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val installGraalVmAarch64 by
|
val installGraalVmAarch64 by
|
||||||
tasks.registering(InstallGraalVm::class) {
|
tasks.registering(InstallGraalVm::class) {
|
||||||
dependsOn(verifyGraalVmAarch64)
|
dependsOn(verifyGraalVmAarch64)
|
||||||
configureInstallGraalVm(buildInfo.graalVmAarch64)
|
graalVm = buildInfo.graalVmAarch64
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val installGraalVmAmd64 by
|
val installGraalVmAmd64 by
|
||||||
tasks.registering(InstallGraalVm::class) {
|
tasks.registering(InstallGraalVm::class) {
|
||||||
dependsOn(verifyGraalVmAmd64)
|
dependsOn(verifyGraalVmAmd64)
|
||||||
configureInstallGraalVm(buildInfo.graalVmAmd64)
|
graalVm = buildInfo.graalVmAmd64
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,29 +93,21 @@ fun createCompatibilityTestTask(versionInfo: GradleVersionInfo): TaskProvider<Te
|
|||||||
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
|
createCompatibilityTestTask(versionInfo.version, versionInfo.downloadUrl)
|
||||||
|
|
||||||
fun createCompatibilityTestTask(version: String, downloadUrl: String): TaskProvider<Test> {
|
fun createCompatibilityTestTask(version: String, downloadUrl: String): TaskProvider<Test> {
|
||||||
val currentGradleVersion = gradle.gradleVersion
|
|
||||||
return tasks.register("compatibilityTest$version", Test::class.java) {
|
return tasks.register("compatibilityTest$version", Test::class.java) {
|
||||||
mustRunAfter(tasks.test)
|
mustRunAfter(tasks.test)
|
||||||
|
|
||||||
val myMaxHeapSize = tasks.test.map { it.maxHeapSize }
|
maxHeapSize = tasks.test.get().maxHeapSize
|
||||||
val myJvmArgs = tasks.test.map { it.jvmArgs }
|
jvmArgs = tasks.test.get().jvmArgs
|
||||||
val myClasspath = tasks.test.map { it.classpath }
|
classpath = tasks.test.get().classpath
|
||||||
|
|
||||||
systemProperty("testGradleVersion", version)
|
systemProperty("testGradleVersion", version)
|
||||||
systemProperty("testGradleDistributionUrl", downloadUrl)
|
systemProperty("testGradleDistributionUrl", downloadUrl)
|
||||||
|
|
||||||
doFirst {
|
doFirst {
|
||||||
if (
|
if (version == gradle.gradleVersion && gradle.taskGraph.hasTask(tasks.test.get())) {
|
||||||
version == currentGradleVersion &&
|
|
||||||
project.gradle.taskGraph.hasTask(project.tasks.getByName("test"))
|
|
||||||
) {
|
|
||||||
// don't test same version twice
|
// don't test same version twice
|
||||||
println("This version has already been tested by the `test` task.")
|
println("This version has already been tested by the `test` task.")
|
||||||
throw StopExecutionException()
|
throw StopExecutionException()
|
||||||
}
|
}
|
||||||
maxHeapSize = myMaxHeapSize.get()
|
|
||||||
jvmArgs = myJvmArgs.get()
|
|
||||||
classpath = myClasspath.get()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ val validateHtml by
|
|||||||
// write a basic result file s.t. gradle can consider task up-to-date
|
// write a basic result file s.t. gradle can consider task up-to-date
|
||||||
// writing a result file in case validation fails is not easily possible with JavaExec, but also
|
// writing a result file in case validation fails is not easily possible with JavaExec, but also
|
||||||
// not strictly necessary
|
// not strictly necessary
|
||||||
doFirst { resultFile.get().asFile.delete() }
|
doFirst { project.delete(resultFile) }
|
||||||
doLast { resultFile.get().asFile.writeText("Success.") }
|
doLast { resultFile.get().asFile.writeText("Success.") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,10 +47,8 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
|
|||||||
val outputFile = layout.buildDirectory.file("testStartJavaExecutable/$name")
|
val outputFile = layout.buildDirectory.file("testStartJavaExecutable/$name")
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
|
|
||||||
val executableFile = javaExecutable.flatMap { it.outJar }
|
|
||||||
val pklVersion = buildInfo.pklVersionNonUnique
|
|
||||||
val execOutput = providers.exec {
|
val execOutput = providers.exec {
|
||||||
val executablePath = executableFile.get().asFile
|
val executablePath = javaExecutable.get().outputs.files.singleFile
|
||||||
if (launcher?.isPresent == true) {
|
if (launcher?.isPresent == true) {
|
||||||
commandLine(
|
commandLine(
|
||||||
launcher.get().executablePath.asFile.absolutePath,
|
launcher.get().executablePath.asFile.absolutePath,
|
||||||
@@ -65,9 +63,9 @@ fun Task.setupTestStartJavaExecutable(launcher: Provider<JavaLauncher>? = null)
|
|||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val outputText = execOutput.standardOutput.asText.get()
|
val outputText = execOutput.standardOutput.asText.get()
|
||||||
if (!outputText.contains(pklVersion)) {
|
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
||||||
throw GradleException(
|
throw GradleException(
|
||||||
"Expected version output to contain current version ($pklVersion), but got '$outputText'"
|
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
outputFile.get().asFile.toPath().apply {
|
outputFile.get().asFile.toPath().apply {
|
||||||
|
|||||||
@@ -67,35 +67,13 @@ dependencies {
|
|||||||
stagedWindowsAmd64Executable(executableFile("windows-amd64.exe"))
|
stagedWindowsAmd64Executable(executableFile("windows-amd64.exe"))
|
||||||
}
|
}
|
||||||
|
|
||||||
val nativeImageBuildService =
|
|
||||||
gradle.sharedServices.registerIfAbsent(
|
|
||||||
"nativeImageBuildService",
|
|
||||||
NativeImageBuildService::class,
|
|
||||||
) {
|
|
||||||
maxParallelUsages = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
private val nativeImageCommandName =
|
|
||||||
if (buildInfo.os.isWindows) "native-image.cmd" else "native-image"
|
|
||||||
|
|
||||||
private fun NativeImageBuild.configure() {
|
|
||||||
graalSdkLibraryName = buildInfo.libs.findLibrary("graalSdk").get().map { it.module.name }
|
|
||||||
releaseBuild = buildInfo.isReleaseBuild
|
|
||||||
nativeArch = buildInfo.isNativeArch
|
|
||||||
processorDivisor = if (buildInfo.os.isMacOsX && !buildInfo.isCiBuild) 4 else 1
|
|
||||||
buildService = nativeImageBuildService
|
|
||||||
usesService(nativeImageBuildService)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun NativeImageBuild.amd64() {
|
private fun NativeImageBuild.amd64() {
|
||||||
arch = Architecture.AMD64
|
arch = Architecture.AMD64
|
||||||
nativeImageExecutable = "${buildInfo.graalVmAmd64.baseDir}/bin/$nativeImageCommandName"
|
|
||||||
dependsOn(":installGraalVmAmd64")
|
dependsOn(":installGraalVmAmd64")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun NativeImageBuild.aarch64() {
|
private fun NativeImageBuild.aarch64() {
|
||||||
arch = Architecture.AARCH64
|
arch = Architecture.AARCH64
|
||||||
nativeImageExecutable = "${buildInfo.graalVmAarch64.baseDir}/bin/$nativeImageCommandName"
|
|
||||||
dependsOn(":installGraalVmAarch64")
|
dependsOn(":installGraalVmAarch64")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,7 +91,6 @@ val macExecutableAmd64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val macExecutableAarch64 by
|
val macExecutableAarch64 by
|
||||||
@@ -122,7 +99,6 @@ val macExecutableAarch64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
aarch64()
|
aarch64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val linuxExecutableAmd64 by
|
val linuxExecutableAmd64 by
|
||||||
@@ -131,7 +107,6 @@ val linuxExecutableAmd64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val linuxExecutableAarch64 by
|
val linuxExecutableAarch64 by
|
||||||
@@ -140,7 +115,6 @@ val linuxExecutableAarch64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
aarch64()
|
aarch64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
// Ensure compatibility for kernels with page size set to 4k, 16k and 64k
|
||||||
// (e.g. Raspberry Pi 5, Asahi Linux)
|
// (e.g. Raspberry Pi 5, Asahi Linux)
|
||||||
extraNativeImageArgs.add("-H:PageSize=65536")
|
extraNativeImageArgs.add("-H:PageSize=65536")
|
||||||
@@ -152,7 +126,6 @@ val alpineExecutableAmd64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
extraNativeImageArgs.addAll(listOf("--static", "--libc=musl"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,7 +135,6 @@ val windowsExecutableAmd64 by
|
|||||||
mainClass = executableSpec.mainClass
|
mainClass = executableSpec.mainClass
|
||||||
amd64()
|
amd64()
|
||||||
setClasspath()
|
setClasspath()
|
||||||
configure()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val assembleNative by tasks.existing
|
val assembleNative by tasks.existing
|
||||||
@@ -171,18 +143,18 @@ val testStartNativeExecutable by tasks.registering {
|
|||||||
dependsOn(assembleNative)
|
dependsOn(assembleNative)
|
||||||
|
|
||||||
// dummy file for up-to-date checking
|
// dummy file for up-to-date checking
|
||||||
val outputFile = layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
val outputFile = project.layout.buildDirectory.file("testStartNativeExecutable/output.txt")
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
|
|
||||||
val nativeExecutableFile = assembleNative.map { it.outputs.files.singleFile }
|
val execOutput = providers.exec {
|
||||||
val execOutput = providers.exec { commandLine(nativeExecutableFile.get(), "--version") }
|
commandLine(assembleNative.get().outputs.files.singleFile, "--version")
|
||||||
val pklVersion = buildInfo.pklVersionNonUnique
|
}
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val outputText = execOutput.standardOutput.asText.get()
|
val outputText = execOutput.standardOutput.asText.get()
|
||||||
if (!outputText.contains(pklVersion)) {
|
if (!outputText.contains(buildInfo.pklVersionNonUnique)) {
|
||||||
throw GradleException(
|
throw GradleException(
|
||||||
"Expected version output to contain current version ($pklVersion), but got '$outputText'"
|
"Expected version output to contain current version (${buildInfo.pklVersionNonUnique}), but got '$outputText'"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
outputFile.get().asFile.toPath().apply {
|
outputFile.get().asFile.toPath().apply {
|
||||||
@@ -199,10 +171,10 @@ val requiredGlibcVersion: Version = Version.parse("2.17")
|
|||||||
val checkGlibc by tasks.registering {
|
val checkGlibc by tasks.registering {
|
||||||
enabled = buildInfo.os.isLinux && !buildInfo.musl
|
enabled = buildInfo.os.isLinux && !buildInfo.musl
|
||||||
dependsOn(assembleNative)
|
dependsOn(assembleNative)
|
||||||
val nativeExecutableFile = assembleNative.map { it.outputs.files.singleFile }
|
|
||||||
val requiredGlibcVersion = requiredGlibcVersion
|
|
||||||
val exec = providers.exec { commandLine("objdump", "-T", nativeExecutableFile.get()) }
|
|
||||||
doLast {
|
doLast {
|
||||||
|
val exec = providers.exec {
|
||||||
|
commandLine("objdump", "-T", assembleNative.get().outputs.files.singleFile)
|
||||||
|
}
|
||||||
val output = exec.standardOutput.asText.get()
|
val output = exec.standardOutput.asText.get()
|
||||||
val minimumGlibcVersion =
|
val minimumGlibcVersion =
|
||||||
output
|
output
|
||||||
|
|||||||
+19
-39
@@ -53,47 +53,27 @@ idea {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val clean by tasks.existing {
|
val clean by tasks.existing { delete(layout.buildDirectory) }
|
||||||
val buildDirectory = layout.buildDirectory.map { it.asFile }
|
|
||||||
doLast { buildDirectory.get().delete() }
|
|
||||||
}
|
|
||||||
|
|
||||||
val printVersion by tasks.registering {
|
val printVersion by tasks.registering { doFirst { println(buildInfo.pklVersion) } }
|
||||||
val pklVersion = buildInfo.pklVersion
|
|
||||||
doFirst { println(pklVersion.get()) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val printInfo by tasks.registering {
|
val message =
|
||||||
val arch = buildInfo.arch
|
"""
|
||||||
val pklVersion = buildInfo.pklVersion
|
====
|
||||||
val pklVersionNonUnique = buildInfo.pklVersionNonUnique
|
Gradle version : ${gradle.gradleVersion}
|
||||||
val commitId = buildInfo.commitId
|
Java version : ${System.getProperty("java.version")}
|
||||||
val gradleVerison = gradle.gradleVersion
|
isParallel : ${gradle.startParameter.isParallelProjectExecutionEnabled}
|
||||||
val javaVersion = System.getProperty("java.version")
|
maxWorkerCount : ${gradle.startParameter.maxWorkerCount}
|
||||||
val isParallel = gradle.startParameter.isParallelProjectExecutionEnabled
|
Architecture : ${buildInfo.arch}
|
||||||
val maxWorkerCount = gradle.startParameter.maxWorkerCount
|
|
||||||
val projectVersion = project.version
|
|
||||||
doFirst {
|
|
||||||
val message =
|
|
||||||
"""
|
|
||||||
====
|
|
||||||
Gradle version : $gradleVerison
|
|
||||||
Java version : $javaVersion
|
|
||||||
isParallel : $isParallel
|
|
||||||
maxWorkerCount : $maxWorkerCount
|
|
||||||
Architecture : $arch
|
|
||||||
|
|
||||||
Project Version : $projectVersion
|
Project Version : ${project.version}
|
||||||
Pkl Version : ${pklVersion.get()}
|
Pkl Version : ${buildInfo.pklVersion}
|
||||||
Pkl Non-Unique Version : $pklVersionNonUnique
|
Pkl Non-Unique Version : ${buildInfo.pklVersionNonUnique}
|
||||||
Git Commit ID : ${commitId.get()}
|
Git Commit ID : ${buildInfo.commitId}
|
||||||
====
|
====
|
||||||
"""
|
"""
|
||||||
.trimIndent()
|
|
||||||
|
|
||||||
val formattedMessage =
|
val formattedMessage =
|
||||||
message.replace("====", "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
|
message.replace("\n====", "\n" + "=".repeat(message.lines().maxByOrNull { it.length }!!.length))
|
||||||
|
|
||||||
println(formattedMessage)
|
logger.info(formattedMessage)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ org.gradle.jvmargs= \
|
|||||||
|
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.configuration-cache=true
|
|
||||||
|
|
||||||
kotlin.stdlib.default.dependency=false
|
kotlin.stdlib.default.dependency=false
|
||||||
kotlin.daemon.jvmargs=-XX:+UseParallelGC
|
kotlin.daemon.jvmargs=-XX:+UseParallelGC
|
||||||
#org.gradle.workers.max=1
|
#org.gradle.workers.max=1
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
import java.io.ByteArrayOutputStream
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import org.gradle.kotlin.dsl.support.serviceOf
|
import org.gradle.kotlin.dsl.support.serviceOf
|
||||||
|
|
||||||
@@ -117,15 +118,9 @@ private fun setupJavaExecutableRun(
|
|||||||
null -> "java"
|
null -> "java"
|
||||||
else -> launcher.get().executablePath.asFile.absolutePath
|
else -> launcher.get().executablePath.asFile.absolutePath
|
||||||
}
|
}
|
||||||
|
standardOutput = OutputStream.nullOutputStream()
|
||||||
|
|
||||||
doFirst { standardOutput = OutputStream.nullOutputStream() }
|
args("-jar", tasks.javaExecutable.get().outputs.files.singleFile.toString(), *args)
|
||||||
|
|
||||||
val javaExecutableFile = tasks.javaExecutable.map { it.outputs.files.singleFile }
|
|
||||||
argumentProviders.add(
|
|
||||||
CommandLineArgumentProvider {
|
|
||||||
listOf("-jar", javaExecutableFile.get().absolutePath) + args.toList()
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
doFirst { outputFile.get().asFile.delete() }
|
doFirst { outputFile.get().asFile.delete() }
|
||||||
|
|
||||||
@@ -138,10 +133,7 @@ val evalTestFlags = arrayOf("eval", "-x", "1 + 1", "pkl:base")
|
|||||||
|
|
||||||
fun Exec.useRootDirAndSuppressOutput() {
|
fun Exec.useRootDirAndSuppressOutput() {
|
||||||
workingDir = rootProject.layout.projectDirectory.asFile
|
workingDir = rootProject.layout.projectDirectory.asFile
|
||||||
doFirst {
|
standardOutput = ByteArrayOutputStream() // we only care that this exec doesn't fail
|
||||||
// we only care that this exec doesn't fail
|
|
||||||
standardOutput = OutputStream.nullOutputStream()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 0.28 Preparing for JDK21 toolchains revealed that `testStartJavaExecutable` may pass, even though
|
// 0.28 Preparing for JDK21 toolchains revealed that `testStartJavaExecutable` may pass, even though
|
||||||
|
|||||||
@@ -70,26 +70,17 @@ for (packageDir in file("src/main/files/packages").listFiles()!!) {
|
|||||||
into(destinationDir)
|
into(destinationDir)
|
||||||
val shasumFile = destinationDir.map { it.file("${packageDir.name}.json.sha256") }
|
val shasumFile = destinationDir.map { it.file("${packageDir.name}.json.sha256") }
|
||||||
outputs.file(shasumFile)
|
outputs.file(shasumFile)
|
||||||
val isWindows = buildInfo.os.isWindows
|
filter { line ->
|
||||||
|
line.replaceFirst("\$computedChecksum", archiveFile.get().asFile.computeChecksum())
|
||||||
|
}
|
||||||
doLast {
|
doLast {
|
||||||
val outputFile = destinationDir.get().asFile.resolve("${packageDir.name}.json")
|
val outputFile = destinationDir.get().asFile.resolve("${packageDir.name}.json")
|
||||||
fun sha256Hex(file: File): String {
|
if (buildInfo.os.isWindows) {
|
||||||
val hash = MessageDigest.getInstance("SHA-256").digest(file.readBytes())
|
val contents = outputFile.readText()
|
||||||
return buildString(hash.size * 2) {
|
|
||||||
for (b in hash) {
|
|
||||||
append("0123456789abcdef"[b.toInt() shr 4 and 0xF])
|
|
||||||
append("0123456789abcdef"[b.toInt() and 0xF])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var contents =
|
|
||||||
outputFile.readText().replace("\$computedChecksum", sha256Hex(archiveFile.get().asFile))
|
|
||||||
if (isWindows) {
|
|
||||||
// workaround for https://github.com/gradle/gradle/issues/1151
|
// workaround for https://github.com/gradle/gradle/issues/1151
|
||||||
contents = contents.replace("\r\n", "\n")
|
outputFile.writeText(contents.replace("\r\n", "\n"))
|
||||||
}
|
}
|
||||||
outputFile.writeText(contents)
|
shasumFile.get().asFile.writeText(outputFile.computeChecksum())
|
||||||
shasumFile.get().asFile.writeText(sha256Hex(outputFile))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +111,6 @@ val generateKeys by
|
|||||||
"CN=localhost",
|
"CN=localhost",
|
||||||
)
|
)
|
||||||
workingDir(keystoreDir)
|
workingDir(keystoreDir)
|
||||||
// capture keystoreFile inside closure so we don't reference `this$0`; which breaks Gradle
|
|
||||||
// configuration cache
|
|
||||||
val keystoreFile = keystoreFile
|
|
||||||
doFirst {
|
doFirst {
|
||||||
workingDir.mkdirs()
|
workingDir.mkdirs()
|
||||||
keystoreFile.get().asFile.delete()
|
keystoreFile.get().asFile.delete()
|
||||||
@@ -155,3 +143,20 @@ val exportCerts by
|
|||||||
outputFile.get().asFile.delete()
|
outputFile.get().asFile.delete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toHex(hash: ByteArray): String {
|
||||||
|
val hexDigitTable =
|
||||||
|
charArrayOf('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f')
|
||||||
|
return buildString(hash.size * 2) {
|
||||||
|
for (b in hash) {
|
||||||
|
append(hexDigitTable[b.toInt() shr 4 and 0xF])
|
||||||
|
append(hexDigitTable[b.toInt() and 0xF])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun File.computeChecksum(): String {
|
||||||
|
val md = MessageDigest.getInstance("SHA-256")
|
||||||
|
val hash = md.digest(readBytes())
|
||||||
|
return toHex(hash)
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ val generateTestConfigClasses by
|
|||||||
|
|
||||||
classpath = pklCodegenJava
|
classpath = pklCodegenJava
|
||||||
mainClass.set("org.pkl.codegen.java.Main")
|
mainClass.set("org.pkl.codegen.java.Main")
|
||||||
val codegenSources = fileTree("src/test/resources/codegenPkl")
|
|
||||||
argumentProviders.add(
|
argumentProviders.add(
|
||||||
CommandLineArgumentProvider {
|
CommandLineArgumentProvider {
|
||||||
listOf("--output-dir", outputDir.get().asFile.path, "--generate-javadoc") +
|
listOf("--output-dir", outputDir.get().asFile.path, "--generate-javadoc") +
|
||||||
codegenSources.map { it.path }
|
fileTree("src/test/resources/codegenPkl").map { it.path }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,11 +57,10 @@ val generateTestConfigClasses by
|
|||||||
|
|
||||||
classpath = pklCodegenKotlin
|
classpath = pklCodegenKotlin
|
||||||
mainClass.set("org.pkl.codegen.kotlin.Main")
|
mainClass.set("org.pkl.codegen.kotlin.Main")
|
||||||
val codegenSources = fileTree("src/test/resources/codegenPkl")
|
|
||||||
argumentProviders.add(
|
argumentProviders.add(
|
||||||
CommandLineArgumentProvider {
|
CommandLineArgumentProvider {
|
||||||
listOf("--output-dir", outputDir.get().asFile.absolutePath) +
|
listOf("--output-dir", outputDir.get().asFile.absolutePath) +
|
||||||
codegenSources.map { it.absolutePath }
|
fileTree("src/test/resources/codegenPkl").map { it.absolutePath }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,22 +98,20 @@ tasks.processResources {
|
|||||||
inputs.property("version", buildInfo.pklVersion)
|
inputs.property("version", buildInfo.pklVersion)
|
||||||
inputs.property("commitId", buildInfo.commitId)
|
inputs.property("commitId", buildInfo.commitId)
|
||||||
|
|
||||||
val pklVersion = buildInfo.pklVersion
|
|
||||||
val commitId = buildInfo.commitId
|
|
||||||
val stdlibModules =
|
|
||||||
fileTree("$rootDir/stdlib") {
|
|
||||||
include("*.pkl")
|
|
||||||
exclude("doc-package-info.pkl")
|
|
||||||
}
|
|
||||||
.map { "pkl:" + it.nameWithoutExtension }
|
|
||||||
.sortedBy { it.lowercase() }
|
|
||||||
|
|
||||||
filesMatching("org/pkl/core/Release.properties") {
|
filesMatching("org/pkl/core/Release.properties") {
|
||||||
|
val stdlibModules =
|
||||||
|
fileTree("$rootDir/stdlib") {
|
||||||
|
include("*.pkl")
|
||||||
|
exclude("doc-package-info.pkl")
|
||||||
|
}
|
||||||
|
.map { "pkl:" + it.nameWithoutExtension }
|
||||||
|
.sortedBy { it.lowercase() }
|
||||||
|
|
||||||
filter<ReplaceTokens>(
|
filter<ReplaceTokens>(
|
||||||
"tokens" to
|
"tokens" to
|
||||||
mapOf(
|
mapOf(
|
||||||
"version" to pklVersion.get(),
|
"version" to buildInfo.pklVersion,
|
||||||
"commitId" to commitId.get(),
|
"commitId" to buildInfo.commitId,
|
||||||
"stdlibModules" to stdlibModules.joinToString(","),
|
"stdlibModules" to stdlibModules.joinToString(","),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -142,15 +140,13 @@ val externalReaderFixture by tasks.registering {
|
|||||||
group = "build"
|
group = "build"
|
||||||
dependsOn(tasks.named("compileExternalReaderFixtureJava"))
|
dependsOn(tasks.named("compileExternalReaderFixtureJava"))
|
||||||
inputs.files(externalReaderFixtureSourceSet.map { it.output })
|
inputs.files(externalReaderFixtureSourceSet.map { it.output })
|
||||||
val isWindows = buildInfo.os.isWindows
|
val fileName = if (buildInfo.os.isWindows) "externalreader.bat" else "externalreader"
|
||||||
val fileName = if (isWindows) "externalreader.bat" else "externalreader"
|
|
||||||
val outputFile = layout.buildDirectory.file("fixtures/$fileName")
|
val outputFile = layout.buildDirectory.file("fixtures/$fileName")
|
||||||
outputs.file(outputFile)
|
outputs.file(outputFile)
|
||||||
val runtimeClasspath = externalReaderFixtureSourceSet.map { it.runtimeClasspath }
|
|
||||||
doLast {
|
doLast {
|
||||||
val classpath = runtimeClasspath.get().asPath
|
val classpath = externalReaderFixtureSourceSet.get().runtimeClasspath.asPath
|
||||||
val scriptContent =
|
val scriptContent =
|
||||||
if (isWindows) {
|
if (buildInfo.os.isWindows) {
|
||||||
"""
|
"""
|
||||||
@echo off
|
@echo off
|
||||||
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
java -cp $classpath org.pkl.core.externalreaderfixture.Main
|
||||||
|
|||||||
@@ -68,16 +68,15 @@ sourceSets { main { java { srcDir("src/main/java") } } }
|
|||||||
|
|
||||||
val prepareHistoricalDistributions by tasks.registering {
|
val prepareHistoricalDistributions by tasks.registering {
|
||||||
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
|
val outputDir = layout.buildDirectory.dir("pklHistoricalDistributions")
|
||||||
inputs.files(pklHistoricalDistributions)
|
inputs.files(pklHistoricalDistributions.files)
|
||||||
outputs.dir(outputDir)
|
outputs.dir(outputDir)
|
||||||
val isWindows = buildInfo.os.isWindows
|
|
||||||
doLast {
|
doLast {
|
||||||
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
|
val distributionDir = outputDir.get().asFile.toPath().also(Files::createDirectories)
|
||||||
for (file in inputs.files) {
|
for (file in pklHistoricalDistributions.files) {
|
||||||
val target = distributionDir.resolve(file.name)
|
val target = distributionDir.resolve(file.name)
|
||||||
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
|
// Create normal files on Windows, symlink on macOS/linux (need admin privileges to create
|
||||||
// symlinks on Windows)
|
// symlinks on Windows)
|
||||||
if (isWindows) {
|
if (buildInfo.os.isWindows) {
|
||||||
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
|
if (!Files.isRegularFile(target, LinkOption.NOFOLLOW_LINKS)) {
|
||||||
if (Files.exists(target)) {
|
if (Files.exists(target)) {
|
||||||
Files.delete(target)
|
Files.delete(target)
|
||||||
|
|||||||
@@ -13,9 +13,6 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
import org.gradle.api.file.ArchiveOperations
|
|
||||||
import org.gradle.kotlin.dsl.support.serviceOf
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("pklAllProjects")
|
id("pklAllProjects")
|
||||||
id("pklJavaLibrary")
|
id("pklJavaLibrary")
|
||||||
@@ -83,14 +80,13 @@ val externalReaderJar by
|
|||||||
archiveVersion = ""
|
archiveVersion = ""
|
||||||
|
|
||||||
// Package all dependencies into the jar (shadow plugin lite).
|
// Package all dependencies into the jar (shadow plugin lite).
|
||||||
val archiveOps = serviceOf<ArchiveOperations>()
|
|
||||||
from(
|
from(
|
||||||
externalReader.runtimeClasspath.elements.map { locations ->
|
externalReader.runtimeClasspath.elements.map { locations ->
|
||||||
locations.mapNotNull { location ->
|
locations.mapNotNull { location ->
|
||||||
val f = location.asFile
|
val f = location.asFile
|
||||||
when {
|
when {
|
||||||
f.isDirectory -> f
|
f.isDirectory -> f
|
||||||
f.isFile -> archiveOps.zipTree(f)
|
f.isFile -> zipTree(f)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,32 +96,18 @@ val externalReaderJar by
|
|||||||
manifest { attributes("Main-Class" to "org.pkl.gradle.test.extreader.Main") }
|
manifest { attributes("Main-Class" to "org.pkl.gradle.test.extreader.Main") }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Named class avoids the anonymous inner-class `this$0` field that Gradle's configuration
|
tasks.test {
|
||||||
// cache cannot serialize when a SAM lambda is created inside a lambda-with-receiver.
|
|
||||||
class ExternalReaderArgProvider(
|
|
||||||
private val jarFile: Provider<RegularFile>,
|
|
||||||
private val javaExecutable: Provider<String>,
|
|
||||||
) : CommandLineArgumentProvider {
|
|
||||||
override fun asArguments() =
|
|
||||||
listOf(
|
|
||||||
"-DpklGradle.externalReaderJar=${jarFile.get().asFile.absolutePath}",
|
|
||||||
"-DpklGradle.javaExecutable=${javaExecutable.get()}",
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val externalReaderJarFile = externalReaderJar.flatMap { it.archiveFile }
|
|
||||||
|
|
||||||
val javaExecutablePath =
|
|
||||||
javaToolchains.launcherFor(java.toolchain).map { it.executablePath.asFile.absolutePath }
|
|
||||||
|
|
||||||
// Apply to all Test tasks (not just `test`) so that testJdk* tasks also receive the
|
|
||||||
// external-reader system properties without relying on jvmArgumentProviders being copied
|
|
||||||
// across tasks (which breaks the configuration cache via stale task references).
|
|
||||||
tasks.withType<Test>().configureEach {
|
|
||||||
dependsOn(externalReaderJar)
|
dependsOn(externalReaderJar)
|
||||||
// Currently the only way to inject system properties from lazy values in Gradle
|
// Currently the only way to inject system properties from lazy values in Gradle
|
||||||
// is via `jvmArgumentProviders`.
|
// is via `jvmArgumentProviders`.
|
||||||
jvmArgumentProviders += ExternalReaderArgProvider(externalReaderJarFile, javaExecutablePath)
|
jvmArgumentProviders += CommandLineArgumentProvider {
|
||||||
|
listOf(
|
||||||
|
"-DpklGradle.externalReaderJar=" +
|
||||||
|
externalReaderJar.get().archiveFile.get().asFile.absolutePath,
|
||||||
|
"-DpklGradle.javaExecutable=" +
|
||||||
|
javaToolchains.launcherFor(java.toolchain).get().executablePath.asFile.absolutePath,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
|
|||||||
@@ -81,14 +81,13 @@ private fun Exec.configureTestStartFatJar(launcher: Provider<JavaLauncher>) {
|
|||||||
|
|
||||||
inputs.files(tasks.shadowJar)
|
inputs.files(tasks.shadowJar)
|
||||||
executable = launcher.get().executablePath.asFile.absolutePath
|
executable = launcher.get().executablePath.asFile.absolutePath
|
||||||
doFirst { standardOutput = OutputStream.nullOutputStream() }
|
standardOutput = OutputStream.nullOutputStream()
|
||||||
|
|
||||||
val shadowJarFile = tasks.shadowJar.flatMap { it.archiveFile }
|
|
||||||
argumentProviders.add(
|
argumentProviders.add(
|
||||||
CommandLineArgumentProvider {
|
CommandLineArgumentProvider {
|
||||||
buildList {
|
buildList {
|
||||||
add("-cp")
|
add("-cp")
|
||||||
add(shadowJarFile.get().asFile.absolutePath)
|
add(tasks.shadowJar.get().outputs.files.singleFile.absolutePath)
|
||||||
add("org.pkl.cli.Main")
|
add("org.pkl.cli.Main")
|
||||||
add("eval")
|
add("eval")
|
||||||
add("-x")
|
add("-x")
|
||||||
@@ -164,7 +163,7 @@ publishing {
|
|||||||
connection.set("scm:git:git://github.com/apple/pkl.git")
|
connection.set("scm:git:git://github.com/apple/pkl.git")
|
||||||
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
|
developerConnection.set("scm:git:ssh://github.com/apple/pkl.git")
|
||||||
val buildInfo = project.extensions.getByType<BuildInfo>()
|
val buildInfo = project.extensions.getByType<BuildInfo>()
|
||||||
url.set(buildInfo.commitish.map { "https://github.com/apple/pkl/tree/$it" })
|
url.set("https://github.com/apple/pkl/tree/${buildInfo.commitish}")
|
||||||
}
|
}
|
||||||
issueManagement {
|
issueManagement {
|
||||||
system.set("GitHub Issues")
|
system.set("GitHub Issues")
|
||||||
|
|||||||
Reference in New Issue
Block a user